Nodejs实现Kafka日志发送

创建常量类: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');

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值