第九章:日志管理与分析

最后更新: 2024-01-01 作者: DevOps Team
页面目录

第九章:日志管理与分析

日志是系统运行状态的直接反映,也是故障排查的重要依据。本章将介绍如何构建集中式日志管理系统,实现日志的采集、存储、搜索和分析。


9.1 日志架构

9.1.1 ELK Stack 架构

┌─────────────────────────────────────────────────────────────────┐
│                       ELK Stack 架构                             │
│                                                                 │
│  ┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐       │
│  │  应用    │   │  容器    │   │  系统    │   │  网络    │       │
│  └────┬────┘   └────┬────┘   └────┬────┘   └────┬────┘       │
│       │              │              │              │            │
│       └──────────────┼──────────────┼──────────────┘            │
│                      ↓                                          │
│              ┌───────────────┐                                  │
│              │   Filebeat     │                                  │
│              │   Fluentd      │                                  │
│              │   Logstash     │                                  │
│              └───────┬───────┘                                  │
│                      ↓                                          │
│              ┌───────────────┐                                  │
│              │ Elasticsearch  │                                  │
│              │   (存储/搜索)   │                                  │
│              └───────┬───────┘                                  │
│                      ↓                                          │
│              ┌───────────────┐                                  │
│              │    Kibana      │                                  │
│              │   (可视化)     │                                  │
│              └───────────────┘                                  │
└─────────────────────────────────────────────────────────────────┘

9.1.2 日志类型

类型 说明 示例
应用日志 应用程序产生的业务日志 业务事件、错误堆栈
系统日志 操作系统和中间件日志 syslog、dmesg
容器日志 容器运行日志 stdout、stderr
审计日志 安全和合规相关的操作记录 登录、操作审计

9.2 日志采集配置

9.2.1 Fluentd 配置

# /etc/fluent/fluent.conf
<source>
  @type tail
  @id input-tail-app
  path /var/log/myapp/*.log
  pos_file /var/log/fluent/app.log.pos
  tag myapp.app
  <parse>
    @type json
    time_type float
  </parse>
</source>

<source>
  @type tail
  @id input-tail-container
  path /var/log/containers/*.log
  pos_file /var/log/fluent/containers.log.pos
  tag kubernetes.container
  <parse>
    @type cri
  </parse>
</source>

<filter myapp.**>
  @type parser
  key_name log
  <parse>
    @type json
    time_type float
  </parse>
  replace_key_reader true
  keep_key_reader true
</filter>

<filter kubernetes.container>
  @type kubernetes_metadata
  @id filter-kube-metadata
  kubernetes_url https://kubernetes.default.svc
  verify_ssl true
  cache_size 1000
  watch false
</filter>

<match myapp.**>
  @type elasticsearch
  @id output-elasticsearch
  host elasticsearch.logging.svc
  port 9200
  logstash_format true
  logstash_prefix myapp
  include_tag_key true
  <buffer>
    @type file
    path /var/log/fluent/buffers/myapp
    flush_mode interval
    flush_interval 10s
    retry_type exponential_backoff
  </buffer>
</match>

9.2.2 Filebeat 配置

# filebeat.yml
filebeat.inputs:
  - type: container
    enabled: true
    paths:
      - /var/log/containers/*.log
    processors:
      - add_kubernetes_metadata:
          host: ${NODE_NAME}
          matchers:
            - logs_path:
                logs_path: "/var/log/containers/"

  - type: log
    enabled: true
    paths:
      - /var/log/myapp/*.log
    json.keys_under_root: true
    json.add_error_key: true
    fields:
      service: myapp
      environment: production

processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~

output.elasticsearch:
  hosts: ["elasticsearch:9200"]
  index: "myapp-%{+yyyy.MM.dd}"

setup.kibana:
  host: "kibana:5601"

9.3 Kibana 日志分析

9.3.1 日志查询语法

// JSON 格式日志查询
{
  "query": {
    "bool": {
      "must": [
        { "match": { "level": "ERROR" } },
        { "range": { "@timestamp": { "gte": "now-1h" } } }
      ],
      "filter": [
        { "term": { "service": "api-gateway" } }
      ]
    }
  }
}

// Lucene 查询语法
// level:ERROR AND service:api-gateway AND @timestamp:[now-1h TO now]

9.4 Loki 日志系统

9.4.1 Loki 配置

# loki-config.yaml
auth_enabled: false

server:
  http_listen_port: 3100
  grpc_listen_port: 9096

distributor:
  ring:
    instance_addr: 127.0.0.1
    kvstore:
      store: inmemory

ingester:
  lifecycler:
    address: 127.0.0.1
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1
  chunk_idle_period: 15m
  max_transfer_retries: 0

schema_config:
  configs:
    - from: 2024-01-01
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h

storage_config:
  boltdb_shipper:
    active_index_directory: /tmp/loki/index
    cache_location: /tmp/loki/cache
  filesystem:
    directory: /tmp/loki/chunks

limits_config:
  reject_old_samples: true
  reject_old_samples_max_age: 168h

9.4.2 LogQL 查询

# 查询所有错误日志
{service="api-gateway"} |= "ERROR"

# 统计错误数量
sum(count_over_time({service="api-gateway"} |= "ERROR"[5m]))

# 按状态码统计
sum by (status) (rate({service="api-gateway"}[5m]))

# 日志趋势
histogram_quantile(0.99, sum(rate({service="api-gateway"}[5m])) by (le))

9.5 日志最佳实践

9.5.1 日志规范

// 标准日志格式
{
  "timestamp": "2024-01-01T12:00:00.000Z",
  "level": "INFO",
  "service": "order-service",
  "version": "1.2.3",
  "trace_id": "abc123",
  "span_id": "def456",
  "user_id": "user_123",
  "message": "Order created successfully",
  "context": {
    "order_id": "ord_789",
    "amount": 99.99,
    "currency": "USD"
  },
  "metadata": {
    "host": "pod-xyz",
    "environment": "production"
  }
}

9.5.2 日志级别使用

级别 使用场景 示例
DEBUG 开发调试信息 变量值、详细流程
INFO 正常业务事件 请求开始/结束、状态变更
WARN 潜在问题 超时重试、资源使用高
ERROR 错误异常 业务异常、系统故障
FATAL 系统不可用 服务崩溃、无法恢复

9.6 本章小结

组件 功能 特点
ELK Stack 完整日志解决方案 功能全面,资源消耗大
Loki 日志聚合系统 原生支持 Kubernetes,资源高效
Fluentd 日志采集器 插件丰富,配置灵活
Filebeat 轻量日志采集 占用资源少,适合容器环境

📌 下一章预告

下一章我们将学习 DevOps 安全实践,包括:

  • 容器安全扫描
  • 密钥管理
  • 安全合规

💡 提示:日志应该结构化,便于搜索和分析。建议使用 JSON 格式记录日志。