MonkeyCode搞定ELK日志体系:从零搭建生产级日志平台

[复制链接]
发表于 昨天 04:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
步调员的一样平常:看日志日志→猜题目→改代码→看日志日志。有了ELK,整个过程从"猜"酿成"查"。
ELK是什么?
  1. ELK Stack
  2. ├── Elasticsearch  → 存储 + 搜索(核心)
  3. ├── Logstash     → 收集 + 过滤 + 转发(处理器)
  4. ├── Kibana       → 查询 + 可视化(界面)
  5. └── Beats        → 日志日志采集Agent(搬运工)
复制代码
版本ELK Stack = Elasticsearch + Logstash + Kibana + Beats
团体架构
  1. 你的应用(Python/Go/Java)
  2.     ↓ 输出JSON日志(stdout或文件)
  3. Filebeat(轻量Agent,部署在每台服务器
  4.     ↓ 采集日志,转发
  5. Logstash(过滤、解析、丰富)
  6.     ↓ 写入
  7. Elasticsearch(存储、索引、搜索)
  8.     ↓ 查询展示
  9. Kibana(可视化、告警、Dashboard)
复制代码
第一步:Docker Compose一键启动

让MonkeyCode天生:
  1. # docker-compose.elk.yml
  2. version: '3.8'
  3. services:
  4.   elasticsearch:
  5.     image: elasticsearch:8.12.0
  6.     environment:
  7.       - discovery.type=single-node
  8.       - xpack.security.enabled=false
  9.       - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
  10.     ports: ["9200:9200", "9300:9300"]
  11.     volumes: ["es_data:/usr/share/elasticsearch/data"]
  12.     healthcheck:
  13.       test: ["CMD-SHELL", "curl -f http://localhost:9200 || exit 1"]
  14.       interval: 30s
  15.       timeout: 10s
  16.       retries: 5
  17.       
  18.   logstash:
  19.     image: logstash:8.12.0
  20.     ports: ["5044:5044", "5000:5000/udp"]
  21.     volumes:
  22.       - ./logstash/pipeline:/usr/share/logstash/pipeline:ro
  23.       - ./logstash/config:/usr/share/logstash/config:ro
  24.     depends_on: [elasticsearch]
  25.    
  26.   kibana:
  27.     image: kibana:8.12.0
  28.     ports: ["5601:5601"]
  29.     environment:
  30.       - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
  31.     depends_on: [elasticsearch]
  32.    
  33.   filebeat:
  34.     image: elastic/filebeat:8.12.0
  35.     user: root
  36.     volumes:
  37.       - /var/lib/docker/containers:/var/lib/docker/containers:ro
  38.       - /var/run/docker.sock:/var/run/docker.sock:ro
  39.       - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
  40.       - ./logs:/var/log/app:ro
  41.     depends_on: [logstash]
  42.     network_mode: "host"
  43. volumes:
  44.   es_data:
复制代码
启动:
  1. docker-compose -f docker-compose.elk.yml up -d
复制代码
访问Kibana:http://localhost:5601
第二步:应用输出布局化日志

关键原则:永久输出JSON格式,不要输出文本日志。
  1. # app/logging_config.py
  2. import structlog
  3. import json
  4. import sys
  5. def setup_logging():
  6.     structlog.configure(
  7.         processors=[
  8.             # 添加时间戳
  9.             structlog.processors.TimeStamper(fmt="iso"),
  10.             # 添加日志级别
  11.             structlog.processors.add_log_level,
  12.             # 添加进程/线程信息
  13.             structlog.processors.add_logger_name,
  14.             # 异常信息格式化
  15.             structlog.processors.format_exc_info,
  16.             # 输出为JSON
  17.             structlog.dev.JSONRenderer()
  18.         ],
  19.         logger_factory=structlog.PrintLoggerFactory(file=sys.stdout),
  20.         wrapper_class=structlog.stdlib.BoundLogger,
  21.     )
  22. logger = structlog.get_logger()
  23. # 使用
  24. async def create_order(req: CreateOrderRequest, user_id: int):
  25.     log = logger.bind(user_id=user_id, endpoint="/orders")
  26.     log.info("order.create.attempt", amount=req.amount, items=len(req.items))
  27.     try:
  28.         order = await db.create_order(req, user_id)
  29.         log.info("order.create.success", order_id=order.id, amount=order.total_amount)
  30.         return order
  31.     except Exception as e:
  32.         log.error("order.create.failed", error=str(e), exc_info=True)
  33.         raise
复制代码
输出到stdout的JSON日志:
  1. {"event": "order.create.success", "level": "info", "timestamp": "2024-06-01T10:30:00Z", "user_id": 42, "order_id": 10086, "amount": 299.0}
复制代码
第三步:Filebeat收罗日志
  1. # filebeat.yml
  2. filebeat.inputs:
  3.   - type: log
  4.     enabled: true
  5.     paths:
  6.       - /var/log/app/*.log
  7.       - /var/log/app/*.json
  8.     json.keys_under_root: true   # 解析JSON,字段提到顶层
  9.     json.overwrite_keys: true
  10.     tags: ["app", "production"]
  11.     fields:
  12.       env: production
  13.       app: my-service
  14.     fields_under_root: true
  15.   - type: container                  # Docker容器日志
  16.     enabled: true
  17.     paths:
  18.       - /var/lib/docker/containers/*/*.log
  19.     json.keys_under_root: true
  20. processors:
  21.   - add_docker_metadata: ~
  22.   - add_host_metadata: ~
  23.   - dissect:
  24.       tokenizer: "%{timestamp} %{level} %{message}"
  25.       field: "message"
  26.       target_prefix: ""
  27. # 输出到Logstash(推荐)或直连Elasticsearch
  28. output.logstash:
  29.   hosts: ["logstash:5044"]
  30. # 或者直接输出到Elasticsearch(跳过Logstash,简单场景)
  31. # output.elasticsearch:
  32. #   hosts: ["elasticsearch:9200"]
  33. #   index: "my-app-%{+yyyy.MM.dd}"
复制代码
第四步:Logstash过滤与分析
  1. # logstash/pipeline/logstash.conf
  2. input {
  3.   beats {
  4.     port => 5044
  5.   }
  6. }
  7. filter {
  8.   # 解析时间戳
  9.   if [timestamp] {
  10.     date {
  11.       match => [ "timestamp", "ISO8601" ]
  12.     }
  13.   }
  14.   
  15.   # 解析JSON字段(如果Filebeat没解析)
  16.   if [message] =~ /^\{.*\}$/ {
  17.     json {
  18.       source => "message"
  19.       skip_on_invalid_json => true
  20.     }
  21.   }
  22.   
  23.   # 添加地理位置(IP地址)
  24.   if [remote_ip] {
  25.     geoip {
  26.       source => "remote_ip"
  27.       target => "geoip"
  28.     }
  29.   }
  30.   
  31.   # 添加User-Agent解析
  32.   if [user_agent] {
  33.     useragent {
  34.       source => "user_agent"
  35.       target => "ua"
  36.     }
  37.   }
  38.   
  39.   # 过滤掉健康检查日志
  40.   if [endpoint] == "/health" {
  41.     drop {}
  42.   }
  43. }
  44. output {
  45.   elasticsearch {
  46.     hosts => ["elasticsearch:9200"]
  47.     index => "logs-%{+YYYY.MM.dd}"
  48.     manage_template => false
  49.   }
  50.   
  51.   # 调试用:同时输出到控制台
  52.   # stdout { codec => rubydebug }
  53. }
复制代码
第五步:在Kibana中查询

启动后,在Kibana中:
1. 创建Index Pattern

进入 Management → Stack Management → Index Patterns,创建 logs-*
2. 常用查询语法(KQL)

[code]# 正确匹配level: error# 暗昧搜索message: "order"# 多条件level: error AND service: payment# 范围查询@timestamp >= "2024-06-01T00:00:00Z" AND @timestamp
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表