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=apache
和logFormat=google
标记这些应用 pod。 -
您可以在
ClusterLogForwarder
CR YAML 文件中使用以下代码片段。
outputDefaults: elasticsearch: structuredTypeKey: kubernetes.labels.logFormat 1 structuredTypeName: nologformat pipelines: - inputRefs: <application> outputRefs: default parse: json 2
在这种情况下,以下结构化日志记录进入 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
在这种情况下,以下结构化日志记录进入 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 存储前执行此配置。
为避免与索引数量过多相关的性能问题,请考虑通过标准化到常见模式来保持可能的模式数量较低。
流程
将以下代码片段添加到
ClusterLogForwarder
CR YAML 文件中。outputDefaults: elasticsearch: structuredTypeKey: <log record field> structuredTypeName: <name> pipelines: - inputRefs: - application outputRefs: default parse: json
-
使用
structuredTypeKey
字段指定其中一个日志记录字段。 使用
structuredTypeName
字段指定名称。重要要解析 JSON 日志,您必须同时设置
structuredTypeKey
和structuredTypeName
字段。-
对于
inputRefs
,指定要使用该管道转发哪些日志类型,如application
、infrastructure
或audit
。 -
将
parse: json
元素添加到管道。 创建 CR 对象。
$ oc create -f <filename>.yaml
Red Hat OpenShift Logging Operator 会重新部署收集器 Pod。但是,如果没有重新部署,请删除收集器 Pod 以强制重新部署。
$ oc delete pod --selector logging-infra=collector
其他资源