首页 > 编程语言 >Elasticsearch:Node.js ECS 日志记录 - Pino

Elasticsearch:Node.js ECS 日志记录 - Pino

时间:2024-07-08 15:56:04浏览次数:24  
标签:Node pino log js ECS Pino 日志 const

在我的上一篇文章 “Beats:使用 Filebeat 从 Python 应用程序中提取日志” 里,我详述了如何使用 Python 来生成日志,并使用 Filebeat 来收集日志到 Elasticsearch 中。在今天的文章中,我来详细描述如何使用 Node.js 来生成 ECS 相兼容的日子。ECS 相兼容的日志符合易于 Elasticsearch 对日志进行分析并进行可视化。

介绍

Node.js ECS 记录器是你最喜欢的日志库的格式化插件。它们可轻松将你的日志格式化为与 ECS 兼容的 JSON。结合 filebeat,你可以将日志直接发送到 Elasticsearch,并利用 Kibana 的日志应用程序在一个地方检查所有日志。

Node.js ECS 日志格式化程序记录结构化的 JSON,并支持对来自 Node.js 核心和流行 Web 框架的错误对象和 HTTP 请求和响应对象进行序列化。最小日志记录包括以下字段:

{
  "@timestamp": "2021-01-13T21:32:38.095Z",
  "log.level": "info",
  "message": "hi",
  "ecs.version": "8.10.0"
}

提示:想要了解有关 ECS、ECS 日志记录和其他可用语言插件的更多信息?请参阅 ECS 日志记录指南

有关如何生成 ECS 相兼容的日子,我们有如下的几种方法。

在今天的文章里,我们先来介绍 Pino。

使用 Pino 进行 ECS 日志记录

此 Node.js 包为 pino 记录器提供了格式化程序,与 Elastic Common Schema (ECS) 日志记录兼容。结合 Filebeat 发送器,你可以在 Elastic Stack 中的一处监控所有日志。支持 pino 6.x、7.x 和 8.x 版本。

设置

安装

npm install @elastic/ecs-pino-format
npm install pino

配置

const { ecsFormat } = require('@elastic/ecs-pino-format');
const pino = require('pino');

const log = pino(ecsFormat(/* options */));  // 1
log.info('hi');
log.error({ err: new Error('boom') }, 'oops there is a problem');
// ...
  • 这将配置 Pino 的 formatters、messageKey 和 timestamp 选项。

配置 filebeat

1)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: 
  - add_host_metadata: ~
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~
  1. 使用 filestream 输入从活动日志文件中读取行。
  2. 如果发生冲突,解码的 JSON 对象的值将覆盖 Filebeat 通常添加的字段(type, source, offset 等)。
  3. 如果发生 JSON 解组错误,Filebeat 将添加 “error.message” 和 “error.type: json” 键。
  4. Filebeat 将递归地从解码的 JSON 中去掉点键,并将其扩展为分层对象结构。
  5. 处理器可增强你的数据。请参阅 processors 以了解更多信息。

2)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 参考

更多关于如何配置 Filebeat,请参考文章 “Beats:使用 Filebeat 从 Python 应用程序中提取日志”。

如何使用

我们创建如下的一个简单的应用:

pino-logging.js

const { ecsFormat } = require('@elastic/ecs-pino-format');
const pino = require('pino');

const log = pino(ecsFormat(/* options */)); 
log.info('Hello world');

const child = log.child({ module: 'foo' });
child.warn('From child');

运行上面的代码:

node pino-logging.js 
$ node pino-logging.js 
{"log.level":"info","@timestamp":"2024-07-08T01:32:42.947Z","process.pid":43946,"host.hostname":"liuxgm.local","ecs.version":"8.10.0","message":"Hello world"}
{"log.level":"warn","@timestamp":"2024-07-08T01:32:42.947Z","process.pid":43946,"host.hostname":"liuxgm.local","ecs.version":"8.10.0","module":"foo","message":"From child"}

