创建常量类:cons.js
{
"common_logger":{
"description":"common logger config",
"switch":true,
"addr":"svc-kafka:9092",
"facility":"Nick Test Process",
"topic":"LOG",
"format":"YYYY-MM-DDTHH:mm:ss.SSSZ",
"hostName":false,
"user":false,
"file":false,
"lineNo":false,
"mod":false,
"normalize":false
}
}
创建普通日志发送js:logger.js
// get hostname
const os = require('os');
// attention : if in docker container, pass env 'HOST_NAME : $(hostname)' when running
let hostNickName = process.env['HOST_NAME'];
if (!hostNickName){
hostNickName = os.hostname();
}
// kafka dependency
var kafka = require('kafka-node');
var Producer = kafka.Producer;
// timeStamp utils
const timeUtil = require('moment-timezone');
// producer obj
var producer;
/**
* logger Entity
*/
class logger {
/**
* init param
* warp send content prior : power-->weak
* options --> default --> default is null? --> function passed
* @param {*} options must description
* @param options.switch O true=>on
* @param options.addr M kafka address ip:port
* @param options.facility M unique facility name, 2 producer must different facility
* @param options.topic O default is LOG
* @param options.format O timeStamp format
* @param options.hostName O option privieged, default use 'os' package fetch hostname, if docker appear, need pass this param
* @param options.user O option privieged
* @param options.file O option privieged, suggest this param pass by caller
* @param options.lineNo O option privieged, suggest this param pass by caller
* @param options.mod O option privieged, suggest fill this param by current module
* @param options.normalize O need normalize send data foramt, default is true
*
*/
constructor(options) {
this._switch = options.switch ? 'true' : 'false',
this._addr = options.addr,
this._facility = options.facility,
this._topic = options.topic ? options.topic : 'LOG',
this._format = options.format ? options.format : '',
this._hostName = options.hostName ? options.hostName : hostNickName,
this._user = options.user ? options.user : '',
this._file = options.file ? options.file : '',
this._lineNo = options.lineNo ? options.lineNo : '',
this._mod = options.mod ? options.mod : '',
this._normalize = options.normalize ? options.normalize : 'true';
}
// private kafka ready
async _setupConnection() {
if (!producer) {
return new Promise((resolve, reject) => {
const client = new kafka.KafkaClient({
kafkaHost: this._addr
});
producer = new Producer(client);
producer.on('error', function (err) {
reject(err);
return;
});
producer.on('ready', function () {
console.info(`common log kafka producer ready.`);
resolve(true);
return;
});
}).catch(e => {
console.log(`common log _setupConnection failed : ${JSON.stringify(e)}`);
return false;
});
} else {
return true;
}
}
/**
* debug log
* @param {*} message
*/
async debug(message, user, file, mod, lineno){
let res;
await this._send(message, 'DEBUG', user, file, mod, lineno).then(r => {
res = true;
}).catch(e => {
console.err(`debug send failed : ${JSON.stringify(e)}`)
res = false;
});
return res;
}
/**
* info log
* @param {*} message
* @param {*} tag
*/
async info(message, user, file, mod, lineno){
let res;
await this._send(message, 'INFO', user, file, mod, lineno).then(r => {
res = true;
}).catch(e => {
console.err(`info send failed : ${JSON.stringify(e)}`)
res = false;
});
return res;
}
/**
* warn log
* @param {*} message
* @param {*} tag
*/
async warn(message, user, file, mod, lineno){
let res;
await this._send(message, 'WARN', user, file, mod, lineno).then(r => {
res = true;
}).catch(e => {
console.err(`warn send failed : ${JSON.stringify(e)}`)
res = false;
});
return res;
}
/**
* error log
* @param {*} message
* @param {*} tag
*/
async error(message, user, file, mod, lineno){
let res;
await this._send(message, 'ERROR', user, file, mod, lineno).then(r => {
res = true;
}).catch(e => {
console.err(`error send failed : ${JSON.stringify(e)}`)
res = false;
});
return res;
}
/**
* fatal error log
* @param {*} message
* @param {*} tag
*/
async fatal(message, user, file, mod, lineno){
let res;
await this._send(message, 'FATAL', user, file, mod, lineno).then(r => {
res = true;
}).catch(e => {
console.err(`fatal send failed : ${JSON.stringify(e)}`)
res = false;
});
return res;
}
/**
* private send blogic
* @param {*} message message str
* @param {*} level log level
* @param {*} user record user
* @param {*} file current filename
* @param {*} mod current module
* @param {*} lineno file linenum
*/
async _send(message, level, user, file, mod, lineno) {
let setupRes = await this._setupConnection();
if (!setupRes){
return false;
}
return new Promise((resolve, reject) => {
// log switch: true=>on
let logSwitch = this._switch;
if (logSwitch != 'true') {
reject(`common log logSwitch is closed.`);
return;
}
let msg;
// need normalize send data format
if ('true' === this._normalize){
try {
// get timeStamp
let now = timeUtil.format(this._format);
// hostname
let machineName;
if (this._hostName){
machineName = this._hostName;
} else {
machineName = 'unknown-Host-Name';
}
// msg obj
let messageObj = new Object();
messageObj['facility'] = this._facility ? this._facility : 'UFO';
messageObj['time'] = now;
messageObj['host'] = machineName;
messageObj['user'] = this._user ? this._user : user;
messageObj['file'] = this._file ? this._file : file;
messageObj['mod'] = this._mod ? this._mod : mod;
messageObj['lineno'] = this._lineNo ? this._lineNo : lineno;
messageObj['level'] = level;
messageObj['message'] = message;
// msg
msg = JSON.stringify(messageObj);
} catch (error) {
console.log(error.message);
}
} else {
msg = message;
}
producer.send([{
topic: this._topic,
messages: msg
}], function (err, result) {
if (err) {
reject(`common log kafka send message failed : ${err}, result is ${result}`);
return;
} else {
// console.log(`kafka send message succeed`);
resolve(true);
return;
}
});
}).catch(e => {
console.error(`common logger send promise failed : ${e}`);
return false;
});
}
}
module.exports.logger = logger;
调用测试,创建测试js:test.js
// logger init
var logger= require('./logger').logger;
cons['common_logger']['mod'] = 'map';
cons['common_logger']['file'] = 'map.js';
var clog = new logger(cons['common_logger']);
// send
clog.error(message, user, '', '', 'L205');