文章目录
- 1. deploy 文件
- 1.1 RBAC
- 1.2. DaemonSet
- 1.2.1. Elasticsearch 连接信息
- 1.2.2. Volume
- 1.3. ConfigMap
- 1.3.1. 日志路径
- 1.3.2. 日志事件输出目标
- 2. 在控制平面节点上运行Filebeat
- 3. 查看输出
- 3.1. 关于处理器 processors
- 4. 日志收集配置
- 4.1. 手动指定日志收集路径
- 4.2. 自动发现
- 5. processors 处理器
- 5.1. 定义处理器
- 5.2. 常用处理器
- 5.2.1. 去除日志中的某些行
- 5.2.2. 向输出的数据中添加某些自定义字段
- 5.2.3. 从事件中删除某些字段
- 5.2.4. add_kubernetes_metadata 详解
- 5.3. Condition 条件
- 6. Indexers and matchers (索引器和匹配器)
- 6.1. Indexers 索引器
- 6.2. Matchers
- 7. 自定义索引
- 8. 配置索引生命周期管理
- 8.1. 配置选项
- 9. 配置Elasticsearch索引模板加载
- 9. parsers 解析器
- 10. 勘探者 prospector
- scanner 扫描器
- 10.1. symlinks 软链接
- 10.2. fingerprint 指纹
- 11. file_identity 文件标识
- 11.1. fingerprint
1. deploy 文件
curl -L -O https://raw.githubusercontent.com/elastic/beats/8.14/deploy/kubernetes/filebeat-kubernetes.yaml
整个部署文件可以被分为三部分:
- rbac 权限
- daemonset 守护程序
- configmap 配置文件
默认部署在 kube-system 名称空间。
1.1 RBAC
filebeat-rbac.yml
apiVersion: v1
kind: ServiceAccount
metadata:
name: filebeat
namespace: kube-system
labels:
k8s-app: filebeat
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: filebeat
labels:
k8s-app: filebeat
rules:
- apiGroups: [""] # "" indicates the core API group
resources:
- namespaces
- pods
- nodes
verbs:
- get
- watch
- list
- apiGroups: ["apps"]
resources:
- replicasets
verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
resources:
- jobs
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: filebeat
# should be the namespace where filebeat is running
namespace: kube-system
labels:
k8s-app: filebeat
rules:
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs: ["get", "create", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: filebeat-kubeadm-config
namespace: kube-system
labels:
k8s-app: filebeat
rules:
- apiGroups: [""]
resources:
- configmaps
resourceNames:
- kubeadm-config
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: filebeat
subjects:
- kind: ServiceAccount
name: filebeat
namespace: kube-system
roleRef:
kind: ClusterRole
name: filebeat
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: filebeat
namespace: kube-system
subjects:
- kind: ServiceAccount
name: filebeat
namespace: kube-system
roleRef:
kind: Role
name: filebeat
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: filebeat-kubeadm-config
namespace: kube-system
subjects:
- kind: ServiceAccount
name: filebeat
namespace: kube-system
roleRef:
kind: Role
name: filebeat-kubeadm-config
apiGroup: rbac.authorization.k8s.io
---
1.2. DaemonSet
Filebeat 会以 daemonset 方式运行在每个Kubernetes 集群的工作节点。
filebeat-ds.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: kube-system
labels:
k8s-app: filebeat
spec:
selector:
matchLabels:
k8s-app: filebeat
template:
metadata:
labels:
k8s-app: filebeat
spec:
serviceAccountName: filebeat
terminationGracePeriodSeconds: 30
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
containers:
- name: filebeat
image: docker.elastic.co/beats/filebeat:8.14.1
args: [
"-c", "/etc/filebeat.yml",
"-e",
]
env:
- name: ELASTICSEARCH_HOST
value: elasticsearch
- name: ELASTICSEARCH_PORT
value: "9200"
- name: ELASTICSEARCH_USERNAME
value: elastic
- name: ELASTICSEARCH_PASSWORD
value: changeme
- name: ELASTIC_CLOUD_ID
value:
- name: ELASTIC_CLOUD_AUTH
value:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
securityContext:
runAsUser: 0
# If using Red Hat OpenShift uncomment this:
#privileged: true
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: config
mountPath: /etc/filebeat.yml
readOnly: true
subPath: filebeat.yml
- name: data
mountPath: /usr/share/filebeat/data
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
- name: varlog
mountPath: /var/log
readOnly: true
volumes:
- name: config
configMap:
defaultMode: 0640
name: filebeat-config
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- name: varlog
hostPath:
path: /var/log
# data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart
- name: data
hostPath:
# When filebeat runs as non-root user, this directory needs to be writable by group (g+w).
path: /var/lib/filebeat-data
type: DirectoryOrCreate
1.2.1. Elasticsearch 连接信息
默认情况下,Filebeat 会将事件发送到现有的 Elasticsearch(如果存在)。要指定不同的目标,请更改清单文件中的以下参数:
- name: ELASTICSEARCH_HOST
value: elasticsearch
- name: ELASTICSEARCH_PORT
value: "9200"
- name: ELASTICSEARCH_USERNAME
value: elastic
- name: ELASTICSEARCH_PASSWORD
value: changeme
技巧:
ELASTICSEARCH_HOST
可以指定为一个 Kubernetes 中的一个 service ,比如: elastic.efk.svc。
这样情况下, Elasticsearch 可以部署在 Kubernetes 集群内部,也可以部署在 Kubernetes 集群外部,如果是部署在外部,可以使用如下内容创建一个 service,来把外部的服务引入到 Kubernetes 集群内部,如下所示。
elastic-svc-ex.yml
apiVersion: v1
kind: Service
metadata:
name: elastic
namespace: efk
spec:
clusterIP: None
ports:
- name: http
protocol: TCP
port: 9200
targetPort: 9200
---
apiVersion: v1
kind: Endpoints
metadata:
name: elastic
namespace: efk
subsets:
- addresses:
- ip: 10.61.8.6 # 外部 elasticsearch 节点 IP
- ip: 10.61.8.7
- ip: 10.61.8.8
ports:
- name: http
port: 9200
protocol: TCP
1.2.2. Volume
数据卷需要映射 配置文件、Filebeat 自己的数据路径、日志收集路径
配置文件
配置文件,就是 Filebeat 程序自身使用的配置文件,这个是使用 configmap 映射到 Filebeat 的 Pod 中的。
volumes:
- name: config
configMap:
defaultMode: 0640
name: filebeat-config
日志收集路径
日志收集就是需要让 Filebeat 收集的日志所在的路径,这个路径需要映射到 Filebeat Pod 中,这个可以是多个,官方清单文件中默认就有 docker 容器的日志 varlibdockercontainers 和服务器的系统日志 varlog,如下所示:
volumes:
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- name: varlog
hostPath:
path: /var/log
数据路径
就是 Filebeat 程序自己存放数据的目录,主要存放日志注册到 Filebeat 程序的信息,作用是记录 Filebeat 程序读取到的都有哪些日志,还有这些日志都被读取到了哪个位置。
如果在做实验的时候,需要重新读取每个日志的内容,需要清空此数据目录下的数据。
volumes:
# data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart
# data文件夹存储所有文件的读取状态注册表,因此我们不会在Filebeat pod重新启动时再次发送所有内容
- name: data
hostPath:
# When filebeat runs as non-root user, this directory needs to be writable by group (g+w).
path: /var/lib/filebeat-data
type: DirectoryOrCreate
1.3. ConfigMap
filebeat-cm.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-config
namespace: kube-system
labels:
k8s-app: filebeat
data:
filebeat.yml: |-
filebeat.inputs:
- type: filestream
id: kubernetes-container-logs
paths:
- /var/log/containers/*.log
parsers:
- container: ~
prospector:
scanner:
fingerprint.enabled: true
symlinks: true
file_identity.fingerprint: ~
processors:
- add_kubernetes_metadata:
host: ${NODE_NAME}
matchers:
- logs_path:
logs_path: "/var/log/containers/"
# To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this:
# filebeat.autodiscover:
# providers:
# - type: kubernetes
# node: ${NODE_NAME}
# hints.enabled: true
# hints.default_config:
# type: filestream
# id: kubernetes-container-logs-${data.kubernetes.pod.name}-${data.kubernetes.container.id}
# paths:
# - /var/log/containers/*-${data.kubernetes.container.id}.log
# parsers:
# - container: ~
# prospector:
# scanner:
# fingerprint.enabled: true
# symlinks: true
# file_identity.fingerprint: ~
processors:
- add_cloud_metadata:
- add_host_metadata:
cloud.id: ${ELASTIC_CLOUD_ID}
cloud.auth: ${ELASTIC_CLOUD_AUTH}
output.elasticsearch:
hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
username: ${ELASTICSEARCH_USERNAME}
password: ${ELASTICSEARCH_PASSWORD}
---
这部分主要需要修改的主要有两处:
1.3.1. 日志路径
因为这里配置的日志收集路径和 daemonset 中的日志收集路径不一致。
daemonset 中日志路径 /var/lib/docker/containers
被挂载 Pod 中的 /var/lib/docker/containers
,如下所示:
apiVersion: apps/v1
kind: DaemonSet
spec:
template:
spec:
containers:
volumeMounts:
...
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
而这里 configmap 中配置的日志收集路径是 /var/log/containers/*.log
,如下所示:
data:
filebeat.yml: |-
filebeat.inputs:
- type: filestream
id: kubernetes-container-logs
paths:
- /var/log/containers/*.log
因此应该修改为和挂载的路径一致,也就是修改为如下内容:
data:
filebeat.yml: |-
filebeat.inputs:
- type: filestream
id: kubernetes-container-logs
paths:
- /var/lib/docker/containers/*/*.log
1.3.2. 日志事件输出目标
Filebeat 读取到日志文件中的每一行日志被 Filebeat 称为一个事件(event)。
官方默认清单文件中 configmap 配置的日志事件输出目标是 elasticsearch, 为了便于调试可以把输出目标设置为 标准输出(stdout)。这样就可以查看 Filebeat 日志的方式(kubectl logs pod-name)查看 Filebeat 处理日志的事件内容了,通过查看事件内容可以明确的查看事件内容中都有哪些字段,以便可以在配置文件中进一步使用这些字段进行更灵活的配置,比如自定义索引。
注释或者删除 configmap 中如下内容:
data:
filebeat.yml: |-
...
output.elasticsearch:
hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
username: ${ELASTICSEARCH_USERNAME}
password: ${ELASTICSEARCH_PASSWORD}
在 configmap 中添加如下内容:
...
data:
filebeat.yml: |-
filebeat.inputs:
...
output.console:
pretty: true
注意: 同一时间,Filebeat 运行时,日志事件输出目标只能设置一个。
2. 在控制平面节点上运行Filebeat
Kubernetes控制平面节点可以使用污点来限制可以在其上运行的工作负载。要在控制平面节点上运行Filebeat,您可能需要更新Daemoset规范以包括适当的容忍度:
spec:
tolerations:
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
要部署 Filebeat 到 Kubernetes 中,执行如下命令
kubectl apply -f filebeat-rbac.yaml
kubectl apply -f filebeat-cm.yaml
kubectl apply -f filebeat-ds.yaml
默认 Filebeat 以 DaemonSet 方式部署在 kube-system 名称空间
kubectl -n kube-system get ds/filebeat
3. 查看输出
当配置输出目标为标准输出时,被处理过的日志事件内容会输出到 Filebeat Pod 的运行日志里,可以使用如下命令查看。
kubectl -n kube-system logs -f pod-name
这时,运行在 pod-name 所在的服务器上的容器日志都会被 pod-name 这个 Filebeat 处理,也就是在Kubernetes工作节点的 /var/lib/docker/containers//.log 日志文件。
输出的内容类似下面的内容:
{
"@timestamp": "2024-04-10T06:26:36.900Z",
"@metadata": {
"beat": "filebeat",
"type": "_doc",
"version": "8.4.1"
},
"stream": "stdout",
"message": "10.244.1.0 - - [10/Apr/2024:06:26:36 +0000] \"GET /js/bignumber.js/bignumber.js.aae73227.js HTTP/1.0\" 0.000 200 89631 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36\" \"100.125.64.73\"\"/js/bignumber.js/bignumber.js.aae73227.js\" \"-\"\n",
"input": {
"type": "filestream"
},
"ecs": {
"version": "8.0.0"
},
"host": {
"hostname": "k8s-node2",
"architecture": "aarch64",
"os": {
"version": "20.04.4 LTS (Focal Fossa)",
"family": "debian",
"name": "Ubuntu",
"kernel": "4.19.90-17.5.ky10.aarch64",
"codename": "focal",
"type": "linux",
"platform": "ubuntu"
},
"containerized": true,
"ip": [... // 服务器上所有的IP
],
"name": "k8s-node2",
"mac": [... // 服务器上所有的 Mac
]
},
"agent": {
"type": "filebeat",
"version": "8.4.1",
"ephemeral_id": "c31de016-1c62-4520-8615-b9ceb40db6e2",
"id": "565c2d65-9b9e-4a57-8093-d1afa7026c8d",
"name": "k8s-node2"
},
"cloud": {
"instance": {
"id": "f7c55cbe-0baf-432b-8147-96d724036796"
},
"region": "",
"availability_zone": "cn-cq1a",
"service": {
"name": "ECS"
},
"provider": "huawei"
},
"log": {
"offset": 556597,
"file": {
"path": "/var/lib/docker/containers/a3760f9e51d54e63e8cc24dc05d436e7b34b9c16762c310c42b36faa4f58a7f8/a3760f9e51d54e63e8cc24dc05d436e7b34b9c16762c310c42b36faa4f58a7f8-json.log"
}
}
}
现将内容进行优化修改,保留主要字段,并对主要字段进行说明。
{
"@timestamp": "2024-04-10T06:26:36.900Z",
"@metadata": {...
},
"stream": "stdout", // 表示这行日志内容是正常未报错的日志
"message": "日志中的一行日志内容",
"input": {
"type": "filestream"
},
"ecs": {
"version": "8.0.0"
},
"host": {... // 这个服务器的主机方面的信息,比如主机名,所有的IP,所有的 Mac 地址等
},
"agent": {... // 这个代理信息,就是 Filebeat 的版本,名称登录
},
"cloud": { ... // 加入 Filebeat 所在的服务器是某个云上(华为云、阿里云等)运行的,就会有这个云的相关信息
},
}
3.1. 关于处理器 processors
日志事件可以被配置的处理器进行处理,不同的处理器有不同的行为,会影响日志事件的内容输出。
这些处理器,如果不需要可以不配置,不配置的话,相应会失去这个处理器带来的功能。
官方默认的清单文件中配置了如下处理器:
- add_cloud_metadata
- add_host_metadata
- add_kubernetes_metadata
add_cloud_metadata
会向日志事件中添加如下字段:
"cloud": {
"instance": {
"id": "f7c55cbe-0baf-432b-8147-96d724036796"
},
"region": "",
"availability_zone": "cn-cq1a",
"service": {
"name": "ECS"
},
"provider": "huawei"
},
add_host_metadata
会向日志事件中添加如下字段:
"host": {
"hostname": "k8s-node2", // 服务器的主机名
"architecture": "aarch64", // 服务器的CPU架构
"os": { // 操作系统相关信息
"version": "20.04.4 LTS (Focal Fossa)",
"family": "debian",
"name": "Ubuntu",
"kernel": "4.19.90-17.5.ky10.aarch64",
"codename": "focal",
"type": "linux",
"platform": "ubuntu"
},
"containerized": true,
"ip": [... // 服务器上所有的IP
],
"name": "k8s-node2",
"mac": [... // 服务器上所有的 Mac
]
},
add_kubernetes_metadata
会向日志事件中添加如下字段:
"kubernetes": {
"node": { //节点的信息
"hostname": "k8s-node1",
"name": "k8s-node1",
"uid": "e05fe0cf-2042-4d02-bedc-789ad567aea6",
"labels": {... // 这个节点所有的标签
}
},
"namespace_uid": "6b98dd5a-66ce-4dda-a7e2-6f7a51bf40cf",
"namespace_labels": {...
},
"pod": {
"name": "polaris-0",
"uid": "b88b918e-6904-4e7d-8f3f-43de56bb4548",
"ip": "10.244.3.55"
},
"namespace": "spms-bluespace",
"statefulset": { // 这个这条日志产出者(这个 Pod)是从哪个资源创建的,这里是 statefulset。
// 如果是 deployment 会是 "deployment": { "name": "deployment 的名称" },
"name": "polaris"
},
"labels": {... // 这个这条日志产出者(这个 Pod) 的标签
},
"container": { // 这个这条日志产出者(这个 Pod)的容器的名称
"name": "polaris-server"
}
},
细心的朋友,可以发现上面的示例数据中并没有 Kubernetes 相关的字段,这个原因稍后在接下来的【处理器 add_kubernetes_metadata 详解】部分进行详细介绍。
4. 日志收集配置
这里的高级配置主要针对 configmap 中的 filebeat.yml 文件中配置内容。
日志收集方式有多重,这里对于 docker 容器中的日志收集,主要介绍两种:
- 手动指定日志收集路径
- 自动发现
4.1. 手动指定日志收集路径
这里主要介绍的是 Filebeat 配置文件中 filebeat.inputs
的配置。
filebeat.inputs
配置项的作用就是告诉 Filebeat 程序可以从哪儿获取需要读取的数据。支持多种输入模块,比如普通文件中、redis 中、kafka 中等。
配置示例:
filebeat.inputs:
- type: log
paths:
- /var/log/system.log
- /var/log/wifi.log
# 支持通配符
- /log/spms-*[a-z].log
# 可以写多个
- type: filestream
paths:
- "/var/log/apache2/*"
log
log 输入模块适用于普通文本日志文件、syslog 格式的日志。filestream
filestream 输入模块是 Filebeat 7.13.0 版本中引入的新输入模块,用于从文件中读取结构化数据。filestream 输入模块支持读取 JSON 格式、NDJSON 格式等结构化数据文件,它可以更高效地处理结构化数据文件,并提供更好的性能。
不同的输入模块支持不同的配置项,在 filestream 下可以配置如下选项(这些配置项同时支持 log 输入模块)。
- type: filestream
# id 是集群中的唯一标识
id: kubernetes-container-logs
paths:
# 日志收集的路径
- /var/lib/docker/containers/*/*.log
parsers:
# 解析器
- container: ~
prospector:
# 勘探者
scanner:
symlinks: true
processors:
# 处理器名称
- add_kubernetes_metadata:
parsers 解析器,主要对输入的数据进行解析,不同的数据有不同的格式,比如docker容器的日志格式一般是 json, 就需要使用 container 解析器进行解析处理。
prospector 勘探者,主要是控制 Filebeat 对日志文件进行读取的时候如何处理,比如扫描文件的时候是否支持软连接的文件路径,是否对日志文件进行计算密文,以便更好的识别是否是同一个文件。
processors 处理器,主要会把每次日志事件内容进行处理,比如添加某些字段,删除某些字段,删除这个事件等。
parsers 和 prospector 后面内容有详细介绍。也可以参考官方文档
还有几个值得注意的配置项:
harvester_buffer_size 每个采集器在获取文件时使用的缓冲区的大小(以字节为单位)。默认值为16384。
max_bytes 单个日志消息可以具有的最大字节数。max_bytes之后的所有字节都将被丢弃而不发送。此设置对于多行日志消息特别有用,因为多行日志信息可能会变大。默认值为10MB(10485760)。
close_inactive指定在文件不再更新的情况下多久后关闭文件句柄。我们建议您将close_inactive设置为一个大于日志文件最不频繁更新的值。例如,如果日志文件每隔几秒钟更新一次,则可以安全地将close_inactive设置为1m。如果存在更新率非常不同的日志文件,则可以使用具有不同值的多个配置。
4.2. 自动发现
从运行在Kubernetes上的工作负载收集日志时,这些应用程序以json格式进行日志记录是很常见的情况。在这种情况下,可以应用特殊处理,以便正确解析这些json日志并将其解码为字段。Bellow提供了两种不同的方式来配置filebeat的自动发现,以便识别和解析json日志。我们将使用一个带有两个容器的Pod的示例,其中只有一个日志是json格式的。
示例日志:
{"type":"log","@timestamp":"2020-11-16T14:30:13+00:00","tags":["warning","plugins","licensing"],"pid":7,"message":"License information could not be obtained from Elasticsearch due to Error: No Living connections error"}
- 将
json.*
选项与模板一起使用
filebeat.autodiscover:
providers:
- type: kubernetes
node: ${NODE_NAME}
templates:
- condition: # 条件
contains: # 包含
kubernetes.container.name: "no-json-logging"
config:
- type: container
paths:
- "/var/log/containers/*-${data.kubernetes.container.id}.log"
- condition:
contains:
kubernetes.container.name: "json-logging"
config:
- type: container
paths:
- "/var/log/containers/*-${data.kubernetes.container.id}.log"
json.keys_under_root: true
json.add_error_key: true
json.message_key: message
- 使用带有
hints
的json.*
选项
这里的关键部分是正确地注释Pod,以仅将正确容器的日志解析为json日志。在这种情况下,注释(annotation )应该这样构造:
co.elastic.logs.<container_name>/json.keys_under_root: "true"
Autodiscovery configuration:
filebeat.autodiscover:
providers:
- type: kubernetes
node: ${NODE_NAME}
hints.enabled: true
hints.default_config:
type: container
paths:
- /var/log/containers/*${data.kubernetes.container.id}.log
然后对 Pod 进行注释
annotations:
co.elastic.logs.json-logging/json.keys_under_root: "true"
co.elastic.logs.json-logging/json.add_error_key: "true"
co.elastic.logs.json-logging/json.message_key: "message"
5. processors 处理器
5.1. 定义处理器
在将数据发送到配置的输出之前,可以使用处理器对数据进行过滤和增强。要定义处理器,请指定处理器名称、可选条件和一组参数:
processors:
- <processor_name>:
when:
<condition>
<parameters>
- <processor_name>:
when:
<condition>
<parameters>
...
-
<processor_name>指定执行某种操作的处理器,例如选择要删除的字段或向事件添加元数据。
-
<condition>指定一个可选条件。如果条件存在,则仅当条件满足时此处理器才执行操作。如果未设置任何条件,则此处理器始终执行操作。
-
<parameters>是要传递给处理器的参数列表,比如指定要添加哪些字段,添加到哪个字段内。
处理更复杂的情况
更复杂的条件处理可以通过使用if-then-else处理器配置来完成。这允许基于单个条件执行多个处理器。
processors:
- if:
<condition>
then:
- <processor_name>:
<parameters>
- <processor_name>:
<parameters>
...
else:
- <processor_name>:
<parameters>
- <processor_name>:
<parameters>
...
-
then
必须包含单个处理器或一个或多个处理器的列表,以便在条件计算为true时执行。 -
else
是可选的。当条件求值为false时,它可以包含要执行的单个处理器或处理器列表。
处理器工作方式
每个处理器都接收一个事件,对该事件应用已定义的操作,然后返回该事件。如果定义处理器列表,则将按照在Filebeat配置文件中定义的顺序执行它们。
处理器在哪里配置有效
在配置的顶层。处理器应用于Filebeat收集的所有数据。
filebeat.autodiscover:
...
filebeat.inputs:
...
output.elasticsearch:
...
# 处理器,让数据更丰富
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
...
在特定输入下。处理器应用于为该输入收集的数据。
- type: <input_type>
processors:
- <processor_name>:
when:
<condition>
<parameters>
...
同样,对于Filebeat modules,您可以在模块定义的 input
部分定义处理器。
5.2. 常用处理器
- drop_event
- drop_fields
- add_docker_metadata
- add_host_metadata
- add_kubernetes_metadata
官方完整的处理器列表:点我查看目前支持的所以处理器列表
5.2.1. 去除日志中的某些行
配置位置在 filebeat.yml
文件中。
考虑这样的场景:
在一个服务器上,使用 docker 运行了应用的 Pod 的容器 ,也运行了 docker-compose 管理的 容器,并且 Pod 有的是应用程序(需要收集的日志),有的Pod是监控系统、日志收集系统等(不要求收集日志)。
从这么多的容器中要过滤出只要求收集的日志,就可以使用处理器 drop_event
,再配合 when
条件判断过滤。
删除所有以 DBG:
开头的行
processors:
- drop_event:
when.regexp:
message: "^DBG:"
5.2.2. 向输出的数据中添加某些自定义字段
fields 中的字段被添加到 target 所指定的字段内(此字段是顶级),如果没有 target, 将会被添加到顶级字段 fields
中。
processors:
- add_fields:
target: project
fields:
name: myproject
id: '574734885120952459'
- 将字段添加到此目标字段内。
- 将要添加的字段和值
输出效果如下图所示:
5.2.3. 从事件中删除某些字段
processors:
- drop_fields:
when:
condition
fields: ["field1", "field2", ...]
ignore_missing: false
condition
是一个条件,当条件满足时,才会删除定义的字段。这个是可选的,不设置条件,则会都删除。
以上配置,将删除字段: field1
和 field2
ignore_missing
的值为 false
表示,字段名不存在则会返回错误。为 true
不会返回错误。
⚠️ 注意: 事件中的 "@timestamp
和 type
字段是无法删除的。
下面的配置示例是删除顶级字段 input
和 顶级字段 ecs
中的 version
字段。
- drop_fields:
fields: ['input', "ecs.version"]
删除之前⬇️
{
...
"input": {
"type": "log"
},
...
"ecs": {
"version": "1.5.0"
},
...
}
删除之后⬇️
{
...
"ecs": {},
...
}
5.2.4. add_kubernetes_metadata 详解
add_kubernetes_metadata 处理器根据事件源自哪个kubernetes pod,用相关元数据对每个事件添加相关的字段信息。在启动时,它检测一个 in_cluster
环境并缓存与Kubernetes相关的元数据。只有在检测到有效配置时,才会对事件进行注释。如果无法检测到有效的Kubernetes配置,则不会使用与Kubernete相关的元数据对事件进行注释。
每个事件都注释有:
- Pod Name
- Pod UID
- Namespace
- Labels
也就是,对 Kubernetes 的每个日志事件,处理日志数据的时候,都会在处理后的日志数据中添加上面列出的信息。
此外,节点和命名空间元数据被添加到 pod 元数据中。
add_kubernetes_metadata处理器有两个基本构建块:
- Indexers
- Matchers
索引器(Indexers)使用pod元数据为每个pod创建唯一的标识符。这些标识符有助于将观察到的pod的元数据与实际事件相关联。例如,ip_port
索引器可以获取一个 Kubernetes pod,并根据其所有 pod_ip:container_port
的组合,为其创建标识符。
匹配器(Matchers)使用事件中的信息,来构造与索引器创建的标识符匹配的查找键。例如,当字段匹配器将["metricset.host"
]作为查找字段时,它将使用字段 metricset_host
的值构造查找关键字。当这些查找键中的一个与其中一个标识符匹配时,事件会丰富已标识的pod的元数据。
当 add_kubernetes_medata
与 Filebeat 一起使用时,它使用容器索引器和 logs_path
。因此,在 log.file.path
中路径包含对容器ID的引用的事件会被该容器的pod的元数据丰富。
可以通过禁用配置中的默认索引器和匹配器来禁用此行为:
processors:
- add_kubernetes_metadata:
default_indexers.enabled: false
default_matchers.enabled: false
当filebeat在Kubernetes中作为pod运行时,下面的配置将启用处理器。
processors:
- add_kubernetes_metadata:
#labels.dedot: true
#annotations.dedot: true
下面的配置允许 Filebeat 上的处理器作为在Kubernetes节点上运行一个进程(也就是支持运行在 Kubernetes 集群之外,但必须在 Kubernetes 节点上)。
processors:
- add_kubernetes_metadata:
host: <hostname>
# If kube_config is not set, KUBECONFIG environment variable will be checked
# and if not present it will fall back to InCluster
kube_config: $Filebeat Reference [8.14]/.kube/config
#labels.dedot: true
#annotations.dedot: true
下面的配置禁用了默认的索引器和匹配器,并启用了用户感兴趣的索引器。
processors:
- add_kubernetes_metadata:
host: <hostname>
# If kube_config is not set, KUBECONFIG environment variable will be checked
# and if not present it will fall back to InCluster
kube_config: ~/.kube/config
default_indexers.enabled: false
default_matchers.enabled: false
indexers:
- ip_port:
matchers:
- fields:
lookup_fields: ["metricset.host"]
#labels.dedot: true
#annotations.dedot: true
add_kubernetes_metadata
处理器具有以下配置设置:
host
(可选)指定要将filebeat定位到的节点,以防无法准确检测到,例如在主机网络模式下运行filebeat时。
scope
(可选)指定处理器应该在节点级别还是在整个集群级别具有可见性。可能的值为node和cluster。默认情况下,作用域为 node。
namespace
(可选)选择要从中收集元数据的命名空间。如果未设置,处理器将从所有命名空间收集元数据。默认情况下未设置。
add_resource_metadata
(可选)为将要添加到事件中的额外元数据,指定筛选器和配置,以便优化这些元数据,比如添加哪些,删除哪些。
配置参数:
node
ornamespace
: 为来自 node 和 namespace 的额外元数据指定标签和注释过滤器。默认情况下,包括所有标签,而不包括注释。要更改默认行为,可以定义include_labels
,exclude_labels
和include_annotations
。当存储需要特殊处理以避免存储输出过载的标签和注释时,这些设置非常有用。注意:这些设置不支持通配符。通过设置enabled: false
,可以单独禁用node
或namespace
元数据的丰富。deployment
: 如果资源是pod,并且是从 deployment 创建的,那么默认情况下会添加 deployment 名称,可以通过设置deployment: false
来禁用此功能。cronjob
: 如果资源是 Pod,并且是从 cronjob 创建的,那么默认情况下会添加 cronjob 名称,可以通过设置cronjob: false
来禁用此功能。
示例:
add_resource_metadata:
namespace:
include_labels: ["namespacelabel1"]
#labels.dedot: true
#annotations.dedot: true
node:
include_labels: ["nodelabel2"]
include_annotations: ["nodeannotation1"]
#labels.dedot: true
#annotations.dedot: true
deployment: false
cronjob: false
kube_config
(可选)使用给定的配置文件作为Kubernetes客户端的配置。它默认为 KUBECONFIG 环境变量的值(如果提供)。
kube_client_options
(可选)可以为Kubernetes客户端配置其他选项。目前支持客户端QPS和burst,如果不设置,将使用Kubernetes客户端的默认QPS和burst。示例:
kube_client_options:
qps: 5
burst: 10
cleanup_timeout
(Optional) Specify the time of inactivity before stopping the running configuration for a container. This is 60s by default.
(可选)指定停止容器的运行配置之前的非活动时间。默认情况下为60秒。
sync_period
(可选)指定列出历史资源的超时时间。
default_indexers.enabled
(可选)当您想要指定自己的pod索引器时,启用或禁用默认pod索引器。
default_matchers.enabled
(可选)当您想要指定自己的pod匹配器时,启用或禁用默认pod匹配器。
labels.dedot
(可选)默认为 true
。如果设置为 true
,那么 labels 中的 .
将替换为 _
。
annotations.dedot
(可选)默认为 true
。如果设置为 true
,那么 annotations 中的 .
将替换为 _
。
5.3. Condition 条件
每个条件都接收日志事件中的一个字段进行比较。通过在字段之间使用AND,可以在相同条件下指定多个字段(例如,field1 AND field2)。
对于每个字段,可以指定一个简单的字段名或字段的嵌套映射,例如host.name
。
不同的处理器导出不同的字段,每个处理器导出的字段可以参考官方文档
支持的条件:
- equals
- contains
- regexp
- range
- network
- has_fields
- or
- and
- not
equals 等于
使用等于条件,可以比较字段是否具有某个值。该条件只接受一个整数或字符串值。
例如,以下条件检查HTTP事务的响应代码是否为200:
equals:
http.response.code: 200
contains 包含
包含条件检查给定的值,是否是给定字段实际值的一部分。字段可以是字符串或字符串数组。该条件只接受字符串值。
例如,以下条件检查名称空间中是否含有 shark-test 对应值的一部分:
contains:
kubernetes.namespace: "shark-test"
regexp 正则表达式
正则表达式条件根据正则表达式检查字段。该条件只接受字符串。
例如,以下条件检查进程名称是否以foo开头:
regexp:
system.process.name: "^foo.*"
has_fields
has_fields 条件检查事件中是否存在所有给定字段。该条件接受表示字段名称的字符串值列表。
例如,以下条件检查事件中是否存在 http.response.code
字段。
has_fields: ['http.response.code']
or
接收一个条件列表,满足列表中任意一个条件即可。
or:
- <condition1>
- <condition2>
- <condition3>
...
配置示例:
or:
- equals:
http.response.code: 304
- equals:
http.response.code: 404
and
接收一个条件列表,必须同时满足列表中的所有条件。
and:
- <condition1>
- <condition2>
- <condition3>
...
配置示例:
and:
- equals:
http.response.code: 200
- equals:
status: OK
or 和 and 还可以嵌套使用:
or:
- <condition1>
- and:
- <condition2>
- <condition3>
not
not运算符接收到要求反的条件。
not:
<condition>
配置示例:
not:
equals:
status: OK
6. Indexers and matchers (索引器和匹配器)
6.1. Indexers 索引器
索引器使用pod元数据为每个pod创建唯一的标识符。
可用的索引器:
-
container
使用容器的ID标识 Pod 元数据。 -
ip_port
Identifies the pod metadata using combinations of its IP and its exposed ports.
使用 IP 和 公开的 ports 的结合标识 Pod 元数据。
When using this indexer metadata is identified using the IP of the pods, and the combination if ip:port for each one of the ports exposed by its containers.
使用此索引器时,元数据是使用pod的IP以及容器暴露的每个端口的组合来标识的ip:port
。 -
pod_name
Identifies the pod metadata using its namespace and its name as namespace/pod_name.
使用它的命名空间和名称(namespace/pod_name)标识 Pod 元数据。 -
pod_uid
Identifies the pod metadata using the UID of the pod.
使用 Pod 的 UID 表示 Pod 元数据。
6.2. Matchers
匹配器用于构造查找键,这个会与索引创建的标识符进行匹配。
matcher 插件用于定义条件,以决定是否对指定的日志进行处理。
field_format
使用字符串格式创建的键,查找pod元数据,该字符串格式可以包括事件字段。
这个匹配器有一个选项格式来定义字符串格式。此字符串格式可以包含事件中任何字段的占位符。
例如,以下配置使用 ip_port
索引器通过 Pod IP 及其公开端口的组合来识别 Pod 元数据,并使用事件中的目标 IP 和端口作为匹配密钥:
processors:
- add_kubernetes_metadata:
...
default_indexers.enabled: false
default_matchers.enabled: false
indexers:
- ip_port:
matchers:
- field_format:
format: '%{[destination.ip]}:%{[destination.port]}'
fields
使用某些特定字段的值作为关键字来查找pod元数据。定义多个字段时,将使用事件中包含的第一个字段。
此匹配器具有一个选项 lookup_fields
,用于定义其值将用于查找。
例如,以下配置使用 ip_port
索引器来识别 Pod,并定义一个匹配器,该匹配器使用目标 IP 或服务器 IP 进行查找,这是它在事件中找到的第一个匹配器:
processors:
- add_kubernetes_metadata:
...
default_indexers.enabled: false
default_matchers.enabled: false
indexers:
- ip_port:
matchers:
- fields:
lookup_fields: ['destination.ip', 'server.ip']
logs_path
使用从 log.file.path
字段中存储的日志路径中提取的标识符查找pod元数据。
此匹配器具有以下配置设置:
- logs_path
(可选)容器日志的基本路径。如果未指定,则使用运行Filebeat的平台的默认日志路径:
Linux:/var/lib/docker/containers/
Windows:C:\\ProgramData\\Docker\\containers
- resource_type
有效的资源类型:- pod: 以基于pod UID进行查找。当
resource_type
设置为pod
时,还必须设置logs_path
,在这种情况下支持路径:- /var/lib/kubelet/pods/ 用于读取挂载到 pod 卷中的日志,这些日志最终位于
/var/lib/kubelet/pods/<pod UID>/volumes/<volume-name>/..
下。要使用/var/lib/kubelet/pods/
作为log_path
,必须将/var/lib/kobelet/pods
filebeat pods。 - /var/log/pods/ 注意:当使用
resource_type: 'pod'
时,Pod 元数据将只使用Pod 元数据: pod id,namespace 填充。
- /var/lib/kubelet/pods/ 用于读取挂载到 pod 卷中的日志,这些日志最终位于
- container: 要根据容器ID进行查找,必须将
logs_path
设置为/var/log/containers/
。它默认为container
。
- pod: 以基于pod UID进行查找。当
要能够使用 logs_path
匹配器 filebeat,输入路径必须是 logs_path
配置设置中定义的目录的子目录。
当从默认的docker日志路径(Linux上的 /var/lib/docker/containers/<containerID>/…
)收集日志时,默认配置能够使用容器ID查找元数据。
例如,当从 var/lib/kubelet/pods/<pod UID>/...
收集日志时,以下配置将使用pod UID
processors:
- add_kubernetes_metadata:
...
default_indexers.enabled: false
default_matchers.enabled: false
indexers:
- pod_uid:
matchers:
- logs_path:
logs_path: '/var/lib/kubelet/pods'
resource_type: 'pod'
7. 自定义索引
8. 配置索引生命周期管理
使用Elasticsearch中的索引生命周期管理(ILM)功能来管理您的Filebeat,它们在数据流老化时作为数据流的备份索引。Filebeat自动加载默认策略,并将其应用于Filebeat创建的任何数据流。
您可以在Kibana的索引生命周期策略UI中查看和编辑策略。有关使用UI的更多信息,请参阅索引生命周期策略。
配置示例:
setup.ilm.enabled: true
如果启用了索引生命周期管理(这通常是默认设置),则会忽略setup.template.name
和 setup.template.pattern
。
8.1. 配置选项
可以在 filebeat.yml
配置文件的 setup.ilm
部分指定以下设置:
setup.ilm.enabled
对Filebeat创建的任何新索引启用或禁用索引生命周期管理。有效值为 true
和false
。
setup.ilm.policy_name
用于生命周期策略的名称。默认值为 filebeat
。
setup.ilm.policy_file
JSON文件的路径,该文件包含生命周期策略配置。使用此设置可以加载您自己的生命周期策略。
有关生命周期策略的更多信息,请参阅Elasticsearch参考中的设置索引生命周期管理策略。
setup.ilm.check_exists
如果设置为 false
,则禁用对现有生命周期策略的检查。默认值为 true
。如果连接到安全群集的Filebeat用户没有 read_ilm
权限,则需要禁用此检查。
如果将此选项设置为 false
,则即使 setup.ilm.overwrite
设置为 true
,也不会安装生命周期策略。
setup.ilm.overwrite
当设置为 true
时,生命周期策略将在启动时被覆盖。默认值为 false
。
9. 配置Elasticsearch索引模板加载
filebeat.yml 配置文件的 setup.template
部分指定用于在Elasticsearch中设置映射的索引模板。如果启用了模板加载(默认),Filebeat会在成功连接到Elasticsearch后自动加载索引模板。
加载索引模板需要连接到Elasticsearch。如果配置的输出不是Elasticsearch(或Elasticsearch服务),则必须手动加载模板。
您可以调整以下设置以加载自己的模板或覆盖现有模板。
setup.template.enabled
设置为false可禁用模板加载。如果设置为 false
,则必须手动加载模板。
setup.template.name
模版的名字,默认是 filebeat
。 Filebeat 版本总会追加到给定的名字后,因此最终的名字是 filebeat-%{[agent.version]}
。
setup.template.pattern
要应用于默认索引设置的模板模式。默认模式为 filebeat
。Filebeat版本总是包含在模式中,因此最终的模式是 Filebeat-%{[agent.version]}
。
示例:
setup.template.name: "filebeat"
setup.template.pattern: "filebeat"
setup.template.pattern
允许您定义一个模式,该模式将用于匹配将应用模板的索引名称。例如,如果您将 setup.template.pattern
设置为 "myindex-*"
,那么 Filebeat 将尝试将模板应用于所有以 "myindex-"
开头的索引。
这个选项的作用在于,它允许您根据特定的索引名称模式来自动应用索引模板,从而确保新创建的索引能够按照您的要求进行配置。
总而言之,setup.template.pattern
允许您定义一个模式,以便 Filebeat 可以自动将索引模板应用于匹配该模式的索引。
setup.template.overwrite
一个布尔值,用于指定是否覆盖现有模板。默认值为 false
。如果同时启动多个Filebeat实例,请不要启用此选项。发送过多的模板更新请求可能会使Elasticsearch过载。
setup.template.settings
通过 setup.template.settings
,您可以指定要应用于索引模板的设置,例如分片和副本的数量、索引的分片设置、索引的刷新间隔等。这些设置可以确保新创建的索引与您的要求一致,并且具有适当的性能和配置。
以下是一个示例设置 setup.template.settings 的配置:
setup.template.settings:
index.number_of_shards: 3
index.number_of_replicas: 2
一个完整的示例
setup.template.enabled: true
setup.template.overwrite: false
setup.template.name: "spms"
setup.template.pattern: "spms*"
setup.template.settings:
index.number_of_shards: 3
index.number_of_replicas: 2
9. parsers 解析器
此选项需要一个日志行必须经过的解析器列表。
可以使用的解析器:
- multiline
- ndjson
- container
- syslog
multiline
控制Filebeat如何处理跨越多行的日志消息的选项。
ndjson
这些选项使Filebeat能够解码构造为JSON消息的日志。Filebeat逐行处理日志,因此只有当每条消息有一个JSON对象时,JSON解码才有效。
解码发生在行过滤之前。如果设置message_key选项,可以将JSON解码与过滤相结合。这在应用程序日志被封装在JSON对象中的情况下很有帮助,比如在使用Docker时。
配置示例:
- ndjson:
target: ""
add_error_key: true
message_key: log
- target 新JSON对象的名称,该对象应包含已解析的键值对。如果将其留空,则新 key 将进入顶级之下。
- add_error_key 如果启用此设置,Filebeat会在json解组错误或配置中定义了
message_key
但无法使用时添加"error.message"
和"error.type:json"
key。 - message_key 一个可选的配置设置,用于指定要应用行筛选和多行设置的JSON键。如果指定了该键,则该键必须位于JSON对象的顶级,并且与该键关联的值必须是字符串,否则将不会发生筛选或多行聚合。
container
使用 container
解析器从容器日志文件中提取信息。它将行解析为通用消息行,并提取时间戳。
10. 勘探者 prospector
探矿者正在运行一个文件系统观察器,该观察器查找路径选项中指定的文件。目前只支持简单的文件系统扫描。
scanner 扫描器
扫描仪监视配置的路径。它会定期扫描文件系统,并将文件系统事件返回到“浏览”。
10.1. symlinks 软链接
符号链接选项允许Filebeat除了获取常规文件外,还可以获取符号链接。在获取符号链接时,Filebeat会打开并读取原始文件,即使它报告了符号链接的路径。
当您为获取配置符号链接时,请确保排除原始路径。如果将单个输入配置为同时获取符号链接和原始文件,Filebeat将检测到问题并只处理它找到的第一个文件。但是,如果配置了两个不同的输入(一个读取符号链接,另一个读取原始路径),则会获取两个路径,导致Filebeat发送重复数据,并且输入会覆盖彼此的状态。
如果指向日志文件的符号链接在文件名中有其他元数据,并且您希望在Logstash中处理元数据,则符号链接选项可能很有用。例如,Kubernetes日志文件就是这样。
由于此选项可能会导致数据丢失,因此默认情况下会禁用此选项。
配置示例:
prospector:
scanner:
symlinks: true
10.2. fingerprint 指纹
fingerprint 可以让 Filebeat 根据文件的内容字节范围来识别文件。
在比较文件时,不依赖设备ID和inode值(Filebeat默认行为),而是比较文件的给定字节范围的哈希值。
如果由于文件系统提供的文件标识符不稳定而导致数据丢失或数据重复,请启用此选项。
以下是可能发生这种情况的一些场景:
-
一些文件系统(即Docker中)缓存和重用inode
例如,如果你:
a. Create a file (touch x)
b. Check the file’s inode (ls -i x)
c. Delete the file (rm x)
d. 立即创建新文件(touch y)
e. 检查新文件的索引节点(ls -i y)
对于这两个文件,您可能会看到相同的 inode 值,尽管文件名不同。 -
非Ext文件系统可以更改 inodes:
Ext文件系统将索引节点号存储在i_ino文件中,该文件位于结构索引节点内,并写入磁盘。在这种情况下,如果文件是相同的(而不是另一个具有相同名称的文件),则inode编号保证是相同的。
如果文件系统不是Ext,则inode编号由文件系统驱动程序定义的inode操作生成。由于他们不知道inode是什么,所以他们必须模仿inode的所有内部字段以符合VFS,因此在重新启动后,甚至在再次关闭和打开文件后(理论上),这个数字可能会有所不同。 -
一些文件处理工具更改inode值。
有时用户会使用rsync或sed等工具无意中更改inode。 -
某些操作系统在重新启动后更改设备ID
根据装载方法的不同,设备ID(也用于比较文件)可能会在重新启动后更改。
启用指纹模式会延迟接收新文件,直到它们的大小至少增加到偏移量+长度字节,以便对其进行指纹打印。在此之前,这些文件将被忽略。
通常,日志行包含时间戳和其他应该能够使用指纹模式的唯一字段,但在每个用例中,用户都应该检查日志,以确定 offset
和 length
参数的适当值。默认偏移量为0,默认长度为1024或1 KB。长度不能小于64。
默认 Fingerprint 方法是禁用的,如下所示。
fingerprint:
enabled: false
offset: 0
length: 1024
在 docker 的 容器环境中,应该配置开启。
prospector:
scanner:
fingerprint.enabled: true
11. file_identity 文件标识
可以配置不同的 file_identity 方法,以适应收集日志消息的环境。
11.1. fingerprint
根据文件的内容字节范围来识别文件。
低版本有可能不支持,此文档用的是 8.14.1。
为了使用此文件标识选项,您必须在扫描仪中启用指纹选项。
prospector: scanner: fingerprint.enabled: true
启用此文件标识后,更改指纹配置(offset, length 或其他设置)将导致全局重新接收与输入的路径配置匹配的所有文件。
file_identity.fingerprint: ~