egg-elk & 日志规范

- You can't play God without being acquainted with the Devil.
想要扮演上帝,你就不能不去了解魔鬼。

第一部分 简述ELK

ELK 是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。

  1. Elasticsearch 是一个搜索和分析引擎
  2. Logstash 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等存储库中。
  3. Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化

ELK Stack

Elasticsearch 的核心是搜索引擎,所以用户开始将其用于日志用例,并希望能够轻松地对日志进行采集和可视化。有鉴于此,Elastic 引入了强大的采集管道 Logstash 和灵活的可视化工具 Kibana

ELK日志系统数据流图如下:

第二部分 日志的重要性

第三部分 egg 日志扩展

Async Local Storage

思考问题

Now what if you want to persist specific data with that specific user whenever the asynchronous code specific to them is being called?

单线程的性质&事件处理机制就不赘述,直接对比下侧代码。

let idSeq = 0;
http.createServer(async (req, res) => {
// some synchronous operation (save state)
// some asynchronous operation
await test()
res.end();
}).listen(8080);

async fun test() {
// 如何判断该函数是具体谁发起的?
console.log('发起该异步函数的是?')
}

const http = require('http');
const { AsyncLocalStorage } = require('async_hooks');

const asyncLocalStorage = new AsyncLocalStorage();

function logWithId(msg) {
const id = asyncLocalStorage.getStore();
console.log(`${id !== undefined ? id : '-'}:`, msg);
}

let idSeq = 0;
http.createServer((req, res) => {
asyncLocalStorage.run(idSeq++, () => {
logWithId('start');
// Imagine any chain of async operations here
setImmediate(() => {
logWithId('finish');
res.end();
});
});
}).listen(8080);

http.get('http://localhost:8080');
http.get('http://localhost:8080');
// Prints:
// 0: start
// 1: start
// 0: finish
// 1: finish

参考

最佳日志实践(v2.0)
Node.js + ELK 日志规范
手把手教你搭建 ELK 实时日志分析平台
如何更优雅的使用egg的日志体系? #2006
What’s Async Local Storage in Node.js v14?