UNPKG

splog

Version:

A NodeJS library which provides a syslog-like remote logging interface

208 lines (190 loc) 5.41 kB
var exec = require('child_process').exec; var net = require('net'); var util = require('util'); var hostname = null; function _hostname(error, stdout, stderr) { if (stdout) { hostname = stdout.trim(); } else { hostname = 'localhost'; } onHostnameReady(); } exec('hostname', _hostname); function _pad(what, howFar, withWhat) { var padded = what.toString(); if (withWhat === undefined) { if (typeof what === 'number') { withWhat = '0'; } else { withWhat = ' '; } } for (var index = padded.length; index < howFar; index = index + 1) { padded = withWhat + padded; } return padded; } function _timestamp() { var now = new Date(); return [ [ [now.getFullYear(), _pad(now.getMonth() + 1, 2), _pad(now.getDate(), 2)].join('-'), [_pad(now.getHours(), 2), _pad(now.getMinutes(), 2), _pad(now.getSeconds(), 2)].join(':'), ].join(' '), _pad(now.getMilliseconds(), 3)].join(','); } var FACILITIES = { 'user': 1, }; var LEVELS = { 'debug': 7, 'info': 6, 'warning': 4, 'error': 3, 'critical': 2, }; var configuration = { 'hostnameBacklog': [], 'socketBacklog': [], 'hostnameReady': false, 'socketReady': false, }; function onSocketError(line) { configuration['socketReady'] = false; if (line) { if(line instanceof Error){ log('warning',line.toString()); console.log(line); } else { configuration['socketBacklog'].push(line); } } _reconnectSocket(); } function onHostnameReady() { configuration['hostnameReady'] = true; var backlog = configuration['hostnameBacklog']; configuration['hostnameBacklog'] = []; for (var index in backlog) { backlog[index]['hostname'] = hostname; _format(backlog[index]); } } function onSocketReady() { configuration['socketReady'] = true; var backlog = configuration['socketBacklog']; configuration['socketBacklog'] = []; if (backlog.length > 0) { _send(backlog.join('')); } } function _reconnectSocket() { if (configuration['socket']) { configuration['socket'].destroy(); } var socket = new net.Socket({type: 'tcp'}); socket.setNoDelay(true); socket.setKeepAlive(true); socket.on('error', onSocketError); socket.on('connect', onSocketReady); configuration['socketReady'] = false; configuration['socket'] = socket; socket.connect(configuration['port'] || 514, configuration['host']); } function configure(settings) { if (settings) { if (settings['port']) { configuration['port'] = settings['port']; } else { delete configuration['port']; } if (settings['host']) { configuration['host'] = settings['host']; } else { delete configuration['host']; } if (settings['app']) { configuration['app'] = settings['app']; } else { delete configuration['app']; } if (settings['instance']) { configuration['instance'] = settings['instance']; } else { delete configuration['instance']; } if (settings['minLevel']) { configuration['minLevel'] = parseInt(settings['minLevel']); if(isNaN(configuration['minLevel'])){ configuration['minLevel'] = LEVELS[settings['minLevel'].trim().toLowerCase()]; } } } if (configuration['host']) { _reconnectSocket(); } } module.exports.configure = configure; function _format(data) { if (configuration['hostnameReady']) { var message = (data['msg'] || '').toString(); if (message[message.length - 1] === '\n'){ message = message.slice(0, -1); } var lines = message.split('\n'); for (var index in lines) { var line = data['hostname'] + ' ' + data['app'] + ' ' + data['timestamp']+ ' ' + data['instance'] + ' ' + data['level'].toUpperCase() + ' ' + lines[index]; if (configuration['host']) { line = '<' + 8 * FACILITIES[data['facility']] + LEVELS[data['level'].toLowerCase()] + '>' + line; if (line[line.length - 1] !== '\n') { line += '\n'; } } else { // This is destined for console.log which will throw in a newline. if (line[line.length - 1] === '\n') { line = line.slice(0, -1); } } _send(line); } } else { configuration['hostnameBacklog'].push(data); } } function _send(line) { if (configuration['host']) { if (configuration['socketReady']) { configuration['socket'].write(line,function(err){ if(err){ onSocketError(line); } }); } else { configuration['socketBacklog'].push(line); } } else { console.log(line); } } function log(level, msg) { if(configuration.minLevel && LEVELS[level.trim().toLowerCase()] > configuration.minLevel){ return; } var data = { 'facility': configuration['facility'] || 'user', 'level': level, 'hostname': hostname, 'app': configuration['app'] || process.argv[0], 'timestamp': _timestamp(), 'instance': configuration['instance'] || process.pid, 'msg': msg, }; _format(data); } module.exports.log = log module.exports.debug = function(msg) { log('debug', msg); } module.exports.info = function(msg) { log('info', msg); } module.exports.warning = function(msg) { log('warning', msg); } module.exports.error = function(msg) { log('error', msg); } module.exports.critical = function(msg) { log('critical', msg); } //module.exports.configure = configure