Elasticsearch:Golang ECS 日志记录 - zap

251 阅读2分钟

ECS 记录器是你最喜欢的日志库的格式化程序/编码器插件。它们可让你轻松地将日志格式化为与 ECS 兼容的 JSON。

编码器以 JSON 格式记录日志,并在可能的情况下依赖默认的 zapcore/json_encoder。它还处理 ECS 错误格式的错误字段记录。

默认情况下,会添加以下字段:



1.  {
2.    "log.level": "info",
3.    "@timestamp": "2020-09-13T10:48:03.000Z",
4.    "message":" some logging info",
5.    "ecs.version": "1.6.0"
6.  }


安装

将包添加到你的 go.mod 文件中:

go.mod



1.  module zerolog-logging
2.  require go.elastic.co/ecszap master
3.  require go.uber.org/zap master


我们使用如下的命令来下载包:



1.  go get go.elastic.co/ecszap
2.  go get go.uber.org/zap


配置

设置默认记录器。例如:



1.  encoderConfig := ecszap.NewDefaultEncoderConfig()
2.  core := ecszap.NewCore(encoderConfig, os.Stdout, zap.DebugLevel)
3.  logger := zap.New(core, zap.AddCaller())


你可以自定义 ECS 记录器。例如:



1.  encoderConfig := ecszap.EncoderConfig{
2.    EncodeName: customNameEncoder,
3.    EncodeLevel: zapcore.CapitalLevelEncoder,
4.    EncodeDuration: zapcore.MillisDurationEncoder,
5.    EncodeCaller: ecszap.FullCallerEncoder,
6.  }
7.  core := ecszap.NewCore(encoderConfig, os.Stdout, zap.DebugLevel)
8.  logger := zap.New(core, zap.AddCaller())


示例

使用结构化日志记录

zap1.go



1.  package main

3.  import (
4.  	"errors"
5.  	"os"

7.  	"go.elastic.co/ecszap"
8.  	"go.uber.org/zap"
9.  )

11.  func main() {
12.  	encoderConfig := ecszap.NewDefaultEncoderConfig()
13.  	core := ecszap.NewCore(encoderConfig, os.Stdout, zap.DebugLevel)
14.  	logger := zap.New(core, zap.AddCaller())

16.  	logger = logger.With(zap.String("custom", "foo"))
17.  	logger = logger.Named("mylogger")

19.  	// Use strongly typed Field values
20.  	logger.Info("some logging info",
21.  		zap.Int("count", 17),
22.  		zap.Error(errors.New("boom")))
23.  }


我们可以使用如下的方法来运行上面的应用:

go run zap1.go | jq .

Log errors

zap_error.go



1.  package main

3.  import (
4.  	"errors"
5.  	"os"

7.  	pkgerrors "github.com/pkg/errors"
8.  	"go.elastic.co/ecszap"
9.  	"go.uber.org/zap"
10.  )

12.  func main() {
13.  	encoderConfig := ecszap.NewDefaultEncoderConfig()
14.  	core := ecszap.NewCore(encoderConfig, os.Stdout, zap.DebugLevel)
15.  	logger := zap.New(core, zap.AddCaller())

17.  	err := errors.New("boom")
18.  	logger.Error("some error", zap.Error(pkgerrors.Wrap(err, "crash")))
19.  }


我们使用如下的命令来运行应用:

go run zap_error.go | jq .

使用 sugar logger

zap_sugar.go



1.  package main

3.  import (
4.  	"os"

6.  	"go.elastic.co/ecszap"
7.  	"go.uber.org/zap"
8.  )

10.  func main() {
11.  	encoderConfig := ecszap.NewDefaultEncoderConfig()
12.  	core := ecszap.NewCore(encoderConfig, os.Stdout, zap.DebugLevel)
13.  	logger := zap.New(core, zap.AddCaller())

15.  	sugar := logger.Sugar()
16.  	sugar.Infow("some logging info",
17.  		"foo", "bar",
18.  		"count", 17,
19.  	)
20.  }


我们使用如下的命令来运行:

go run zap_sugar.go | jq .

 把日志写入到 Elasticsearch

  1. 按照 Filebeat 快速入门
  2. 将以下配置添加到你的 filebeat.yaml 文件中。

Filebeat 7.16+

filebeat.yaml



1.  filebeat.inputs:
2.  - type: filestream  # 1
3.    paths: /path/to/logs.json
4.    parsers:
5.      - ndjson:
6.        overwrite_keys: true # 2
7.        add_error_key: true  # 3
8.        expand_keys: true    # 4

10.  processors: # 5
11.    - add_host_metadata: ~
12.    - add_cloud_metadata: ~
13.    - add_docker_metadata: ~
14.    - add_kubernetes_metadata: ~


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

Filebeat < 7.16

filebeat.yaml



1.  filebeat.inputs:
2.  - type: log
3.    paths: /path/to/logs.json
4.    json.keys_under_root: true
5.    json.overwrite_keys: true
6.    json.add_error_key: true
7.    json.expand_keys: true

9.  processors:
10.  - add_host_metadata: ~
11.  - add_cloud_metadata: ~
12.  - add_docker_metadata: ~
13.  - add_kubernetes_metadata: ~