繁华依在的小站

🔍 日志管理与监控:做网站的"侦探",洞察一切

技术 作者:admin | 发布时间:2026-02-03 16:17 | 更新时间:2026-04-09 00:26 | 阅读:14 |
标签: 日志 监控 系统运维 ELK Grafana 报警

🔍 日志管理与监控:做网站的"侦探",洞察一切

网站出问题了?慢了?挂了?别慌,日志会告诉你真相!

今天我们来学习如何成为一名优秀的"网站侦探" 🕵️‍♂️


🎯 为什么需要日志和监控?

想象一下:

text
1没有日志 = 盲人摸象
2  - 不知道发生了什么
3  - 出问题无从查起
4  - 用户投诉才发现问题
5
6有日志 = 开启上帝视角 👁️
7  - 知道发生了什么
8  - 提前发现问题
9  - 主动优化性能

📊 日志的层次

应用层日志

text
1Flask/Gunicorn 日志
2  ├─ 访问日志:谁在什么时候访问了什么
3  ├─ 错误日志:出了什么问题
4  └─ 性能日志:响应时间有多长

系统层日志

text
1Systemd 日志
2  ├─ 服务启动/停止
3  ├─ 进程崩溃记录
4  └─ 资源使用情况

网络层日志

text
1Nginx 日志
2  ├─ 请求详情
3  ├─ 响应状态
4  └─ 转发记录

🗂️ 第一步:配置访问日志

Nginx 访问日志

/etc/nginx/nginx.conf

nginx
 1http {
 2    # 自定义日志格式
 3    log_format main '$remote_addr - $remote_user [$time_local] '
 4                    '"$request" $status $body_bytes_sent '
 5                    '"$http_referer" "$http_user_agent" '
 6                    '$request_time $upstream_response_time '
 7                    '$upstream_addr $upstream_status';
 8
 9    # 访问日志
10    access_log /var/log/nginx/access.log main;
11
12    # 错误日志
13    error_log /var/log/nginx/error.log warn;
14}

日志字段说明

字段 说明 示例
$remote_addr 客户端 IP 192.168.1.100
$request 请求行 GET /api/posts HTTP/1.1
$status 状态码 200
$request_time 总请求时间 0.523
$upstream_response_time 后端响应时间 0.500

Gunicorn 访问日志

gunicorn_config.py

python
 1import multiprocessing
 2
 3# 日志配置
 4loglevel = "info"
 5
 6# 访问日志
 7accesslog = "logs/gunicorn_access.log"
 8
 9# 错误日志
10errorlog = "logs/gunicorn_error.log"
11
12# 自定义日志格式
13access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'

字段说明

  • %(h)s:客户端 IP
  • %(r)s:请求行
  • %(s)s:状态码
  • %(D)s:请求时间(微秒)

Flask 应用日志

app.py

python
 1import logging
 2from logging.handlers import RotatingFileHandler
 3
 4# 配置日志
 5if not os.path.exists('logs'):
 6    os.mkdir('logs')
 7
 8# 文件日志
 9file_handler = RotatingFileHandler(
10    'logs/app.log',
11    maxBytes=10240000,  # 10MB
12    backupCount=10
13)
14file_handler.setFormatter(logging.Formatter(
15    '%(asctime)s %(levelname)s: %(message)s'
16))
17file_handler.setLevel(logging.INFO)
18
19# 控制台日志
20stream_handler = logging.StreamHandler()
21stream_handler.setLevel(logging.INFO)
22
23# 添加到 Flask
24app.logger.addHandler(file_handler)
25app.logger.addHandler(stream_handler)
26app.logger.setLevel(logging.INFO)
27
28# 使用日志
29app.logger.info('应用启动')
30app.logger.error('数据库连接失败')

📈 第二步:日志分析

实时查看

bash
1# 查看最新日志
2tail -f /var/log/nginx/access.log
3
4# 查看最后 50 行
5tail -n 50 /var/log/nginx/access.log
6
7# 查看并高亮错误
8tail -f /var/log/nginx/error.log | grep --color=auto "error"

统计访问量

bash
 1# 统计总访问量
 2wc -l /var/log/nginx/access.log
 3
 4# 按小时统计
 5awk '{print $4}' /var/log/nginx/access.log | \
 6  cut -d: -f2 | sort | uniq -c
 7
 8# 统计独立 IP
 9awk '{print $1}' /var/log/nginx/access.log | \
10  sort | uniq | wc -l

统计状态码

bash
1# 状态码分布
2awk '{print $9}' /var/log/nginx/access.log | \
3  sort | uniq -c | sort -rn
4
5# 输出示例:
6#  15000 200
7#    500 404
8#    100 500
9#     50 301

找出慢请求

