這是之前系列文章:
-
Elasticsearch:Node.js ECS 日志記錄 - Pino
-
Elasticsearch:Node.js ECS 日志記錄 - Winston
中的第三篇文章。在今天的文章中,我將描述如何使用 Morgan 包針對 Node.js 應用進行日子記錄。此 Morgan Node.js 軟件包為 morgan 日志中間件(通常與 Express 一起使用)提供了一個格式化程序,與 Elastic Common Schema (ECS) 日志記錄兼容。結合 Filebeat 發送器,你可以在 Elastic Stack 中的一處監控所有日志。
設置
安裝
npm install @elastic/ecs-morgan-format
npm install morgan
配置
morgan-logging.js
const app = require('express')();
const morgan = require('morgan');
const { ecsFormat } = require('@elastic/ecs-morgan-format');app.use(morgan(ecsFormat(/* options */))); // 1// ...
app.get('/', function (req, res) {res.send('hello, world!');
})
app.listen(3000);
- 將 ECS 格式化程序傳遞給 morgan()。
配置 Filebeat
收集 ECS 格式化的日志的最佳方式是使用 Filebeat:
Filebeat 7.16+
filebeat.yml
filebeat.inputs:
- type: filestream # 1paths: /path/to/logs.jsonparsers:- ndjson:overwrite_keys: true # 2add_error_key: true # 3expand_keys: true # 4processors: # 5- add_host_metadata: ~- add_cloud_metadata: ~- add_docker_metadata: ~- add_kubernetes_metadata: ~
- 使用文件流輸入從活動日志文件中讀取行。
- 如果發生沖突,解碼的 JSON 對象的值將覆蓋 Filebeat 通常添加的字段(type、source、offset 等)。
- 如果發生 JSON 解組錯誤,Filebeat 將添加 “error.message” 和 “error.type: json” 鍵。
- Filebeat 將遞歸地從解碼的 JSON 中去掉點鍵,并將其擴展為分層對象結構。
- 處理器可增強您的數據。請參閱 processor 以了解更多信息。
Filebeat < 7.16
filebeat.yml
filebeat.inputs:
- type: logpaths: /path/to/logs.jsonjson.keys_under_root: truejson.overwrite_keys: truejson.add_error_key: truejson.expand_keys: trueprocessors:
- add_host_metadata: ~
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
有關更多信息,請參閱 Filebeat 參考。
使用方法
morgan-logging.js
const app = require('express')();
const morgan = require('morgan');
const { ecsFormat } = require('@elastic/ecs-morgan-format');app.use(morgan(ecsFormat(/* options */))); // 1app.get('/', function (req, res) {res.send('hello, world!');
})
app.get('/error', function (req, res, next) {next(new Error('boom'));
})app.listen(3000)
- 請參閱下面的可用選項。
運行上面的應用,并訪問 http://localhost:3000。
npm install express
$ pwd
/Users/liuxg/nodejs/nodejs-logs
$ ls
morgan-logging.js pino-logging.js winston-logging.js
$ node morgan-logging.js | jq .
運行此腳本(完整示例在這里)并發出請求(通過 curl -i localhost:3000/)將產生類似于以上內容的日志輸出。
Format 選項
你可以傳遞任何通常傳遞給 morgan() 的格式參數,日志 “message” 字段將使用指定的格式。默認為 combined。
const app = require('express')();
const morgan = require('morgan');
const { ecsFormat } = require('@elastic/ecs-morgan-format');app.use(morgan(ecsFormat({ format: 'tiny' }))); // 1
// ...
- 如果 “format” 是你使用的唯一選項,你可以將其作為 ecsFormat('tiny') 傳遞。
log.level
如果響應代碼 >= 500,log.level 字段將為 “error”,否則為 “info”。例如,再次運行 examples/express.js,curl -i localhost:3000/error 將產生:
% node examples/express.js | jq .
{"@timestamp": "2021-01-18T17:52:12.810Z","log.level": "error","message": "::1 - - [18/Jan/2021:17:52:12 +0000] \"GET /error HTTP/1.1\" 500 1416 \"-\" \"curl/7.64.1\"","http": {"response": {"status_code": 500,...
使用 APM 進行日志關聯
此 ECS 日志格式化程序與 Elastic APM 集成。如果你的 Node 應用正在使用 Node.js Elastic APM Agent,則會將多個字段添加到日志記錄中,以關聯 APM 服務或跟蹤和日志數據:
- 當前跟蹤跨度時調用的日志語句(例如 logger.info(...))將包括跟蹤字段?—?trace.id、transaction.id。
- 由 APM 代理確定或在 APM 代理上配置的多個服務標識符字段允許在 Kibana 中的服務和日志之間進行交叉鏈接?—?service.name、service.version、service.environment、service.node.name。
- event.dataset 在 Elastic Observability 應用中啟用日志率異常檢測。
例如,運行 examples/express-with-apm.js 和 curl -i localhost:3000/ 會產生包含以下內容的日志記錄:
% node examples/express-with-apm.js | jq .
{// The same fields as before, plus:"service.name": "express-with-elastic-apm","service.version": "1.1.0","service.environment": "development","event.dataset": "express-with-elastic-apm","trace.id": "116d46f667a7600deed9c41fa015f7de","transaction.id": "b84fb72d7bf42866"
}
這些 ID 與 APM 代理報告的跟蹤數據相匹配。
可以通過 apmIntegration: false 選項明確禁用與 Elastic APM 的集成,例如:
app.use(morgan(ecsFormat({ apmIntegration: false })));
參考
ecsFormat([options])
- options {type-object} 支持以下選項:
- format {type-string} 格式名稱(例如 combined)、格式函數(例如 morgan.combined)或格式字符串(例如 :method :url :status)。這用于格式化“message”字段。默認值?morgan.combined。
- convertErr {type-boolean} 是否將記錄的錯誤字段轉換為 ECS 錯誤字段。默認值:true。
- apmIntegration {type-boolean} 是否啟用 APM 代理集成。默認值:true。
- serviceName {type-string} “service.name”值。如果指定,則覆蓋來自活動 APM 代理的任何值。
- serviceVersion {type-string} “service.version”值。如果指定,則覆蓋來自活動 APM 代理的任何值。
- serviceEnvironment {type-string} “service.environment”值。如果指定,則將覆蓋來自活動 APM 代理的任何值。
- serviceNodeName {type-string} “service.node.name” 值。如果指定,則將覆蓋來自活動 APM 代理的任何值。
- eventDataset {type-string} “event.dataset” 值。如果指定,則將覆蓋使用 ${serviceVersion} 的默認設置。
為 morgan 創建以 ECS 日志記錄格式發出的格式化程序。