> Linux日志管理与分析:快速定位服务器问题

日志是排查问题的第一手线索

服务器出了问题,第一反应就是看日志。我处理过的90%的故障,都是通过日志找到原因的。会看日志,解决问题的速度能快十倍。

今天来系统梳理Linux的日志体系和分析方法。

Linux日志体系

日志文件位置

日志文件内容查看命令
/var/log/syslog系统综合日志tail -f /var/log/syslog
/var/log/auth.log认证日志(SSH登录等)grep "Failed" /var/log/auth.log
/var/log/kern.log内核日志tail /var/log/kern.log
/var/log/nginx/access.logNginx访问日志tail -f
/var/log/nginx/error.logNginx错误日志tail -f
/var/log/mysql/error.logMySQL错误日志tail
/var/log/apt/history.log软件安装历史cat
1
2
3
4
5
6
7
8
# 查看有哪些日志文件
$ ls -la /var/log/
total 12456
-rw-r--r-- 1 root   root    234567 Feb 12 10:00 syslog
-rw-r----- 1 root   adm      56789 Feb 12 10:00 auth.log
-rw-r--r-- 1 root   root     12345 Feb 12 09:00 kern.log
drwxr-xr-x 2 root   root      4096 Feb 12 10:00 nginx
-rw-r--r-- 1 root   root      8901 Feb 12 08:00 dpkg.log

journalctl:系统日志管理

systemd的日志系统,功能比直接看文件强大得多。

基本用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 查看所有日志(从最新的开始)
$ journalctl -r

# 查看最近的日志
$ journalctl -n 50   # 最近50条

# 实时跟踪日志
$ journalctl -f

# 查看特定服务的日志
$ journalctl -u nginx
Feb 12 10:00:01 server nginx[1234]: 2026/02/12 10:00:01 [notice] start worker processes
Feb 12 10:00:01 server nginx[1234]: 2026/02/12 10:00:01 [notice] start worker process 1235

$ journalctl -u mysql -f  # 实时跟踪MySQL日志

按时间过滤

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 今天的日志
$ journalctl --since today

# 最近1小时
$ journalctl --since "1 hour ago"

# 指定时间范围
$ journalctl --since "2026-02-12 08:00" --until "2026-02-12 10:00"

# 上次启动以来的日志
$ journalctl -b

# 上上次启动的日志
$ journalctl -b -1

按优先级过滤

级别数字含义
emerg0系统不可用
alert1需要立即处理
crit2严重错误
err3错误
warning4警告
notice5普通但重要
info6信息
debug7调试
1
2
3
4
5
6
7
# 只看错误及以上级别
$ journalctl -p err
Feb 12 03:15:23 server kernel: Out of memory: Killed process 1234 (mysql)
Feb 12 05:30:45 server nginx[5678]: [error] upstream timed out

# 只看严重错误
$ journalctl -p crit

日志占用空间管理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 查看日志占用空间
$ journalctl --disk-usage
Archived and active journals take up 1.5G in the file system.

# 限制日志大小
$ sudo journalctl --vacuum-size=500M
Vacuuming done, freed 1.0G of archived journals.

# 限制日志保留时间
$ sudo journalctl --vacuum-time=7d

# 永久配置
$ sudo vim /etc/systemd/journald.conf
SystemMaxUse=500M
MaxRetentionSec=1week

$ sudo systemctl restart systemd-journald

Nginx日志分析

访问日志格式

1
2
3
4
$ tail -5 /var/log/nginx/access.log
203.0.113.5 - - [12/Feb/2026:10:00:01 +0000] "GET /index.html HTTP/1.1" 200 1234 "-" "Mozilla/5.0"
198.51.100.3 - - [12/Feb/2026:10:00:02 +0000] "POST /api/login HTTP/1.1" 200 567 "https://example.com" "Mozilla/5.0"
192.0.2.100 - - [12/Feb/2026:10:00:03 +0000] "GET /notfound HTTP/1.1" 404 162 "-" "curl/7.88.1"

常用分析命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 统计HTTP状态码分布
$ awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
   15234 200
    2345 301
    1567 304
     890 404
      45 500

# 访问量Top 10 IP
$ awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
   5234 203.0.113.5
   3456 198.51.100.3
   1234 192.0.2.100

# 访问量Top 10 URL
$ awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
   8901 /
   5678 /api/data
   2345 /login
    890 /favicon.ico

# 统计每小时访问量
$ awk '{print $4}' /var/log/nginx/access.log | cut -d: -f1,2 | sort | uniq -c
    120 [12/Feb/2026:08
    350 [12/Feb/2026:09
    890 [12/Feb/2026:10

# 查找所有500错误
$ grep '" 500 ' /var/log/nginx/access.log
203.0.113.5 - - [12/Feb/2026:10:15:23 +0000] "GET /api/crash HTTP/1.1" 500 234

错误日志分析

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 查看最近的错误
$ tail -20 /var/log/nginx/error.log
2026/02/12 10:15:23 [error] 1234#0: *5678 upstream timed out (110: Connection timed out)
2026/02/12 10:20:45 [error] 1234#0: *5679 connect() failed (111: Connection refused)

# 统计错误类型
$ grep -oP '\[error\].*?(?=,)' /var/log/nginx/error.log | sort | uniq -c | sort -rn
   45 [error] upstream timed out
   23 [error] connect() failed
   12 [error] open() failed

logrotate:日志轮转

防止日志文件无限增长撑满磁盘。

默认配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily           # 每天轮转
    missingok       # 日志不存在也不报错
    rotate 14       # 保留14个
    compress        # 压缩旧日志
    delaycompress   # 延迟压缩
    notifempty      # 空文件不轮转
    create 0640 www-data adm  # 新文件的权限
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}

自定义logrotate配置

1
$ sudo vim /etc/logrotate.d/myapp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/var/log/myapp/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 0644 deploy deploy
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}
配置项作用常用值
daily/weekly/monthly轮转频率按需选择
rotate N保留份数7-30
compress压缩旧日志建议开启
maxsize 100M超过大小就轮转大日志文件
minsize 10M小于此不轮转避免过度轮转
1
2
3
4
5
6
# 手动触发轮转(测试配置)
$ sudo logrotate -f /etc/logrotate.d/nginx
$ ls -la /var/log/nginx/
-rw-r--r-- 1 www-data adm      0 Feb 12 10:30 access.log
-rw-r--r-- 1 www-data adm 123456 Feb 12 10:30 access.log.1
-rw-r--r-- 1 www-data adm  45678 Feb 11 10:30 access.log.2.gz

快速排查流程

服务器出问题时,我的排查流程:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 1. 看系统有没有严重错误
$ journalctl -p err --since "1 hour ago"

# 2. 看对应服务的日志
$ journalctl -u nginx --since "1 hour ago"

# 3. 看应用错误日志
$ tail -50 /var/log/nginx/error.log

# 4. 看系统资源情况(是不是OOM了)
$ journalctl -k | grep -i "out of memory"
$ dmesg | grep -i "oom"

# 5. 看登录日志(是不是被入侵了)
$ grep "Failed password" /var/log/auth.log | tail -20

总结

日志分析是运维的核心技能。记住三个关键工具:journalctl看系统日志,tail -f实时跟踪,grep/awk过滤分析。再配合logrotate做好日志轮转,就不用担心日志撑爆磁盘了。

更多文本处理技巧可以看grep、sed、awk实战。服务器监控工具推荐阅读监控工具对比

日志管理 Journalctl Logrotate
cd ..