公司部署的kibana目前是从容器中的标准输入输出中采集日志,目前还不支持指定文件或者目录,egg自己的日志是基于文件的,因此是没发在kibana中查看egg自己打印的日志node
linux shell下经常使用输入输出操做符是:linux
1. 标准输入 (stdin) :代码为 0 ,使用 < 或 << ; /dev/stdin -> /proc/self/fd/0 0表明:/dev/stdin
2. 标准输出 (stdout):代码为 1 ,使用 > 或 >> ; /dev/stdout -> /proc/self/fd/1 1表明:/dev/stdout
3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ; /dev/stderr -> /proc/self/fd/2 2表明:/dev/stderr
复制代码
node中console.log会输出到stdout、console.error输出到stderr,因此要想收集到日志,那就要用console方式输出,shell
Egg 框架提供了多种扩展点扩展自身的功能:bash
Application
Context
Request
Response
Helper
在开发中,咱们既可使用已有的扩展 API 来方便开发,也能够对以上对象进行自定义扩展,进一步增强框架的功能。
复制代码
我选择基于Context进行拓展,给他增长一个自定义Log方法,代码以下,能够根据本身的业务需求自行修改,文件路径为app/extend/context.js
app
module.exports = {
logs: [],
LogStart (text) {
const time = new Date()
this.logs = [{
time,
text: 'start print log'
}]
},
Log (text) {
const time = new Date()
this.logs.push({
time,
text
})
},
LogEnd (type) {
const tranceId = new Date().getTime()
const url = this.request.url
const userId = this.request.header['user-id']
let logObj = {
tranceId,
userId,
url,
steps: {}
}
this.logs.map((item, index) => {
let timeStr = item.time.toLocaleString() + ' ' + item.time.getMilliseconds() + 'ms'
logObj.steps[index] = `< ${timeStr} > - ${item.text}`
})
const useTime = new Date().getTime() - new Date(this.logs[0].time).getTime()
logObj.useTime = `${useTime} ms`
if (type === 'error') {
console.error('System Error:' + JSON.stringify(logObj))
} else {
console.log(JSON.stringify(logObj))
}
}
}
复制代码
一般 Web 访问是高频访问,每次打印日志都写磁盘会形成频繁磁盘 IO,为了提升性能,咱们采用的文件日志写入策略是: 日志同步写入内存,异步每隔一段时间(默认 1 秒)刷盘框架
因此我在日志调用结束会将日志的完整链路一次所有打出,防止频繁调用,只输出一条记录,在kibana中方便查看异步
这样咱们在中间件中就能够这样调用async
module.exports = function (options) {
return async function proxy(ctx, next) {
await next()
ctx.LogStart()
ctx.Log('你要打印的日志!')
ctx.Log('执行A操做!')
ctx.Log('执行B操做!')
ctx.LogEnd()
};
};
复制代码
最后在kibana能够看到下面这样 性能