我正在开发一个应用程序,其日志包含用于度量目的的自定义字段。因此,我们以JSON格式生成日志,并将其发送到Elasticsearch集群。我们目前正在将应用程序从本地Docker节点迁移到我们组织的Kubernetes集群。我们的集群使用Fluentd作为DaemonSet,将所有pod的日志输出到我们的Elasticsearch集群。设置与此类似:https://medium.com/kubernetes-tutorials/cluster-level-logging-in-kubernetes-with-fluentd-e59aa2b6093a
我正试图找出从我们的应用程序发送日志的最佳做法。我的两个要求是:
- 日志以JSON格式正确格式化。我不希望它们嵌套在持久化文档的
msg
字段中 - 我可以运行
kubectl logs -f <pod>
并以可读的文本格式查看日志
目前,如果我什么都不做,让DaemonSet发送日志,它将无法满足这两个要求。
我想到的最好的解决方案是让Kubernetes集群的管理员用Fluentbit替换Fluentd日志记录。然后我可以这样配置我的部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-app
labels:
app: example-app
annotations:
fluentbit.io/parser-example-app: json
fluentbit.io/exclude-send-logs: "true"
spec:
selector:
matchLabels:
app: example-app
template:
metadata:
labels:
app: example-app
spec:
containers:
- name: example-app
image: myapp:1.0.0
volumeMounts:
- name: app-logs
mountPath: "/var/log/app"
- name: tail-logs
image: busybox
args: [/bin/sh, -c, 'tail -f /var/log/example-app.log']
volumeMounts:
- name: app-logs
mountPath: "/var/log/app"
volumes:
- name: app-logs
emptyDir: {}
然后,日志以正确的JSON格式发送到Elasticsearch,我可以运行kubectl logs -f example-app -c tail-logs
以可读的格式查看它们。
这是最好的做法吗?我是不是错过了一个更简单的解决方案?Fluentd是否支持替代方案?
我很乐意提供您的意见:(
这里没有一个真正好的选项不会消耗大量的CPU。除了你上面提到的解决方案之外,我能建议的最接近的事情是在主输出流未格式化的情况下反转它,并且你运行Fluent*(通常是Bit(是辅助文件流上的一个sidecar。不过也没什么好的。
实际上,我们中的大多数人只是以JSON格式输出,在极少数情况下,我们需要手动戳普通UI之外的日志(Kibana、Grafana等(,我们只是处理这些烦恼。
理论上,你也可以让你的";"人";格式足够机器可解析以允许查询。通常的选择是";logfmt";,又称CCD_ 4对。所以我在logfmt-y服务上的日志行看起来像timestamp=2021-05-15T03:48:05.171973Z level=info event="some message" otherkey=1 foo="bar baz"
。这很简单,可以手工阅读,但也可以有效地进行解析。