11.3. 启用 JSON 日志转发


您可以配置 Log Forwarding API,将 JSON 字符串解析为结构化对象。

11.3.1. 解析 JSON 日志

包含 JSON 日志的日志通常以 message 字段中的字符串表示。这使得用户难以查询 JSON 文档中的特定字段。OpenShift Logging 的 Log Forwarding API 可让您将 JSON 日志解析到结构化对象,并将其转发到 OpenShift Logging 管理的 Elasticsearch 或 Log Forwarding API 支持的任何其他第三方系统。

为了说明其工作原理,假定您有以下结构化 JSON 日志条目:

结构化 JSON 日志条目示例

{"level":"info","name":"fred","home":"bedrock"}

通常,ClusterLogForwarder 自定义资源 (CR) 会在 message 字段中转发该日志条目。message 字段包含与 JSON 日志条目等效的 JSON-quoted 字符串,如下例中所示:

message 字段示例

{"message":"{\"level\":\"info\",\"name\":\"fred\",\"home\":\"bedrock\"",
 "more fields..."}

要启用解析 JSON 日志,您需要将 parse: json 添加到 ClusterLogForwarder CR 的管道中,如下例所示。

显示 parse: json 的片段示例

pipelines:
- inputRefs: [ application ]
  outputRefs: myFluentd
  parse: json

当使用 parse: json 来启用 JSON 日志解析时,CR 会复制 structured 项中的 JSON 结构化日志条目,如下例所示。这不会修改原始的 message 字段。

包含结构化 JSON 日志条目的 structured 输出示例

{"structured": { "level": "info", "name": "fred", "home": "bedrock" },
 "more fields..."}

重要

如果日志条目不包含有效的结构化 JSON,则将缺少 structured 字段。

11.3.2. 为 Elasticsearch 配置 JSON 日志数据

如果您的 JSON 日志遵循多个模式,在单个索引中存储它们可能会导致类型冲突和卡性问题。要避免这种情况,您必须配置 ClusterLogForwarder 自定义资源 (CR),将每个 schema 分组到单个输出定义中。这样,每个架构被转发到单独的索引。

重要

如果您将 JSON 日志转发到 OpenShift Logging 管理的默认 Elasticsearch 实例,它会根据您的配置生成新的索引。为避免与索引数量过多相关的性能问题,请考虑通过标准化到常见模式来保持可能的模式数量较低。

结构类型

您可以使用 ClusterLogForwarder CR 中的以下结构类型来为 Elasticsearch 日志存储构建索引名称:

  • structuredTypeKey 是 message 字段的名称。该字段的值用于构造索引名称。

    • kubernetes.labels.<key> 是 Kubernetes pod 标签,其值用于构造索引名称。
    • openshift.labels.<key>ClusterLogForwarder CR 中的 pipeline.label.<key> 元素,其值用于构造索引名称。
    • kubernetes.container_name 使用容器名称来构造索引名称。
  • structuredTypeName: 如果没有设置 structuredTypeKey 字段,或者其键不存在,则 structuredTypeName 值将用作结构化类型。当您将 structuredTypeKey 字段和 structuredTypeName 字段一起使用时,如果 JSON 日志数据中缺少 structuredTypeKey 字段中的密钥,则 structuredTypeName 值将提供一个回退索引名称。
注意

虽然您可以将 structuredTypeKey 的值设置为 "Log Record Fields" 主题中显示的任何字段,但最有用的字段将显示在前面的结构类型列表中。

structuredTypeKey: kubernetes.labels.<key> 示例

假设如下:

  • 集群正在运行以两种不同格式生成 JSON 日志的应用 pod,即 "apache" 和 "google"。
  • 用户使用 logFormat=apachelogFormat=google 标记这些应用 pod。
  • 您可以在 ClusterLogForwarder CR YAML 文件中使用以下代码片段。
