📈 第08章 · 日志收集管理

journalctl/logrotate/rsyslog

日志收集管理

这一章讲一台 Linux 服务器上日志的"全家桶":谁来写、谁来收、怎么集中、怎么轮转、怎么别把磁盘写满。监控和排查都依赖日志,但日志管理本身也常被忽略——直到磁盘被日志撑爆。

日志从哪来(三族)

来源 存放 查看方式
systemd journal 二进制,由 systemd 收集 journalctl
传统文本日志 /var/log/ 下各种 .log cat/tail/grep
业务自定义 应用/脚本自写日志 cat/tail/grep

本机例: - journalctl -u nginx 看 nginx(也写 /var/log/nginx/* 文本)。 - /var/log/nginx/learn.access.log(nginx 站点日志)。 - /var/log/mysql/(MySQL)。 - /var/log/tieba_sign.log、/var/log/monitor_report.log(cron 脚本自写)。

1) journalctl 统一管理 systemd 日志

# 服务日志
journalctl -u nginx
journalctl -u mysql -f              # 实时
# 时间过滤
journalctl --since "1 hour ago"
journalctl --since "yesterday" --until "now"
# 级别过滤(err 及以上)
journalctl -u mysql -p err
# 磁盘占用与清理
journalctl --disk-usage
journalctl --vacuum-time=14d        # 只留最近 14 天
journalctl --vacuum-size=1G         # 限制总大小 1G

注意 | journal 是二进制,普通 grep 读不了,必须 journalctl。默认 journal 有一定磁盘配额,过大会被 systemd 自动裁剪,也可能丢重要历史;--vacuum 可手动控制。

2) 传统文本日志与常见位置

路径 内容
/var/log/syslog 系统综合日志(老式非 systemd)
/var/log/auth.log 认证/登录(SSH/sudo 失败等)
/var/log/kern.log 内核日志
/var/log/nginx/access.log nginx 访问(按站点可分开)
/var/log/mysql/error.log MySQL 错误

3) logrotate:日志轮转(防止日志冲爆)

日志只增不减,必须轮转:到大小/时间就压缩归档、留 N 份。

全局配置 /etc/logrotate.conf,每个服务规则 /etc/logrotate.d/<名>。以本机 /var/log/nginx/ 和 Lua 示例:

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    weekly            # 每周
    missingok          # 文件不存在不报错
    rotate 8           # 保留 8 份历史
    compress           # 压缩成 .gz
    delaycompress      # 上一份先不压缩,方便立即查看
    notifempty         # 空文件不轮转
    create 640 www-data adm   # 新建日志文件的属主权限
    sharedscripts
    postrotate
        [ -f /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)   # 让 nginx 重新打开日志
    endscript
}

验证与强制轮转:

sudo logrotate -d /etc/logrotate.conf       # 干跑(dry-run),看会做什么
sudo logrotate -f /etc/logrotate.d/nginx    # 强制轮转一次

常见坑 | Nginx 写入的是一个"文件句柄",轮转把旧文件改名压缩后,nginx 还指向旧文件(占着磁盘)。所以必须在 postrotate 里让 nginx kill -USR1(reopen)重新打开新日志文件。其它服务类似原理。

4) 给业务自定义日志也配轮转

以本机 cron 脚本日志为例,建 /etc/logrotate.d/tieba:

/var/log/tieba_sign.log /var/log/monitor_report.log {
    daily
    rotate 14
    compress
    missingok
    notifempty
    copytruncate      # 复制后清空原文件,适用于无需重启服务的持续写
}

5) 集中收集(进阶:ELK / Loki / rsyslog)

单机日志分散多台时,需要集中:

方案 适合规模 优缺点
rsyslog 转发到中央 中小型、文本日志 简单,只传文本,非结构化
ELK(Elasticsearch+Logstash+Kibana) 大型、结构化检索 强大但重,资源消耗大
Grafana Loki + Promtail 与 Prometheus 生态接近 轻量,标签检索,配合 Grafana
Cloud 日志(如云商自带) 一机多用 免运维、只保留有限天数

建议 | 本机单主机的量,journalctl + logrotate + 文本日志足够,不必上 ELK。等规模扩大或需要全文检索,再考虑 Loki。

6) 日志"别写爆磁盘"的清单

df -h                                  # 看磁盘
du -sh /var/log/* | sort -rh | head    # 看哪个日志最大
journalctl --disk-usage                # journal 占多少

处理手段: - 加大/合理配置 logrotate 频率与保留份数。 - journalctl --vacuum-size=1G(限制 journal 上限)。 - 把 /var/log 放到空间大的分区(或单独挂载)。 - 关键日志别无限 tail -f;脚本日志用 >> 且配合 logrotate。

相关命令

  • journalctl(统一查看)、tail -F(跟随并处理轮转)、grep/awk(统计)。
  • logrotate -d/-f(模拟/强制轮转)、du -sh /var/log/* | sort -rh(找大日志)。
  • ls -lh /var/log/*.gz 看已压缩归档。