bash
1# 响应时间 > 1 秒的请求
2awk -F'"' '$(NF-1) > 1.0 {print $0}' /var/log/nginx/access.log
3
4# 按 IP 统计慢请求
5awk -F'"' '$(NF-1) > 1.0 {print $1}' /var/log/nginx/access.log | \
6  sort | uniq -c | sort -rn | head -10

找出热门 URL

bash
1# 访问最多的页面
2awk '{print $7}' /var/log/nginx/access.log | \
3  sort | uniq -c | sort -rn | head -20
4
5# 输出示例:
6#   5000 /api/posts
7#   3000 /
8#   2000 /about

🔥 第三步:错误日志分析

分析 Nginx 错误

bash
1# 查看最近的错误
2tail -100 /var/log/nginx/error.log
3
4# 统计错误类型
5awk '{print $2}' /var/log/nginx/error.log | \
6  sort | uniq -c | sort -rn

常见错误

错误 原因 解决方案
upstream timed out 后端响应慢 增加 proxy_read_timeout
connect() failed 后端服务挂了 重启后端服务
directory index of 找不到首页 检查 index 配置

分析 Gunicorn 错误

bash
1# 查看 Gunicorn 错误日志
2tail -f logs/gunicorn_error.log
3
4# 统计错误类型
5grep ERROR logs/gunicorn_error.log | \
6  awk '{print $3}' | sort | uniq -c

🔄 第四步:日志轮转

为什么需要轮转?

text
1不轮转 = 💣 炸弹
2  - 日志文件无限增长
3  - 磁盘被占满
4  - 系统崩溃
5
6轮转 = ✅ 安全
7  - 定期归档旧日志
8  - 压缩节省空间
9  - 自动删除过期日志

Logrotate 配置

/etc/logrotate.d/flask-blog