在配置 ecsFormat 时,我们在下面将会看到更多的选项。

Error logging

默认情况下,格式化程序会将 Error 实例的 err 字段转换为 ECS Error 字段。例如:

pino-logging.js

const { ecsFormat } = require('@elastic/ecs-pino-format');
const pino = require('pino');
const log = pino(ecsFormat());

const myErr = new Error('boom');
log.info({ err: myErr }, 'oops');

将产生(为了便于阅读,打印得很漂亮):

这类似于并覆盖了 Pino 的默认 err 序列化器。可以通过 convertErr: false 选项禁用对 err 字段的特殊处理:

const log = pino(ecsFormat({ convertErr: false }));

HTTP 请求和响应日志记录

使用 convertReqRes: true 选项,格式化程序将在分别作为 req 和 res 字段传递时自动转换 Node.js 核心 requestresponse 对象。(此选项取代了 req 和 res Pino 序列化器的使用。)

pino-logging.js

const http = require('http');
const { ecsFormat } = require('@elastic/ecs-pino-format');
const pino = require('pino');

const log = pino(ecsFormat({ convertReqRes: true }));  // 1

const server = http.createServer(function handler (req, res) {
  res.setHeader('Foo', 'Bar');
  res.end('ok');
  log.info({ req, res }, 'handled request');  // 2
});

server.listen(3000, () => {
  log.info('listening at http://localhost:3000');
})
  1. 使用 convertReqRes 选项
  2. 使用 req 和/或 res 字段进行记录

这将使用 ECS HTTP 字段生成包含请求和响应信息的日志。例如:

为了生成上面的日子,我们需要访问本地的服务器 http://localhost:3000/.

examples/ 目录展示了使用请求和响应日志的示例程序:使用 Express、使用 pino-http 中间件包等。

使用 APM 进行日志关联

此 ECS 日志格式化程序与 Elastic APM 集成。如果你的 Node 应用正在使用 Node.js Elastic APM Agent,则会将多个字段添加到日志记录中,以关联 APM 服务或跟踪和日志数据:

  • 当前跟踪 span 时调用的日志语句(例如 logger.info(...))将包括跟踪字段 —  trace.id、transaction.id、span.id。
  • 由 APM 代理确定或在 APM 代理上配置的多个服务标识符字段允许在 Kibana 中的服务和日志之间进行交叉链接 — service.name、service.version、service.environment、service.node.name。
  • event.dataset 在 Elastic Observability 应用中启用日志率异常检测

例如,运行 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": "9f338eae7211b7993b98929046aed21d",
  "transaction.id": "2afbef5642cc7a3f",
...

这些 ID 与 APM 代理报告的跟踪数据相匹配。

可以通过 apmIntegration: false 选项明确禁用与 Elastic APM 的集成,例如:

const log = pino(ecsFormat({ apmIntegration: false }));

限制和注意事项

ecs-logging 规范建议日志记录中的前三个字段必须是 @timestamp、log.level 和 message。Pino 不提供将 message 字段放在前面的机制。鉴于 ecs-logging 字段的排序是为了便于阅读,并且不会影响互操作性,因此这并不是一个重大问题。

Pino 当前提供的钩子(hook)不允许此包转换传递给 <logger>.child({ ... }) 的字段。这意味着,即使使用 convertReqRes 选项,对 <logger>.child({ req }) 的调用也不会将该 req 转换为 ECS HTTP 字段。对于执行此操作的 pino-http 用户来说,这是一个轻微的限制。

参考

ecsFormat([options])

  • options {type-object} 支持以下选项:
    • convertErr {type-boolean} 是否将记录的 err 字段转换为 ECS 错误字段。默认值:true。
    • convertReqRes {type-boolean} 是否将记录的 req 和 res HTTP 请求和响应字段记录到 ECS HTTP、用户代理和 URL 字段。默认值:false。
    • 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} 的默认设置。

