【问题标题】:How do I get fluentd / elasticsearch to parse the "log" key_name as json from a kubernetes pod?如何让 fluentd / elasticsearch 将 kubernetes pod 中的“log”key_name 解析为 json?
【发布时间】:2020-01-17 10:38:42
【问题描述】:

我在尝试从 k8s 集群中的 fluentd 获取日志到 elasticsearch 时遇到问题。

我有几个 Web 应用程序将它们的日志输出为 json。在本地使用带有 docker 容器的简单设置,我可以灵活地正确读取和解析日志。以下是 kibana 中显示的本地 json 示例:

{
  "_index": "logstash-2020.01.17",
  "_type": "fluentd",
  "_id": "S620sm8B2LEvFR841ylg",
  "_version": 1,
  "_score": null,
  "_source": {
    "log": {
      "@timestamp": "2020-01-17T08:53:03.066290",
      "caller": "StaticFileHelper.py::get",
      "data": {
        "python.thread": "Thread-1[{record.thread}]",
        "python.lineno": 45,
        "python.filename": "StaticFileHelper.py",
        "python.logger_name": "root",
        "python.module": "StaticFileHelper",
        "python.funcName": "get",
        "python.pid": 11239
      },
      "message": "application/javascript",
      "level": "INFO"
    },
    "@timestamp": "2020-01-17T08:53:03.000000000+00:00"
  },
  "fields": {
    "@timestamp": [
      "2020-01-17T08:53:03.000Z"
    ],
    "log.@timestamp": [
      "2020-01-17T08:53:03.066Z"
    ]
  },
  "sort": [
    1579251183000
  ]
}

在索引模式下,我可以看到正确的映射。当我在日志输出中引入新字段时,映射会更新。这里的输出示例:

log.@timestamp: date
log.caller: string
log.caller.keyword: string
log.data.python.filename: string
log.data.python.filename.keyword: string
log.data.python.funcName :string

集群中的“log”字段没有被正确解析:

{
  "_index": "logstash-2020.01.17",
  "_type": "fluentd",
  "_id": "atUDs28BFgXM_nqQvYUY",
  "_version": 1,
  "_score": null,
  "_source": {
    "log": "{'@timestamp': '2020-01-17T10:19:21.775339', 'caller': 'RequestLoggingManager.py::print_request_id', 'data': {'python.thread': 'MainThread[{record.thread}]', 'python.lineno': 28, 'python.filename': 'RequestLoggingManager.py', 'python.logger_name': 'root', 'python.module': 'RequestLoggingManager', 'python.funcName': 'print_request_id', 'request_id': '1579256361-1494-XYyVj', 'python.pid': 8}, 'message': 'request: \"1579256361-1497-JUeYF\" is about to enter \"get_settings\"', 'level': 'INFO'}\n",
    "stream": "stderr",
    "docker": {
      "container_id": "fc5b0d5b0aa4008961b18dfe93c4e04b2cfbde0f7ff072dc702c55823baba3a4"
    },
    "kubernetes": {
      "container_name": "cms",
      "namespace_name": "default",
      "pod_name": "cms-68c4b49657-b88hs",
      "container_image": "HIDDEN",
      "container_image_id": "HIDDEN",
      "pod_id": "ffc6a681-390b-11ea-bcac-42010a8000be",
      "labels": {
        "app": "cms",
        "pod-template-hash": "68c4b49657",
        "version": "1.0.0"
      },
      "host": "HIDDEN",
      "master_url": "https://10.0.0.1:443/api",
      "namespace_id": "1ede7315-14fa-11ea-95c1-42010a80010f"
    },
    "@timestamp": "2020-01-17T10:19:21.776876369+00:00",
    "tag": "kubernetes.var.log.containers.cms-68c4b49657-b88hs_default_cms-fc5b0d5b0aa4008961b18dfe93c4e04b2cfbde0f7ff072dc702c55823baba3a4.log"
  },
  "fields": {
    "@timestamp": [
      "2020-01-17T10:19:21.776Z"
    ]
  },
  "highlight": {
    "kubernetes.labels.app": [
      "@kibana-highlighted-field@cms@/kibana-highlighted-field@"
    ]
  },
  "sort": [
    1579256361776
  ]
}

映射显示为:

log: string
log.keyword: string

没有识别出任何自定义 json 映射。

是否有自定义此“日志”字段的方法,如果可以,我需要在哪里进行更改?我对流利和弹性很陌生,所以任何帮助都将不胜感激!

我在 kubernetes 上使用 fluent/fluentd-kubernetes-daemonset。

【问题讨论】:

    标签: json elasticsearch logging kubernetes fluentd


    【解决方案1】:

    为了解决这个问题,我在 docker 本地提取并运行了 fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1 映像。必须确保我在初始运行时将 FLUENT_ELASTICSEARCH_USER 和 FLUENT_ELASTICSEARCH_PASSWORD 指定为环境变量,因为 entrypoint.sh 尝试替换容器 fluent.conf 文件中的信息。如果您不指定密码,它会清除文件中的信息。

    然后就是执行到正在运行的容器中,并将以下信息添加到fluent.conf中:

    filter **>
      @type record_transformer
      <record>
        log_json ${record["log"]}
      </record>
    </filter>
    
    
    <filter **>
      @type parser
      @log_level debug
      key_name log_json
      reserve_data true
      remove_key_name_field true
      emit_invalid_record_to_error false
      <parse>
        @type json
      </parse>
    </filter>
    

    在此之后,我退出并停止了容器,将容器提交到我自己在 Docker Hub 上的存储库中的一个全新镜像,并在我们用于部署到 k8s 的 DaeomnSet yaml 文件中引用了新镜像。

    这可能不是最巧妙或最有效的方法,但在没有任何关于如何自定义 fluentd.conf 的文档的情况下,这暂时起到了作用。

    【讨论】:

    • 这很有魅力,非常感谢。注意:您不必使用额外的log_json 字段。我只使用了第二个过滤器并将key_name 更改为直接指向log 字段。如果删除它,唯一的区别是原始日志在转换后会丢失。但是,对于调试这个完整的配置是完美的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2017-10-21
    • 1970-01-01
    • 2019-04-16
    • 2021-11-23
    • 1970-01-01
    • 2021-09-27
    相关资源
    最近更新 更多