bash
 1/var/www/blog/logs/*.log {
 2    daily           # 每天轮转
 3    missingok       # 文件不存在不报错
 4    rotate 14       # 保留 14 天
 5    compress        # 压缩旧日志
 6    delaycompress   # 延迟一天压缩
 7    notifempty      # 空文件不轮转
 8    create 0644 www-data www-data
 9    sharedscripts
10    postrotate
11        # 重启应用(如果需要)
12        systemctl reload flask-blog > /dev/null 2>&1 || true
13    endscript
14}

Nginx 日志轮转

/etc/logrotate.d/nginx

bash
 1/var/log/nginx/*.log {
 2    daily
 3    missingok
 4    rotate 14
 5    compress
 6    delaycompress
 7    notifempty
 8    create 0640 nginx nginx
 9    sharedscripts
10    prerotate
11        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
12            run-parts /etc/logrotate.d/httpd-prerotate; \
13        fi
14    endscript
15    postrotate
16        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
17    endscript
18}

测试 Logrotate

bash
1# 调试模式(不实际执行)
2sudo logrotate -d /etc/logrotate.d/flask-blog
3
4# 强制执行
5sudo logrotate -f /etc/logrotate.d/flask-blog

📊 第五步:监控指标

系统资源监控

bash
 1# CPU 和内存使用
 2htop
 3
 4# 磁盘使用
 5df -h
 6
 7# 进程监控
 8ps aux | grep gunicorn
 9
10# 网络连接
11netstat -anp | grep :5000

应用性能监控

bash
 1# 统计平均响应时间
 2awk -F'"' '{print $(NF-1)}' /var/log/nginx/access.log | \
 3  awk '{sum+=$1; count++} END {print sum/count}'
 4
 5# 统计 QPS(每秒请求数)
 6awk '{print $4}' /var/log/nginx/access.log | \
 7  cut -d: -f2 | sort | uniq -c
 8
 9# 统计并发数
10netstat -an | grep :5000 | grep ESTABLISHED | wc -l

自定义监控脚本

monitor.sh

bash
 1#!/bin/bash
 2
 3# 颜色定义
 4GREEN='\033[0;32m'
 5RED='\033[0;31m'
 6NC='\033[0m'
 7
 8# 检查服务状态
 9check_service() {
10    if systemctl is-active --quiet "$1"; then
11        echo -e "${GREEN}$1 运行中${NC}"
12    else
13        echo -e "${RED}$1 已停止${NC}"
14    fi
15}
16
17# 检查端口
18check_port() {
19    if netstat -tuln | grep -q ":$1 "; then
20        echo -e "${GREEN}✓ 端口 $1 监听中${NC}"
21    else
22        echo -e "${RED}✗ 端口 $1 未监听${NC}"
23    fi
24}
25
26# 检查磁盘空间
27check_disk() {
28    USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
29    if [ $USAGE -gt 80 ]; then
30        echo -e "${RED}⚠ 磁盘使用: ${USAGE}%${NC}"
31    else
32        echo -e "${GREEN}✓ 磁盘使用: ${USAGE}%${NC}"
33    fi
34}
35
36# 主函数
37main() {
38    echo "=== 系统监控 $(date) ==="
39    echo ""
40    echo "服务状态:"
41    check_service "flask-blog"
42    check_service "nginx"
43    check_service "frpc"
44    echo ""
45    echo "端口检查:"
46    check_port 5000
47    check_port 80
48    echo ""
49    check_disk
50    echo ""
51}
52
53main

🚨 第六步:告警系统

简单告警脚本

alert.sh

bash
 1#!/bin/bash
 2
 3# 阈值
 4CPU_THRESHOLD=80
 5DISK_THRESHOLD=80
 6MEMORY_THRESHOLD=80
 7
 8# 检查 CPU
 9CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
10if (( $(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc -l) )); then
11    echo "⚠️ CPU 使用率过高: ${CPU_USAGE}%" | mail -s "告警" admin@example.com
12fi
13
14# 检查磁盘
15DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
16if [ $DISK_USAGE -gt $DISK_THRESHOLD ]; then
17    echo "⚠️ 磁盘使用率过高: ${DISK_USAGE}%" | mail -s "告警" admin@example.com
18fi

系统级监控工具

1. Monit

bash
 1# 安装
 2sudo apt install monit -y
 3
 4# 配置
 5sudo tee /etc/monit/monitrc.d/flask-blog > /dev/null << 'EOF'
 6check process flask-blog matching gunicorn
 7    start program = "/bin/systemctl start flask-blog"
 8    stop program = "/bin/systemctl stop flask-blog"
 9    if failed port 5000 protocol http then restart
10    if 5 restarts within 5 cycles then timeout
11EOF
12
13# 启动
14sudo systemctl enable monit
15sudo systemctl start monit

2. Prometheus + Grafana

架构

text
1应用 → Exporter → Prometheus → Grafana

安装 Prometheus

bash
 1# 安装
 2sudo apt install prometheus -y
 3
 4# 配置目标
 5sudo tee /etc/prometheus/prometheus.yml > /dev/null << 'EOF'
 6global:
 7  scrape_interval: 15s
 8
 9scrape_configs:
10  - job_name: 'node'
11    static_configs:
12      - targets: ['localhost:9100']
13EOF
14
15# 启动
16sudo systemctl enable prometheus
17sudo systemctl start prometheus

📱 第七步:可视化监控

Grafana Dashboard

bash
 1# 安装 Grafana
 2sudo apt install grafana -y
 3
 4# 启动
 5sudo systemctl enable grafana-server
 6sudo systemctl start grafana-server
 7
 8# 访问
 9http://localhost:3000
10# 默认用户名/密码:admin/admin

常用指标面板

  • QPS(每秒请求数)
  • 响应时间
  • 错误率
  • CPU 使用率
  • 内存使用率
  • 磁盘使用率
  • 网络流量

🔍 第八步:实战案例

场景:网站突然变慢

步骤 1:检查系统资源

bash
1htop
2# 发现:CPU 100%,内存正常

步骤 2:查看日志

bash
1tail -f /var/log/nginx/access.log
2# 发现:大量请求到同一个 URL

步骤 3:分析请求

bash
1awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -5
2# 发现:/api/heavy 被频繁访问

步骤 4:定位问题

bash
1# 查看 Gunicorn 日志
2tail -f logs/gunicorn_error.log
3# 发现:数据库查询很慢

解决方案

python
1# 添加缓存
2@lru_cache(maxsize=128)
3def heavy_computation():
4    # ... 耗时操作
5    pass

📋 监控检查清单

基础监控

  • [ ] 访问日志正常记录
  • [ ] 错误日志正常记录
  • [ ] 日志轮转已配置
  • [ ] 磁盘空间监控

应用监控

  • [ ] 服务状态监控
  • [ ] 响应时间监控
  • [ ] 错误率监控
  • [ ] 并发数监控

告警配置

  • [ ] 服务停止告警
  • [ ] 磁盘满告警
  • [ ] 高负载告警
  • [ ] 异常错误告警

🎉 总结

日志和监控的重要性:

  1. 发现问题 → 从用户抱怨到主动发现
  2. 定位问题 → 快速找到根本原因
  3. 预防问题 → 提前发现趋势
  4. 优化性能 → 数据驱动优化

记住:

"没有监控的系统就像盲人开夜车,迟早要出事!" 🚗💥


🔗 相关工具

  • 日志管理:Logstash, Fluentd, Filebeat
  • 监控系统:Prometheus, Zabbix, Nagios
  • 可视化:Grafana, Kibana
  • APM:New Relic, Datadog, Sentry

下一篇:自动化备份策略,别让你的数据丢了!💾

评论 (0)

暂无评论,快来抢沙发吧~

发表评论