outputDefaults:
 elasticsearch:
    structuredTypeKey: kubernetes.labels.logFormat 1
    structuredTypeName: nologformat
pipelines:
- inputRefs: <application>
  outputRefs: default
  parse: json 2
1
使用 Kubernetes logFormat 标签形成的键值对值。
2
启用解析 JSON 日志。

在这种情况下,以下结构化日志记录进入 app-apache-write 索引:

{
  "structured":{"name":"fred","home":"bedrock"},
  "kubernetes":{"labels":{"logFormat": "apache", ...}}
}

以下结构化日志记录进入 app-google-write 索引中:

{
  "structured":{"name":"wilma","home":"bedrock"},
  "kubernetes":{"labels":{"logFormat": "google", ...}}
}

structuredTypeKey: openshift.labels.<key> 示例

假设您在 ClusterLogForwarder CR YAML 文件中使用了以下代码片段:

outputDefaults:
 elasticsearch:
    structuredTypeKey: openshift.labels.myLabel 1
    structuredTypeName: nologformat
pipelines:
 - name: application-logs
   inputRefs:
   - application
   - audit
   outputRefs:
   - elasticsearch-secure
   - default
   parse: json
   labels:
     myLabel: myValue 2
1
使用由 OpenShift myLabel 标签组成的键值对的值。
2
myLabel 元素将字符串值 myValue 提供给结构化日志消息。

在这种情况下,以下结构化日志记录进入 app-myValue-write 索引中:

{
  "structured":{"name":"fred","home":"bedrock"},
  "openshift":{"labels":{"myLabel": "myValue", ...}}
}

其他注意事项

  • 结构化记录的 Elasticsearch 索引通过将"app-"添加到结构化类型并附加 "-write" 来形成。
  • 非结构化记录不会发送到结构化索引。在应用、基础架构或审计索引中,它们按照常态进行索引。
  • 如果没有非空的结构化类型,则转发一个没有 structured 项的 unstructured 记录。

不要过载有太多索引的 Elasticsearch。仅对不同的日志格式使用不同的结构化类型,而不用为每个应用程序或命名空间都使用不同的结构化类型。例如,大多数 Apache 应用使用相同的 JSON 日志格式和结构化类型,如 LogApache

11.3.3. 将 JSON 日志转发到 Elasticsearch 日志存储

对于 Elasticsearch 日志存储,如果您的 JSON 日志条目遵循不同的模式,请将 ClusterLogForwarder 自定义资源 (CR) 配置为将每个 JSON 模式分组到单个输出定义中。这样,Elasticsearch 会为每个 schema 使用一个单独的索引。

重要

因为将不同的模式转发到同一索引可能会导致类型冲突和卡化问题,所以您必须在将数据转发到 Elasticsearch 存储前执行此配置。

为避免与索引数量过多相关的性能问题,请考虑通过标准化到常见模式来保持可能的模式数量较低。

流程

  1. 将以下代码片段添加到 ClusterLogForwarder CR YAML 文件中。

    outputDefaults:
     elasticsearch:
        structuredTypeKey: <log record field>
        structuredTypeName: <name>
    pipelines:
    - inputRefs:
      - application
      outputRefs: default
      parse: json
  2. 使用 structuredTypeKey 字段指定其中一个日志记录字段。
  3. 使用 structuredTypeName 字段指定名称。

    重要

    要解析 JSON 日志,您必须同时设置 structuredTypeKeystructuredTypeName 字段。

  4. 对于 inputRefs,指定要使用该管道转发哪些日志类型,如 applicationinfrastructureaudit
  5. parse: json 元素添加到管道。
  6. 创建 CR 对象。

    $ oc create -f <filename>.yaml

    Red Hat OpenShift Logging Operator 会重新部署收集器 Pod。但是,如果没有重新部署,请删除收集器 Pod 以强制重新部署。

    $ oc delete pod --selector logging-infra=collector

其他资源

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.