为 pino(...) 创建选项,用于配置 ECS 日志记录格式输出。

标签:Node,pino,log,js,ECS,Pino,日志,const
From: https://blog.csdn.net/UbuntuTouch/article/details/140258495

相关文章

  • 通过高德地图 JS API实现 鼠标绘制多边形
    效果图:  核心代码:<template><a-modaltitle="选择地图所在位置":width="width":visible="visible"@ok="handleOk"@cancel="handleCancel"cancelText="关闭"><divclass="location-map-box&......
  • nodejs编写退出登录的接口逻辑
    目录1.安装必要的依赖2.登录成功生成和返回JWT3.在服务器端维护一个黑名单列表,记录已失效的JWT4.在验证JWT时检查黑名单5.退出登录时将JWT添加到黑名单中完整代码nodejs实现退出登录接口的逻辑,通常包括以下步骤:安装必要的依赖登录成功生成和返回JWT。在服务器......
  • nodejs登录成功生成token并验证
    目录1.安装必要的依赖包2.创建Express应用3.生成token4.使用`express-jwt`验证Token5.错误处理在Node.js中,nodejs登录成功生成token并验证通常涉及以下几个步骤:安装必要的依赖包:常用的库包括 `express`用于创建服务器,`jsonwebtoken`用于处理JWT(JSONWebToken),`expr......
  • [NodeJS] NodeJS运行原理简记
    NodeJS的基本组成NodeJS是JavaScript运行时,主要由V8引擎和libuv组成,其中V8使用javascript和c++编写,而libuv是纯c++编写的,二者都是开源的。V8引擎用于将javascript代码转换为计算机可以执行的机器码;而libuv则负责完成异步IO、与操作系统交互(文件系统和网络模块)、事件循......
  • node.js 写一个静态目录做cdn
    /**@Author:HuangBingQuan<[email protected]>*@Date:2024-07-0721:16:08*@LastEditTime:2024-07-0812:56:45*@FilePath:/myCdn/index.js*/consthttp=require('http');constfs=require('fs');constURL=require(......
  • 起底:Three.js和Cesium.js,二者异同点,好比全科和专科.
    Three.js和Cesium.js是两个常用的webGL引擎,很多小伙伴容易把它们搞混淆了,今天威斯数据来详细介绍一下,他们的起源、不同点和共同点,阅读后你就发现二者就像全科医院和专科医院的关系,很好识别。一、二者的起源Three.js的起源:Three.js是由RicardoCabello(也被称为mrdoob)创建的开......
  • 一个难忘的json反序列化问题
    前言最近我在做知识星球中的商品秒杀系统,昨天遇到了一个诡异的json反序列化问题,感觉挺有意思的,现在拿出来跟大家一起分享一下,希望对你会有所帮助。案发现场我最近在做知识星球中的商品秒杀系统,写了一个filter,获取用户请求的header中获取JWT的token信息。然后根据token信息,获取......
  • 记录npm、node等的相关错误(!!!)
    报错情况当我在试着运行奇文网盘项目的时候,文档中推荐使用node版本为12.13.1,此时我使用的是nvm,所以当即就快速的切换node版本,想要去运行它。npmi还是一如既往地报错,所以我还是一如既往地采用cnpmi来下载包(经验之谈,由于想去后端发展,所以就没关心过前端的东西)。下载好之后,飞快的......
  • Win11系统提示找不到JSC.Resources.dll文件的解决办法
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个JSC.Resources.dll文件(挑选合适的版本文件)......
  • JS根据json数组多个字段排序及json数组常用操作
    本文转载自:https://www.jb51.net/article/162623.htm js根据json数组多个字段排序的实现代码如下所示:1/**数组根据数组对象中的某个属性值进行排序的方法2*使用例子:newArray.sort(sortByArr(['number'],false))//表示根据number属性降序排列;若第二个参数不传递,默......