Go日志分析系统-ELK实时日志监控
文章目录
1: 概述与适用范围
- 本文搭建一套可在单台开发机运行的日志采集与检索环境,完整链路为:
Go 应用 -> JSON 日志文件 -> Filebeat -> Logstash -> Elasticsearch -> Kibana; - Go 应用负责逐行写入结构化 JSON,Filebeat 负责增量读取文件,Logstash 负责接收和转发,Elasticsearch 负责存储与检索,Kibana 负责可视化查询;
- 教程面向 Go 开发者和初级 DevOps 工程师,重点是先跑通一个可观察、可排障的最小闭环;
- 本文的 Compose 配置关闭了 Elastic 安全认证,仅允许用于本机学习,禁止直接暴露到公网或照搬到生产环境;
- 原文参考:Go日志分析系统-ELK实时日志监控。
2: ELK/Filebeat 组件职责
| 组件 | 职责 | 本文端口 |
|---|---|---|
| Go 应用 | 生成逐行 JSON 业务日志 | 无 |
| Filebeat | 追踪文件读取位置,将新增日志发送给 Logstash | 无 |
| Logstash | 通过 Beats input 接收事件,并写入指定索引 | 5044,监控 API 9600 |
| Elasticsearch | 存储、索引和查询日志 | 9200 |
| Kibana | 创建 Data View,使用 KQL 检索日志 | 5601 |
- Filebeat 比直接让 Go 应用调用 Elasticsearch 更容易处理断线重试、读取进度和日志轮转;
- Logstash 在这个入门示例中只做轻量转发。后续需要字段清洗、脱敏或路由时,可以在 pipeline 中增加 filter;
- Elasticsearch 和 Kibana 比较消耗内存,启动前应确认 Docker 可用资源充足。
3: 数据流与示例目录
数据流如下:
| |
新建一个空目录,并准备以下文件:
| |
logs/可以暂时不手动创建,Go 程序中的os.MkdirAll会负责创建;- Filebeat 容器将宿主机
./logs只读挂载为/var/log/go-app; - Filebeat 的读取进度保存在命名卷
filebeat-data中,容器重建后不会从头重复读取所有日志。
4: 环境要求
- Docker Engine 24+,并包含 Docker Compose v2;
- Go 1.21+;
curl,用于检查 Elasticsearch;- 建议为 Docker 分配至少 4 GB 内存和 2 个 CPU;
- Linux 主机如果 Elasticsearch 因虚拟内存限制退出,可临时设置:
| |
- 上述
sysctl -w只在当前系统运行期间生效,重启后会恢复; - 需要持久化时,写入独立配置文件并重新加载系统参数:
| |
先确认工具版本:
| |
5: Go JSON 日志程序
在项目根目录创建 main.go。示例只使用 Go 标准库,输出的每一行都是一个独立 JSON 对象。
| |
json.NewEncoder会在每次Encode后追加换行,符合 Filebeat 的逐行采集方式;@timestamp使用 UTC RFC3339 格式,方便 Elasticsearch 和 Kibana 作为时间字段处理;- 程序采用追加模式,每运行一次会再生成 3 条日志。
6: Docker Compose
创建 docker-compose.yml:
| |
- 四个组件统一使用
8.14.3,避免不同大版本之间的协议和字段兼容问题; - 对外端口只绑定
127.0.0.1,降低学习环境被局域网或公网访问的风险; - Filebeat 使用
root和--strict.perms=false只是为了兼容本地 bind mount 的所有权差异;生产环境应设置正确的文件所有者和权限,并保留 Filebeat 的严格权限检查; depends_on.condition用于等待上游健康,但它不能替代应用自身的重试机制。
7: Logstash pipeline
创建 logstash/pipeline/logstash.conf:
| |
- Beats input 与 Filebeat output 都使用
5044; - 索引名称固定为
go-app-日期,因此 Kibana Data View 使用go-app-*; stdout便于在学习阶段通过docker compose logs logstash查看 Logstash 实际收到的事件。
8: Filebeat 配置
创建 filebeat/filebeat.yml:
| |
paths必须写容器内路径/var/log/go-app/*.log,它与 Compose 中./logs:/var/log/go-app:ro完全对应;ndjson.target: ""将 JSON 字段放到事件根级,overwrite_keys: true允许应用日志中的@timestamp覆盖 Filebeat 的采集时间,Logstash 也可以直接读取service、level和trace_id;- filestream 默认指纹长度较大,入门示例日志文件很小,因此将指纹长度调整为
64字节,避免短文件迟迟不开始采集;该值只适用于短演示文件,生产环境应使用更长指纹,或保证不同日志文件的文件头足以区分; - registry 位于
/usr/share/filebeat/data,已经映射到filebeat-data命名卷。
9: 启动服务
先让 Go 程序创建 logs/ 和第一批日志,再校验并启动 Compose:
| |
docker compose config 应输出合并后的有效配置且不报错。docker compose ps 最终应看到四个服务均为 Up,健康检查完成后状态包含 healthy。
检查 Elasticsearch 集群健康状态:
| |
单机模式下预期 status 为 yellow 或 green。如果使用默认副本设置,单节点无法分配副本时显示 yellow 是正常现象,但不应为 red。
10: 生成并验证日志
服务全部健康后,再生成一批日志:
| |
查看本地文件和各采集组件日志:
| |
确认索引已经创建:
| |
查询最新日志:
| |
同时比对原始日志和 Elasticsearch 返回结果中的时间字段:原文件每行的 @timestamp 应与查询结果 _source.@timestamp 一致,而不是 Filebeat 读取该行的时间。
预期结果中包含:
| |
- 第一次启动时,镜像下载、Elasticsearch 初始化和 Filebeat 建立连接需要一些时间;
- 如果查询暂时为空,等待数秒后重试,并按第 14 节顺序检查各环节。
11: Kibana Data View 与 KQL
- 浏览器打开
http://localhost:5601; - 进入 Stack Management -> Data Views;
- 点击 Create data view;
- Name 可填写
Go App Logs,Index pattern 填写go-app-*; - Timestamp field 选择
@timestamp,保存后进入 Discover; - 将右上角时间范围调整为包含刚才生成日志的时间。
在 Discover 的查询框中分别执行以下 KQL:
| |
| |
| |
service用于按服务筛选;level用于快速定位错误日志;trace_id用于串联一次请求在不同处理阶段的日志。真实服务中应由入口生成 trace ID,并在调用链中持续传递。
12: 日志轮转和保留策略
- 本文程序只负责追加文件,没有内置轮转。长期运行时必须限制单文件大小和保留时间,否则磁盘最终会写满;
- 在 Linux 主机上可以使用
logrotate,按天或按大小轮转logs/app.log,设置rotate、maxage、compress等策略; - Go 服务也可以使用成熟的轮转库,但应确认轮转方式与 Filebeat filestream 的文件识别机制兼容,优先采用重命名旧文件并创建新文件,而不是反复复制截断;
- Filebeat registry 只记录读取进度,不负责删除源日志;源文件轮转与 Elasticsearch 索引保留是两个独立问题;
- Elasticsearch 生产环境通常通过 ILM(Index Lifecycle Management)管理热数据保留、只读、迁移和删除。例如保留 7 天热数据、30 天后删除;具体周期应根据查询需求、合规要求和磁盘容量确定;
- 本文为了保持入门配置简洁,没有创建 ILM policy。不要把“每日索引”误认为已经具备自动清理能力。
13: 监控与基础安全
建议至少关注以下状态:
| 对象 | 基础检查 |
|---|---|
| 容器 | docker compose ps、重启次数、CPU、内存、磁盘 |
| Filebeat | harvester 是否启动、发送失败、registry 是否可写、积压量 |
| Logstash | pipeline 是否加载、事件吞吐、队列和 JVM 堆使用率 |
| Elasticsearch | cluster health、节点磁盘、JVM heap、索引增长和 rejected 请求 |
- 学习环境可以用
docker compose logs、docker stats和各组件 HTTP API 做基础检查; - 生产环境必须启用 Elasticsearch/Kibana 认证和 TLS,Filebeat 到 Logstash、Logstash 到 Elasticsearch 的链路也应使用 TLS;
- 为采集端、写入端和查询端分别创建最小权限账号,不要让所有组件共用超级管理员凭据;
- 日志网络应与业务公网隔离,通过防火墙、安全组或容器网络限制访问;
- 日志中不得写入密码、Token、完整身份证号等敏感数据。必要时在应用输出前或 Logstash filter 中脱敏;
- 密钥应通过 Secret 管理系统或受控环境变量注入,不能硬编码到 Compose 或提交到 Git。
14: 常见故障排查
排障时沿数据流从左到右检查,不要直接在 Kibana 末端反复刷新。
14.1 容器未启动
| |
- Elasticsearch 常见原因是内存不足或
vm.max_map_count太小; - Logstash、Filebeat 常见原因是 YAML/配置文件语法错误或挂载路径不存在;
- 先修复第一个明确错误,再重启对应服务:
docker compose restart 服务名。
14.2 Filebeat 无输入
| |
- 确认宿主机文件存在,并且容器内
/var/log/go-app/app.log可读; - 确认配置中的路径是
/var/log/go-app/*.log,而不是宿主机路径./logs/*.log; - 如果为了重复实验删除了日志文件,但保留了 registry,Filebeat 可能认为旧内容已经读过。学习环境可按第 16 节完整清理卷后重试;生产环境不要随意删除 registry。
14.3 Logstash pipeline 错误
| |
- 重点检查
logstash.conf的括号、插件参数和 Elasticsearch 地址; hosts应使用 Compose 服务名http://elasticsearch:9200,不能在容器内写localhost:9200;- 修改 pipeline 后执行
docker compose restart logstash,再观察是否成功加载。
14.4 Elasticsearch 无索引
| |
- 集群为
red时先处理 Elasticsearch 本身; - 集群正常但没有
go-app-*时,检查 Logstash 是否收到事件以及 output 是否连接成功; - 如果 Logstash 有事件但写入失败,日志通常会给出映射冲突、连接失败或磁盘水位等原因。
14.5 Kibana 无数据
- 先用
_cat/indices和_search确认 Elasticsearch 中确实有数据; - 确认 Data View 是
go-app-*,时间字段是@timestamp; - 调大 Discover 时间范围,并清空可能残留的 KQL 筛选条件;
- 如果
_search有数据而 Discover 没有,检查日志时间是否位于当前查询时间窗内。
15: 生产环境演进
跑通单机链路后,可以按实际瓶颈逐步演进,而不是一次引入所有复杂组件:
- 日志峰值导致 Logstash 或 Elasticsearch 短暂不可用时,可在 Filebeat 与消费端之间引入 Kafka,提供削峰和更长时间的缓冲;
- 数据量和可用性要求提升后,将单节点 Elasticsearch 扩展为多节点集群,并规划分片、副本、冷热层和快照恢复;
- 运行在 Kubernetes 时,可用 Filebeat DaemonSet 采集各节点容器日志,并补充 namespace、pod、container 等元数据;
- 配置数量增加后,可使用 Fleet、配置仓库、模板化部署或其他集中配置管理方式,避免逐台修改;
- 进一步接入告警、Dashboard、链路追踪和指标系统,形成日志、指标、Trace 的统一可观测体系。
Kafka、Elasticsearch 集群、Kubernetes DaemonSet 和集中配置管理都属于生产演进,不是本文核心教程的前置条件。
16: 清理环境
停止并删除容器、网络以及 Elasticsearch/Filebeat 数据卷:
| |
如需同时删除本地示例日志:
| |
-v会删除 Elasticsearch 数据和 Filebeat registry,所有已索引日志及读取进度都会丢失;- 执行前确认目录中没有需要保留的数据;
- 不加
-v的docker compose down会保留命名卷,适合稍后继续实验。
17: 总结与参考
- 结构化 JSON 是日志进入检索平台的基础,稳定字段比一大段难以解析的文本更容易筛选和聚合;
- Filebeat 负责可靠采集,Logstash 负责处理与转发,Elasticsearch 负责存储检索,Kibana 负责交互式分析;
- 本文所有路径、端口和索引保持统一:
./logs/*.log、5044、9200、5601、go-app-*; - 单机 Compose 适合学习和验证,不代表生产架构。生产环境必须补齐认证、TLS、网络隔离、最小权限、轮转、ILM、备份和监控。
参考资料:
文章作者 lucas(lpp)
上次更新 2026-07-13