Docker Compose整合ELK/EFK需打通「应用输出→采集→结构化入库→查询」全链路:统一JSON日志格式,优选Fluent Bit采集并映射关键字段,预设Elasticsearch索引模板(service/level设为keyword),Kibana配置时间字段与KQL精准检索。

用 Docker Compose 整合 ELK(Elasticsearch + Logstash + Kibana)或 EFK(Elasticsearch + Fluentd + Kibana)是提升分布式日志检索效率的主流方案。关键不在于堆组件,而在于打通「应用输出 → 日志采集 → 结构化入库 → 高效查询」全链路。下面分四步讲清实操要点。
统一日志输出格式:结构化是高效检索的前提
非结构化日志(如纯文本、混排时间戳)会让 Elasticsearch 无法自动识别字段,导致全文检索慢、过滤失效。必须让各服务输出标准 JSON 日志:
- .NET 后端:在
appsettings.json中配置 Serilog 或 Microsoft.Extensions.Logging 输出为 JSON,启用RenderedCompactJsonFormatter,确保含timestamp、level、service、message、trace_id字段 - Node.js:使用
pino并配pino-elasticsearch传输插件,或直接 stdout 输出 JSON - Vue+Nginx 前端:修改 Nginx 配置,用
log_format定义 JSON 格式 access log,例如:log_format json_log '{"time":"$time_iso8601","host":"$server_addr","uri":"$uri","status":$status,"bytes":$body_bytes_sent,"agent":"$http_user_agent"}'; - 所有服务需禁用控制台彩色/ANSI 转义符,避免 JSON 解析失败
日志采集层选型与 Compose 配置
Logstash 功能强但资源开销大;Fluentd/Fluent Bit 更轻量、更适合容器环境。推荐 Fluent Bit(EFK 方案),配置简洁且原生支持 Kubernetes 和 Docker 标签:
- 在
docker-compose.yml中定义fluent-bit服务,挂载宿主机/var/lib/docker/containers(Docker 默认日志路径)和容器日志目录(如./logs) - Fluent Bit 配置
input指向tail插件读取容器 JSON 日志文件,filter提取container_name、source等元数据,output指向 Elasticsearch 的http接口 - 务必设置
Key字段映射(如log_key log),否则 Fluent Bit 默认只传原始行,Elasticsearch 无法解析内部 JSON 字段
Elasticsearch 映射与索引优化
默认动态映射会将字符串字段设为 text 类型(支持全文检索但不可聚合),而 service、level、status 这类字段应设为 keyword 类型,才能用于精确过滤、图表统计:
- 创建索引模板(Index Template),指定
pattern: "logstash-*"或自定义前缀,预定义字段类型,例如:"service": { "type": "keyword" }, "level": { "type": "keyword" }, "timestamp": { "type": "date" } - 关闭不需要的字段
norms和index(如日志原始内容过长且不需检索,可设"log": { "index": false })以节省存储和提升写入性能 - 对高频查询字段(如
service+level组合)建立复合terms聚合,Kibana 可直接生成服务错误率趋势图
Kibana 可视化与日常检索技巧
Kibana 不只是看图工具,合理配置能大幅缩短排查时间:
- 在
Stack Management → Index Patterns中关联日志索引,并勾选Advanced settings → Timestamp field指定@timestamp或自定义时间字段,确保时间范围筛选准确 - 用
Discover页面左侧Add filter快速添加service: "auth-api"、level: "error"等条件,组合后实时刷新结果 - 在
Visualize Library创建「按服务统计 error 数量」的垂直柱状图,或「过去1小时 error top 5 URI」的表格,嵌入 Dashboard 作为值班看板 - 启用
Query Language(KQL),比 Lucene 更直观,例如输入service : "order-service" and message : "timeout" and timestamp > "now-15m"即可精准定位


















