前两天我用 ElasticSearch 和 Kibana 折腾了一个 Nginx 日志分析系统,虽然可以用起来了,但每次都要手动下载并提交数据,这让系统的易用性大打折扣,所以我琢磨着怎么让这个过程更加便捷。经过一番尝试,我选择了 Filebeat 的方案。
关于我搭建 Nginx 日志分析系统的基础流程,可以参考前一篇文章:《使用 ElasticSearch + Kibana 搭建 Nginx 日志分析系统》。文章结尾其实也提到了使用 CURL 和 Filebeat 的日志自动提交方案,当时想的是简单一点,能用 CURL 就用 CURL,但经过尝试才发现,默认生成的 JSON 日志格式根本无法正常提交,总提示无法解析。迫不得已,只能用 Filebeat。
把 Filebeat 正常用起来也花了我不少时间,主要是目前最新版本 8.4 的 ElasticSearch 默认就开启了 SSL 访问,但用的又是自签名证书。相应的也要让 Filebeat 用证书方式访问 ElasticSearch。但这个证书要在 Filebeat 中使用需要做格式转换,我在转换以 .key 结尾的证书文件时碰到了密码问题,一时无法解决。反正是在本地使用,也无所谓安全不安全的,最终我选择了关闭 ElasticSearch 的安全功能。这需要自己提供一个配置文件,配置文件如下:
cluster.name: "docker-cluster"
network.host: 0.0.0.0
xpack.security.enabled: false
其中 xpack.security.enabled: false
就是禁用 SSL 证书访问以及密码登陆等功能的。在 ElasticSearch 的 Docker 启动命令中挂载这个配置文件到 /usr/share/elasticsearch/config/elasticsearch.yml 这个路径,等 ElasticSearch 启动就能以 *http://` 方式访问了。
然后来配置 Filebeat。首先创建一个目录 logs,用来存放下载的日志文件。Filebeat 会监控这个目录中的文件变动,一旦有新文件进来,就会自动提交到 ElasticSearch。
mkdir logs
然后创建一份 Filebeat 配置文件,内容如下:
filebeat.inputs:
- type: log
paths:
- /data/access.*
json.keys_under_root: true
json.add_error_key: true
json.overwrite_keys: true
processors:
- decode_json_fields:
fields: ["message"]
output.elasticsearch:
hosts: ["http://host.containers.internal:9200"]
indices:
- index: "nginx"
以上配置主要啊分为三块:
filebeat.inputs
定义日志的输入配置。path
指定了日志目录和文件选取规则。Nginx 的访问日志默认是以access
命名开头的,所以就这么定义了。你会发现这个目录为什么是/data
而不是上面创建的logs
,这是因为我会以 Docker 容器的方式来启动 Filebeat,我会把logs
目录挂载到容器中的/data
路径下,所以这里配置的是容器中的路径。后面几个以json
开头的配置项很重要,它们决定了日志内容的展开方式。processors
定义日志的处理部分。Filebeat 默认会把从文件中获取的日志内容放到message
字段,这里的定义就是告诉 Filebeat 在处理时用 JSON 解析日志内容。output.elasticsearch
定义了日志的输出。它主要告诉 Filebeat 数据提交地址,以及相关索引名称。不存在的索引会自动创建。http://host.containers.internal
是 Podman 容器引擎的一个特殊的地址,它指向运行容器的主机 IP。
然后用容器命令启动 Filebeat:
podman run --rm -it \
--userns keep-id \
--network analysis \
-v $PWD/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro \
-v $PWD/logs:/data \
--name filebeat docker.elastic.co/beats/filebeat:8.4.0
这里使用的容器引擎是 Podman,如果你使用的是 Docker,大可不必担心,它们区别不大。把 podman
换成 docker
,然后删掉 --userns keep-id
选项就可以了。
如果 logs 目录中有日志文件,或是现在就丢几个进去,数据立马就会被 Filebeat 提交到 ElasticSearch 中。打开 Kibana,看看 「Index Management」 索引管理页面,会发现数据已经有了。
现在我每天要看最新数据时,只需要用 Shell 命令把日志下载到 logs 目录就可以了。这一步貌似也可以通过 Crontab 计划任务来省掉。