跳转至

第12章:监控与日志

监控与日志

12.1 监控概述

监控的作用

  1. 发现问题:及时发现系统问题
  2. 定位问题:快速定位问题根源
  3. 预防问题:提前预警潜在问题
  4. 优化性能:持续优化系统性能

监控的类型

  1. 基础监控:CPU、内存、磁盘、网络
  2. 应用监控:应用指标、业务指标
  3. 日志监控:日志收集、分析
  4. 链路追踪:请求链路追踪

12.2 监控指标

12.2.1 基础指标

CPU监控

Python
import psutil

def get_cpu_usage():
    # CPU使用率
    cpu_percent = psutil.cpu_percent(interval=1)
    print(f"CPU使用率: {cpu_percent}%")

    # CPU核心数
    cpu_count = psutil.cpu_count()
    print(f"CPU核心数: {cpu_count}")

    # CPU负载
    load_avg = psutil.getloadavg()
    print(f"CPU负载: {load_avg}")

get_cpu_usage()

内存监控

Python
def get_memory_usage():
    # 内存使用情况
    memory = psutil.virtual_memory()
    print(f"总内存: {memory.total / 1024 / 1024 / 1024:.2f} GB")
    print(f"已用内存: {memory.used / 1024 / 1024 / 1024:.2f} GB")
    print(f"内存使用率: {memory.percent}%")

get_memory_usage()

磁盘监控

Python
def get_disk_usage():
    # 磁盘使用情况
    disk = psutil.disk_usage('/')
    print(f"总磁盘: {disk.total / 1024 / 1024 / 1024:.2f} GB")
    print(f"已用磁盘: {disk.used / 1024 / 1024 / 1024:.2f} GB")
    print(f"磁盘使用率: {disk.percent}%")

    # 磁盘IO
    disk_io = psutil.disk_io_counters()
    print(f"读取次数: {disk_io.read_count}")
    print(f"写入次数: {disk_io.write_count}")

get_disk_usage()

网络监控

Python
def get_network_usage():
    # 网络IO
    network = psutil.net_io_counters()
    print(f"发送字节: {network.bytes_sent}")
    print(f"接收字节: {network.bytes_recv}")
    print(f"发送包数: {network.packets_sent}")
    print(f"接收包数: {network.packets_recv}")

get_network_usage()

12.2.2 应用指标

Python
from prometheus_client import Counter, Gauge, Histogram, start_http_server  # Counter计数器:统计元素出现次数

# 定义指标
request_count = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint'])
request_duration = Histogram('http_request_duration_seconds', 'HTTP request duration')
active_connections = Gauge('active_connections', 'Active connections')

# 记录指标
def handle_request(method, endpoint):
    request_count.labels(method=method, endpoint=endpoint).inc()

    with request_duration.time():
        # 处理请求
        process_request()

    active_connections.inc()

# 启动Prometheus HTTP服务器
start_http_server(8000)

12.3 日志收集

12.3.1 日志级别

Python
import logging

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

logger = logging.getLogger(__name__)

# 记录不同级别的日志
logger.debug("Debug message")
logger.info("Info message")
logger.warning("Warning message")
logger.error("Error message")
logger.critical("Critical message")

12.3.2 结构化日志

Python
import json
import logging
from pythonjsonlogger import jsonlogger

# 配置JSON日志
logger = logging.getLogger(__name__)
handler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter()
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# 记录结构化日志
logger.info({
    "event": "user_login",
    "user_id": 123,
    "ip": "192.168.1.1",
    "timestamp": "2024-01-01T00:00:00Z"
})

12.3.3 ELK Stack

Elasticsearch

Python
from elasticsearch import Elasticsearch

# 创建Elasticsearch客户端
es = Elasticsearch(['http://localhost:9200'])

# 索引日志
log_entry = {
    "timestamp": "2024-01-01T00:00:00Z",
    "level": "INFO",
    "message": "User logged in",
    "user_id": 123,
    "ip": "192.168.1.1"
}

es.index(index='logs', document=log_entry)

Logstash

Text Only
# Logstash配置
input {
  file {
    path => "/var/log/app.log"
    start_position => "beginning"
  }
}

filter {
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:message}" }
  }
  date {
    match => ["timestamp", "ISO8601"]
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "logs-%{+YYYY.MM.dd}"
  }
}

Kibana

Kibana是一个可视化工具,用于查看和分析Elasticsearch中的数据。

12.4 链路追踪

12.4.1 OpenTelemetry

Python
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.jaeger.thrift import JaegerExporter

# 配置Tracer
trace.set_tracer_provider(TracerProvider())
jaeger_exporter = JaegerExporter(
    agent_host_name="localhost",
    agent_port=6831,
)
trace.get_tracer_provider().add_span_processor(
    BatchSpanProcessor(jaeger_exporter)
)

tracer = trace.get_tracer(__name__)

# 创建span
with tracer.start_as_current_span("main-operation"):
    # 执行操作
    do_something()

    # 创建子span
    with tracer.start_as_current_span("sub-operation"):
        do_sub_operation()

12.4.2 Jaeger

Jaeger是一个分布式追踪系统,用于监控和诊断微服务架构中的事务。

12.5 告警

12.5.1 告警规则

YAML
# Prometheus告警规则
groups:
  - name: alert_rules
    interval: 30s
    rules:
      - alert: HighCPUUsage
        expr: cpu_usage_percent > 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High CPU usage detected"
          description: "CPU usage is above 80% for more than 5 minutes"

      - alert: HighMemoryUsage
        expr: memory_usage_percent > 90
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High memory usage detected"
          description: "Memory usage is above 90% for more than 5 minutes"

12.5.2 Alertmanager

YAML
# Alertmanager配置
global:
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'web.hook'

receivers:
  - name: 'web.hook'
    webhook_configs:
      - url: 'http://localhost:5001/alerts'

12.6 实战练习

练习1:实现一个监控系统

实现一个监控系统,包括: 1. 基础指标监控 2. 应用指标监控 3. 告警规则 4. 可视化展示

练习2:实现一个日志系统

实现一个日志系统,包括: 1. 日志收集 2. 日志存储 3. 日志分析 4. 日志查询

练习3:实现一个链路追踪系统

实现一个链路追踪系统,包括: 1. 链路数据收集 2. 链路数据存储 3. 链路可视化 4. 链路分析

12.7 面试准备

常见面试题

  1. 什么是监控?有哪些类型?
  2. 如何设计一个监控系统?
  3. 什么是链路追踪?如何实现?
  4. ELK Stack是什么?如何使用?
  5. 如何设计告警规则?

项目经验准备

准备一个监控项目: - 使用的监控技术 - 遇到的挑战 - 解决方案 - 项目成果

12.8 总结

本章介绍了监控与日志,包括监控指标、日志收集、链路追踪和告警。监控和日志是系统运维的重要组成部分。

关键要点

  1. 监控包括基础监控、应用监控、日志监控、链路追踪
  2. 监控指标包括CPU、内存、磁盘、网络
  3. 日志收集需要结构化和集中管理
  4. 链路追踪用于监控分布式系统
  5. 告警规则需要合理配置

下一步

下一章将深入学习安全架构,包括认证授权、数据加密等内容。