kafka插件选择
由于使用的是egg,因此最先考虑的是有没有egg kafka的插件,在gthub中找到了egg-kafka-node,
但是此插件在node v16版本以上无法使用。因此以下的两个插件可以自由选择,我使用的是kafkajs。
1. kafka-node
2. kafkajs
如何获取到egg的各种日志
egg的文档中找到了高级自定义日志,按照文档创建自定义的transport文件,再将kafkajs中的producer示例代码结合一下:
const util = require('util');
const Transport = require('egg-logger').Transport;
const { Kafka } = require('kafkajs');
class KafkaTransport extends Transport {
// 定义 log 方法,在此方法中把日志上报给远端服务
log(level, args) {
let log;
if (args[0] instanceof Error) {
const err = args[0];
log = util.format(
'%s: %s\n%s\npid: %s\n',
err.name,
err.message,
err.stack,
process.pid,
);
} else {
log = util.format(...args);
}
const kafka = new Kafka({
brokers:['此处是kafka的地址']
});
const producer = kafka.producer();
producer.connect().then(()=>{
producer.send({
topic:'',
message:[{value:JSON.stringify(log)}]
}).catch(err=>{
console.log("kafka send message error", err);
})
}).catch(err=>{
console.log("kafka connect error", err);
});
}
}
module.exports = KafkaTransport;
还需要在app.js中添加下面代码,让自定义transport生效
const {app} = this;
app.getLogger('logger').set('名字随便',new KafkaTransport({ level:'ALL',app}));
现在启动项目,所有通过app.logger或者ctx.logger产生的日志都可以从自定义的transport发送到kafka了。在实际使用中不同环境可能对应不同的kafka地址或topic,因此可以将对应环境的kafka配置写在config.[env].js文件中,例如:
// config.dev.js
...
config.kafkaConfig = {
host:['地址1','地址2'],
topic:'xxxx'
}
...
然后对transport.js进行小小的改动:
...
const { app } = this.options;
const kafka = new Kafka({
brokers: app.config.kafkaConfig.host
});
const producer = kafka.producer();
producer.connect().then(()=>{
producer.send({
topic: app.config.kafkaConfig.topic,
message: [{value:JSON.stringify(log)}]
}).catch(err=>{
console.log("kafka send message error", err);
})
}).catch(err=>{
console.log("kafka connect error", err);
})
...
这样就可以根据不同的环境将日志发往对应的kafka了,有疑问或者建议欢迎在评论区交流。