公司部署的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能夠看到下面這樣 性能