Initial commit
This commit is contained in:
251
lib/logger.js
Normal file
251
lib/logger.js
Normal file
@@ -0,0 +1,251 @@
|
||||
/* jshint -W097 */
|
||||
/* jshint strict: false */
|
||||
/*jslint node: true */
|
||||
'use strict';
|
||||
|
||||
var winston = require('winston');
|
||||
var DailyRotateFile = require('winston-daily-rotate-file');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
var tools = require(__dirname + '/tools.js');
|
||||
var SysLog;
|
||||
var hostname = tools.getHostName();
|
||||
|
||||
try {
|
||||
SysLog = require('winston-syslog').Syslog;
|
||||
} catch (ex) {
|
||||
//console.log('No syslog support');
|
||||
}
|
||||
|
||||
var logger = function (level, files, noStdout, prefix) {
|
||||
var userOptions = {};
|
||||
var options = {
|
||||
transports: []
|
||||
};
|
||||
|
||||
//var defaultMaxSize;// = 10 * 1024 * 1024;
|
||||
|
||||
if (typeof files === 'string') {
|
||||
files = [files];
|
||||
}
|
||||
|
||||
files = files || [];
|
||||
|
||||
var isNpm = (__dirname.replace(/\\/g, '/').toLowerCase().indexOf('node_modules/' + tools.appName.toLowerCase() + '.js-controller') !== -1);
|
||||
|
||||
if (typeof level === 'object') {
|
||||
userOptions = Object.assign({}, level);
|
||||
|
||||
level = userOptions.level;
|
||||
prefix = userOptions.prefix;
|
||||
noStdout = userOptions.noStdout;
|
||||
|
||||
if (userOptions.prefix !== undefined) delete userOptions.prefix;
|
||||
|
||||
if (userOptions.transport) {
|
||||
var fName = 0;
|
||||
for (var f in userOptions.transport) {
|
||||
if (!userOptions.transport.hasOwnProperty(f)) continue;
|
||||
if (userOptions.transport[f].type === 'file' && userOptions.transport[f].enabled !== false) {
|
||||
|
||||
userOptions.transport[f].filename = userOptions.transport[f].filename || 'log/' + tools.appName;
|
||||
|
||||
if (!userOptions.transport[f].fileext && userOptions.transport[f].filename.indexOf('.log') === -1) {
|
||||
userOptions.transport[f].fileext = '.log';
|
||||
}
|
||||
|
||||
if (!fName) userOptions.transport[f].systemLog = true;
|
||||
|
||||
userOptions.transport[f].handleExceptions = false;
|
||||
userOptions.transport[f].name = !fName ? tools.appName : 'dailyRotateFile' + fName;
|
||||
fName++;
|
||||
userOptions.transport[f].filename = userOptions.transport[f].filename.replace(/\\/g, '/');
|
||||
if (userOptions.transport[f].filename.match(/^\w:\/|^\//)) {
|
||||
userOptions.transport[f].filename = path.normalize(userOptions.transport[f].filename);
|
||||
} else {
|
||||
userOptions.transport[f].filename = path.normalize(__dirname + (isNpm ? '/../../../' : '/../') + userOptions.transport[f].filename);
|
||||
}
|
||||
|
||||
userOptions.transport[f].label = prefix || '';
|
||||
userOptions.transport[f].level = userOptions.transport[f].level || level;
|
||||
userOptions.transport[f].json = (userOptions.transport[f].json !== undefined) ? userOptions.transport[f].json : false;
|
||||
userOptions.transport[f].silent = (userOptions.transport[f].silent !== undefined) ? userOptions.transport[f].silent : false;
|
||||
userOptions.transport[f].colorize = (userOptions.transport[f].colorize !== undefined) ? userOptions.transport[f].colorize : ((userOptions.colorize === undefined) ? true : userOptions.colorize);
|
||||
userOptions.transport[f].localTime = (userOptions.transport[f].localTime !== undefined) ? userOptions.transport[f].localTime : ((userOptions.localTime === undefined) ? true : userOptions.localTime);
|
||||
// userOptions.transport[f].maxsize = (userOptions.transport[f].maxsize !== undefined) ? userOptions.transport[f].maxsize : defaultMaxSize;
|
||||
userOptions.transport[f].timestamp = timestamp;
|
||||
userOptions.transport[f].datePattern = '.yyyy-MM-dd' + (userOptions.transport[f].fileext || '');
|
||||
/*userOptions.transport[f].logException = function (message, info, next, err) {
|
||||
console.error(message);
|
||||
};*/
|
||||
|
||||
var _log = new DailyRotateFile(userOptions.transport[f]);
|
||||
options.transports.push(_log);
|
||||
} else if (userOptions.transport[f].type === 'syslog' && userOptions.transport[f].enabled !== false) {
|
||||
if (!SysLog) {
|
||||
console.error('Syslog configured, but not installed!');
|
||||
continue;
|
||||
}
|
||||
// host: The host running syslogd, defaults to localhost.
|
||||
// port: The port on the host that syslog is running on, defaults to syslogd's default port.
|
||||
// protocol: The network protocol to log over (e.g. tcp4, udp4, unix, unix-connect, etc).
|
||||
// path: The path to the syslog dgram socket (i.e. /dev/log or /var/run/syslog for OS X).
|
||||
// pid: PID of the process that log messages are coming from (Default process.pid).
|
||||
// facility: Syslog facility to use (Default: local0).
|
||||
// localhost: Host to indicate that log messages are coming from (Default: localhost).
|
||||
// sysLogType: The type of the syslog protocol to use (Default: BSD).
|
||||
// app_name: The name of the application (Default: process.title).
|
||||
// eol: The end of line character to be added to the end of the message (Default: Message without modifications).
|
||||
// replace the used by syslog attribute "type" with own "sysLogType"
|
||||
|
||||
// If no name defined, use hostname as name
|
||||
userOptions.transport[f].localhost = userOptions.transport[f].localhost || hostname;
|
||||
|
||||
if (userOptions.transport[f].sysLogType) {
|
||||
userOptions.transport[f].type = userOptions.transport[f].sysLogType;
|
||||
delete userOptions.transport[f].sysLogType;
|
||||
} else {
|
||||
delete userOptions.transport[f].type;
|
||||
}
|
||||
try {
|
||||
options.transports.push(new SysLog(userOptions.transport[f]));
|
||||
} catch (err) {
|
||||
console.log('Cannot activate syslog: ' + err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var opt = {
|
||||
name: !i ? tools.appName : 'dailyRotateFile' + i,
|
||||
filename: path.normalize(isNpm ? __dirname + '/../../../log/' + files[i] : __dirname + '/../log/' + files[i]),
|
||||
datePattern: '.yyyy-MM-dd.log',
|
||||
json: false, // If true, messages will be logged as JSON (default true).
|
||||
level: level,
|
||||
silent: false,
|
||||
localTime: true,
|
||||
colorize: (userOptions.colorize === undefined) ? true : userOptions.colorize,
|
||||
timestamp: timestamp,
|
||||
label: prefix || '',
|
||||
handleExceptions: false
|
||||
//maxsize: defaultMaxSize
|
||||
};
|
||||
|
||||
options.transports.push(new DailyRotateFile(opt));
|
||||
}
|
||||
}
|
||||
|
||||
if (!noStdout) {
|
||||
options.transports.push(new winston.transports.Console({
|
||||
level: level,
|
||||
silent: false,
|
||||
colorize: (userOptions.colorize === undefined) ? true : userOptions.colorize,
|
||||
timestamp: timestamp,
|
||||
label: prefix || ''
|
||||
}));
|
||||
}
|
||||
|
||||
var log = new winston.Logger(options);
|
||||
|
||||
log.getFileName = function () {
|
||||
if (this.transports && this.transports[tools.appName]) {
|
||||
if (this.transports[tools.appName].filename) {
|
||||
return this.transports[tools.appName].dirname + '/' + this.transports[tools.appName].filename;
|
||||
} else if (this.transports[tools.appName]._getFilename) {
|
||||
return this.transports[tools.appName].dirname + '/' + this.transports[tools.appName]._getFilename();
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
log.activateDateChecker = function (isEnabled, daysCount) {
|
||||
if (!isEnabled && this._fileChecker) {
|
||||
clearInterval(this._fileChecker);
|
||||
} else if (isEnabled && !this._fileChecker) {
|
||||
if (!daysCount) daysCount = 3;
|
||||
|
||||
// Check every hour
|
||||
this._fileChecker = setInterval(function () {
|
||||
if (this.transports[tools.appName] && fs.existsSync(this.transports[tools.appName].dirname)) {
|
||||
var files = fs.readdirSync(this.transports[tools.appName].dirname);
|
||||
var for3days = new Date();
|
||||
for3days.setDate(for3days.getDate() - daysCount);
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var match = files[i].match(/.+\.(\d+-\d+-\d+)/);
|
||||
if (match) {
|
||||
var date = new Date(match[1]);
|
||||
if (date < for3days) {
|
||||
// delete file
|
||||
try {
|
||||
this.transports[tools.appName].log('info', 'host.' + hostname + ' Delete log file ' + files[i]);
|
||||
fs.unlinkSync(this.transports[tools.appName].dirname + '/' + files[i]);
|
||||
} catch (e) {
|
||||
// there is a bug under windows, that file stays opened and cannot be deleted
|
||||
this.log(os.platform().match(/^win/) ? 'info' : 'error', 'host.' + hostname + ' Cannot delete file "' + path.normalize(this.transports[tools.appName].dirname + '/' + files[i]) + '": ' + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bind(this), 3600000); // every hour
|
||||
}
|
||||
};
|
||||
|
||||
winston.unhandleExceptions();
|
||||
|
||||
return log;
|
||||
};
|
||||
|
||||
function timestamp() {
|
||||
var ts = new Date();
|
||||
var result = ts.getFullYear() + '-';
|
||||
|
||||
/** @type {number | string} */
|
||||
var value = ts.getMonth() + 1;
|
||||
if (value < 10) value = '0' + value;
|
||||
result += value + '-';
|
||||
|
||||
value = ts.getDate();
|
||||
if (value < 10) value = '0' + value;
|
||||
result += value + ' ';
|
||||
|
||||
value = ts.getHours();
|
||||
if (value < 10) value = '0' + value;
|
||||
result += value + ':';
|
||||
|
||||
value = ts.getMinutes();
|
||||
if (value < 10) value = '0' + value;
|
||||
result += value + ':';
|
||||
|
||||
value = ts.getSeconds();
|
||||
if (value < 10) value = '0' + value;
|
||||
result += value + '.';
|
||||
|
||||
|
||||
value = ts.getMilliseconds();
|
||||
if (value < 10) {
|
||||
value = '00' + value;
|
||||
} else
|
||||
if (value < 100) {
|
||||
value = '0' + value;
|
||||
}
|
||||
|
||||
result += value + ' ';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = logger;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user