赞
踩
这是继上一篇文章 “Elasticsearch:Node.js ECS 日志记录 - Pino” 的续篇。我们继续上一篇文章来讲述使用 Winston 包来针对 Node.js 应用生成 ECS 向匹配的日子。此 Node.js 软件包为 winston 记录器提供了格式化程序,与 Elastic Common Schema (ECS) 日志记录兼容。结合 Filebeat 发送器,你可以在 Elastic Stack 中的一处监控所有日志。支持 winston 3.x 版本 >=3.3.3。
- npm install @elastic/ecs-winston-format
- npm install winston
winston-logging.js
- const winston = require('winston');
- const { ecsFormat } = require('@elastic/ecs-winston-format');
-
- const logger = winston.createLogger({
- format: ecsFormat(/* options */), // 1
- transports: [
- new winston.transports.Console()
- ]
- });
-
- logger.info('hi');
- logger.error('oops there is a problem', { err: new Error('boom') });
上面的代码的运行结果为:
Filebeat 7.16+
filebeat.yml
- filebeat.inputs:
- - type: filestream # 1
- paths: /path/to/logs.json
- parsers:
- - ndjson:
- overwrite_keys: true # 2
- add_error_key: true # 3
- expand_keys: true # 4
-
- processors: // 5
- - add_host_metadata: ~
- - add_cloud_metadata: ~
- - add_docker_metadata: ~
- - add_kubernetes_metadata: ~
Filebeat < 7.16
filebeat.yml
- filebeat.inputs:
- - type: log
- paths: /path/to/logs.json
- json.keys_under_root: true
- json.overwrite_keys: true
- json.add_error_key: true
- json.expand_keys: true
-
- processors:
- - add_host_metadata: ~
- - add_cloud_metadata: ~
- - add_docker_metadata: ~
- - add_kubernetes_metadata: ~
有关更多信息,请参阅 Filebeat 参考。
winston-logging.js
- const winston = require('winston');
- const { ecsFormat } = require('@elastic/ecs-winston-format');
-
- const logger = winston.createLogger({
- level: 'info',
- format: ecsFormat(/* options */), // 1
- transports: [
- new winston.transports.Console()
- ]
- });
-
- logger.info('hi');
- logger.error('oops there is a problem', { foo: 'bar' });
node winston-logging.js | jq .
运行此脚本(可在此处获得)将产生类似上面内容的日志输出。
格式化程序负责将数据序列化为 JSON,因此你无需添加 json 格式化程序。此外,格式化程序会自动生成 timestamp,因此你无需添加 timestamp 格式化程序。
默认情况下,格式化程序会将 Error 实例的 err 元字段转换为 ECS Error 字段。例如例子:
winston-logging.js
- const winston = require('winston');
- const { ecsFormat } = require('@elastic/ecs-winston-format');
- const logger = winston.createLogger({
- format: ecsFormat(),
- transports: [
- new winston.transports.Console()
- ]
- });
-
- const myErr = new Error('boom');
- logger.info('oops', { err: myErr });
可以通过 convertErr: false 选项禁用对 err 元字段的特殊处理:
winston-logging.js
- const winston = require('winston');
- const { ecsFormat } = require('@elastic/ecs-winston-format');
- const logger = winston.createLogger({
- format: ecsFormat({convertErr: false} ),
- transports: [
- new winston.transports.Console()
- ]
- });
-
- const myErr = new Error('boom');
- logger.info('oops', { err: myErr });
使用 convertReqRes: true 选项,格式化程序将在分别作为 req 和 res 元字段传递时自动转换 Node.js 核 request 和 response 对象。
winston-logging.js
- const http = require('http');
- const winston = require('winston');
- const { ecsFormat } = require('@elastic/ecs-winston-format');
-
- const logger = winston.createLogger({
- level: 'info',
- format: ecsFormat({ convertReqRes: true }), // 1
- transports: [
- new winston.transports.Console()
- ]
- });
-
- const server = http.createServer(handler);
- server.listen(3000, () => {
- logger.info('listening at http://localhost:3000')
- });
-
- function handler (req, res) {
- res.setHeader('Foo', 'Bar');
- res.end('ok');
- logger.info('handled request', { req, res }); // 2
- }
这将使用 ECS HTTP 字段生成包含请求和响应信息的日志。例如例子:
在上面,我们需要访问 http://localhost:3000 才能看到如上所示的日子信息。
此 ECS 日志格式化程序与 Elastic APM 集成。如果你的 Node 应用正在使用 Node.js Elastic APM Agent,则会将多个字段添加到日志记录中,以关联 APM 服务或跟踪和日志数据:
例如,运行 examples/http-with-elastic-apm.js 和 curl -i localhost:3000/ 会产生包含以下内容的日志记录:
- % node examples/http-with-elastic-apm.js | jq .
- ...
- "service.name": "http-with-elastic-apm",
- "service.version": "1.4.0",
- "service.environment": "development",
- "event.dataset": "http-with-elastic-apm"
- "trace.id": "7fd75f0f33ff49aba85d060b46dcad7e",
- "transaction.id": "6c97c7c1b468fa05"
- }
这些 ID 与 APM 代理报告的跟踪数据相匹配。
可以通过 apmIntegration: false 选项明确禁用与 Elastic APM 的集成,例如:
- const logger = winston.createLogger({
- format: ecsFormat({ apmIntegration: false }),
- // ...
- })
ecs-logging 规范建议日志记录中的前三个字段应为 @timestamp、log.level 和 message。从 1.5.0 版开始,此格式化程序不遵循此建议。这是可能的,但需要在 ecsFields 中为每个日志记录创建一个新对象。鉴于 ecs-logging 字段的排序是为了便于阅读,并且不会影响互操作性,因此决定优先考虑性能。
为 winston 创建以 ECS 日志记录格式发出的格式化程序。这是一种处理 ecsFields([options]) 和 ecsStringify([options]) 的单一格式。以下两个是等效的:
- const { ecsFormat, ecsFields, ecsStringify } = require('@elastic/ecs-winston-format');
- const winston = require('winston');
-
- const logger = winston.createLogger({
- format: ecsFormat(/* options */),
- // ...
- });
-
- const logger = winston.createLogger({
- format: winston.format.combine(
- ecsFields(/* options */),
- ecsStringify()
- ),
- // ...
- });
为 winston 创建一个格式化程序,将日志记录信息对象上的字段转换为 ECS 日志记录格式。
为 winston 创建一个格式化程序,将日志记录字符串化/序列化为 JSON。
这类似于 logform.json()。它们都使用 safe-stable-stringify 包来生成 JSON。一些区别:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。