日志管理 - Linux系统日志管理

1. 系统日志架构概述

在rhel7系统中有两个日志服务,分别是传统的rsyslog和新添加的systemd-journal。

1.1 日志服务对比

日志服务 说明 日志位置
rsyslog 传统的系统日志服务 /var/log/目录下各日志文件
systemd-journal systemd自带的日志服务 /run/log(默认,重启后丢失)

1.2 systemd-journald概述

systemd-journald是一个改进型的日志管理服务,可以收集来自内核、系统早期的启动阶段的日志、系统守护进程在启动和运行中的标准输出和错误信息,还有syslog的日志。

特点:

  • 该日志服务仅仅把日志集中保存在单一结构化的日志文件/run/log
  • 默认情况下并不会持久化保存日志, 每次重启后, 之前的日志都会丢失
  • 一些rsyslog无法收集的日志也会被journal记录到

1.3 rsyslog概述

rsyslog作为传统的系统日志服务,把所有收集到的日志都记录到/var/log/目录下的各个日志文件中。

常见的日志文件:

日志文件 说明
/var/log/messages 绝大多数的系统日志都记录到此文件
/var/log/secure 所有跟安全和认证授权等日志都会记录到此文件
/var/log/maillog 邮件服务的日志
/var/log/cron crond计划任务的日志
/var/log/boot.log 系统启动的相关日志

1.4 日志服务关系

1
2
3
4
5
6
7
应用程序/服务

systemd-journald (收集日志)

rsyslog (处理并分类存储)

/var/log/ (日志文件)

2. syslog日志审查

2.1 rsyslog.conf配置文件

rsyslog的配置文件位于/etc/rsyslog.conf

1
2
3
4
5
# 查看rsyslog配置文件
cat /etc/rsyslog.conf

# 查看rsyslog配置目录
ls /etc/rsyslog.d/

2.2 syslog日志类型

syslog日志的属性(优先级从高到低):

优先级 数值 说明
emerg 0 内核崩溃,系统不可用
alert 1 需要立即采取行动
crit 2 严重错误
err 3 错误
warning 4 警告
notice 5 通知
info 6 信息
debug 7 调试信息

2.3 syslog日志设施

设施 说明
kern 内核消息
user 用户级消息
mail 邮件系统
daemon 系统守护进程
auth 安全/认证消息
syslog syslogd内部消息
lpr 行式打印机子系统
news 网络新闻子系统
cron cron守护进程
local0-local7 本地使用

2.4 看懂简单的日志设定规则

rsyslog配置格式:

1
facility.priority    target

示例:

1
2
3
4
5
6
7
8
9
10
11
# 所有设施的所有级别日志都记录到messages
*.* /var/log/messages

# 所有认证相关的info及以上级别日志记录到secure
authpriv.* /var/log/secure

# mail服务的所有日志记录到maillog
mail.* /var/log/maillog

# cron服务的所有日志记录到cron
cron.* /var/log/cron

2.5 分析日志字段

日志格式示例:

1
Mar 18 21:37:04 liyanzhao test: Err

日志字段说明:

字段 说明 示例
时间戳 日志产生的时间 Mar 18 21:37:04
主机名 产生日志的主机 liyanzhao
程序名 产生日志的程序 test
消息内容 日志的具体内容 Err

2.6 手工发送日志logger

使用logger命令可以手动发送日志到syslog。

1
2
3
4
5
6
# 发送日志
[root@liyanzhao ~]# logger -p authpriv.info -t "test" "Err"

# 查看日志
[root@liyanzhao ~]# tail -n1 /var/log/secure
Mar 18 21:37:04 liyanzhao test: Err

logger常用选项

选项 功能 示例
-p 指定优先级 -p authpriv.info
-t 指定标签 -t "test"
-i 记录进程ID -i
-f 从文件读取 -f /path/to/file

logger示例

1
2
3
4
5
6
7
8
9
10
11
# 发送info级别日志
logger -p user.info "This is an info message"

# 发送带标签的日志
logger -t "myapp" "Application started"

# 发送带进程ID的日志
logger -i -t "myapp" "Process message"

# 从文件读取并发送
logger -f /var/log/app.log

3. Journal日志审查

这是systemd自带的日志服务工具,所有日志记录到/run/log文件中, 必须使用如下命令才可打开。

3.1 journalctl基本命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 查看所有的日志
journalctl

# 查看最后5条日志
journalctl -n 5

# 查看err类型的日志
journalctl -p err

# 不断输出最后10条日志
journalctl -f

# 查看今天的日志
journalctl --since today

# 查看指定时间范围的日志
journalctl --since "2014-02-10 20:30:00" --until "2014-02-13 12:00:00"

# 查看日志的详细信息
journalctl -o verbose

# 查看特定服务的日志
journalctl _SYSTEMD_UNIT=sshd.service _PID=1182

3.2 journalctl常用选项

选项 功能 示例
-n 显示最后N条日志 journalctl -n 20
-f 实时跟踪日志 journalctl -f
-p 按优先级过滤 journalctl -p err
--since 从指定时间开始 journalctl --since today
--until 到指定时间结束 journalctl --until "2024-02-17"
-o 指定输出格式 journalctl -o verbose
-u 按服务单元过滤 journalctl -u sshd.service
_SYSTEMD_UNIT 按服务单元过滤 journalctl _SYSTEMD_UNIT=sshd
_PID 按进程ID过滤 journalctl _PID=1182

3.3 journalctl输出格式

格式 说明 示例
short 默认格式 journalctl -o short
verbose 详细信息 journalctl -o verbose
json JSON格式 journalctl -o json
cat 简洁格式 journalctl -o cat

3.4 journalctl实战示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 查看系统启动日志
journalctl -b

# 查看最近1小时的日志
journalctl --since "1 hour ago"

# 查看特定服务的日志
journalctl -u nginx.service

# 查看特定时间段的日志
journalctl --since "2024-02-17 00:00:00" --until "2024-02-17 23:59:59"

# 查看错误及以上级别的日志
journalctl -p err

# 实时跟踪系统日志
journalctl -f

# 查看内核日志
journalctl -k

# 查看特定用户的日志
journalctl _UID=1000

4. Journal日志持久化

持久化保存journal的日志,默认只会保存一个月的日志。

4.1 配置Journal日志持久化

步骤1: 创建日志目录

1
2
# 创建journal日志目录
mkdir /var/log/journal

步骤2: 设置权限

1
2
3
4
5
# 设置所有者和组
chown root:systemd-journal /var/log/journal

# 设置权限(2755表示设置SGID位)
chmod 2755 /var/log/journal

步骤3: 重启journald服务

1
2
3
4
5
# 重启systemd-journald服务
killall -USR1 systemd-journald

# 或使用systemctl
systemctl restart systemd-journald

4.2 验证持久化

1
2
3
4
5
# 查看journal日志位置
journalctl --list-boots

# 查看持久化日志
ls -l /var/log/journal/

4.3 配置Journal日志大小限制

1
2
3
4
5
6
7
8
# 编辑journald配置文件
vim /etc/systemd/journald.conf

# 设置日志最大大小
SystemMaxUse=500M
SystemKeepFree=1G
SystemMaxFileSize=100M
MaxRetentionSec=30day

4.4 Journal配置文件说明

/etc/systemd/journald.conf主要配置项:

配置项 说明 默认值
Storage 日志存储方式 auto
SystemMaxUse 系统日志最大使用空间
SystemKeepFree 系统保留空间
SystemMaxFileSize 单个日志文件最大大小
MaxRetentionSec 日志保留时间

5. 日志轮询logrotate

5.1 logrotate概述

logrotate是一个日志管理工具,用于对日志文件进行轮转、压缩、删除和邮件通知。

5.2 logrotate配置文件

主配置文件

1
2
3
4
5
# 主配置文件
/etc/logrotate.conf

# 配置目录
/etc/logrotate.d/

主配置文件示例

1
2
3
4
5
6
7
# /etc/logrotate.conf
weekly # 每周轮转
rotate 4 # 保留4个备份
create # 创建新文件
dateext # 使用日期作为后缀
compress # 压缩旧日志
include /etc/logrotate.d # 包含其他配置

5.3 logrotate配置示例

示例1: Nginx日志轮转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}

示例2: 系统日志轮转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# /etc/logrotate.d/syslog
/var/log/messages
/var/log/secure
/var/log/maillog
/var/log/spooler
/var/log/boot.log
/var/log/cron
{
daily
rotate 7
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}

5.4 logrotate配置参数

参数 说明 示例
daily 每天轮转 daily
weekly 每周轮转 weekly
monthly 每月轮转 monthly
rotate N 保留N个备份 rotate 7
compress 压缩旧日志 compress
delaycompress 延迟压缩 delaycompress
missingok 日志不存在不报错 missingok
notifempty 空日志不轮转 notifempty
create 创建新文件 create 0640 user group
size 按大小轮转 size 100M
postrotate 轮转后执行的命令 postrotate ... endscript
prerotate 轮转前执行的命令 prerotate ... endscript

5.5 手动执行logrotate

1
2
3
4
5
6
7
8
# 测试logrotate配置(不实际执行)
logrotate -d /etc/logrotate.conf

# 强制执行logrotate
logrotate -f /etc/logrotate.conf

# 指定配置文件测试
logrotate -d /etc/logrotate.d/nginx

5.6 logrotate实战案例

案例1: 应用日志轮转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0644 appuser appgroup
sharedscripts
postrotate
/bin/kill -USR1 `cat /var/run/myapp.pid 2> /dev/null` 2> /dev/null || true
endscript
}

案例2: 大日志文件轮转

1
2
3
4
5
6
7
8
9
10
# /etc/logrotate.d/large-log
/var/log/large.log {
size 500M
rotate 5
compress
delaycompress
missingok
notifempty
create 0644 root root
}

6. 日志管理最佳实践

6.1 日志收集建议

  1. 集中管理: 使用日志收集工具(如ELK、Graylog)集中管理
  2. 分类存储: 不同类型的日志分类存储
  3. 定期清理: 定期清理旧日志,避免占满磁盘
  4. 监控告警: 对关键日志设置监控告警

6.2 日志轮转建议

  1. 合理设置保留时间: 根据需求设置日志保留时间
  2. 压缩旧日志: 启用压缩节省空间
  3. 按大小和时间轮转: 结合使用size和daily等参数
  4. 测试配置: 使用-d参数测试配置

6.3 日志安全建议

  1. 权限控制: 设置合理的日志文件权限
  2. 敏感信息: 避免在日志中记录敏感信息
  3. 日志完整性: 确保日志不被篡改
  4. 备份日志: 重要日志定期备份

7. 日志分析工具

7.1 常用日志分析命令

命令 功能 示例
tail -f 实时查看日志 tail -f /var/log/messages
grep 搜索日志 grep "error" /var/log/messages
awk 分析日志 awk '{print $1}' /var/log/messages
sed 处理日志 sed -n '1,100p' /var/log/messages
less 分页查看 less /var/log/messages

7.2 日志分析示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 统计错误日志数量
grep -i error /var/log/messages | wc -l

# 查看最近的错误日志
grep -i error /var/log/messages | tail -20

# 按时间范围查找日志
grep "2024-02-17" /var/log/messages

# 统计IP访问次数
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# 查找特定服务的日志
journalctl -u nginx.service --since today

8. 日志故障排查

8.1 常见问题

问题1: 日志文件过大

1
2
3
4
5
6
7
8
# 检查日志文件大小
du -sh /var/log/*

# 使用logrotate轮转
logrotate -f /etc/logrotate.conf

# 手动清理(谨慎操作)
> /var/log/messages

问题2: 日志丢失

1
2
3
4
5
6
7
8
# 检查journal日志是否持久化
ls -l /var/log/journal/

# 检查rsyslog服务状态
systemctl status rsyslog

# 检查磁盘空间
df -h /var/log

问题3: 日志权限问题

1
2
3
4
5
6
# 检查日志文件权限
ls -l /var/log/

# 修复权限
chmod 640 /var/log/messages
chown root:root /var/log/messages

9. 命令总结

9.1 日志查看命令

命令 功能 示例
journalctl 查看journal日志 journalctl
journalctl -f 实时查看日志 journalctl -f
journalctl -u 查看服务日志 journalctl -u sshd
tail -f 实时查看文件日志 tail -f /var/log/messages
less 分页查看日志 less /var/log/messages

9.2 日志管理命令

命令 功能 示例
logger 发送日志 logger -p user.info "message"
logrotate 日志轮转 logrotate -f /etc/logrotate.conf
systemctl status rsyslog 查看rsyslog状态 systemctl status rsyslog
systemctl restart rsyslog 重启rsyslog systemctl restart rsyslog

9.3 日志分析命令

命令 功能 示例
grep 搜索日志 grep "error" /var/log/messages
awk 分析日志 awk '{print $1}' /var/log/messages
sed 处理日志 sed -n '1,100p' /var/log/messages
wc -l 统计行数 grep error /var/log/messages | wc -l

10. 实战案例

10.1 案例1: 配置Nginx日志轮转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 创建logrotate配置
cat > /etc/logrotate.d/nginx <<EOF
/var/log/nginx/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 \$(cat /var/run/nginx.pid)
fi
endscript
}
EOF

# 测试配置
logrotate -d /etc/logrotate.d/nginx

# 手动执行
logrotate -f /etc/logrotate.d/nginx

10.2 案例2: 配置MySQL日志轮转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建MySQL日志轮转配置
cat > /etc/logrotate.d/mysql <<EOF
/var/log/mysql/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 mysql mysql
sharedscripts
postrotate
if [ -f /var/run/mysqld/mysqld.pid ]; then
kill -HUP \$(cat /var/run/mysqld/mysqld.pid)
fi
endscript
}
EOF

10.3 案例3: 集中日志收集脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# 日志收集脚本
# 功能: 收集系统关键日志并发送到日志服务器

LOG_SERVER="192.168.1.100"
LOG_PORT="514"

# 收集系统日志
tail -n 100 /var/log/messages | logger -n ${LOG_SERVER} -P ${LOG_PORT}

# 收集安全日志
tail -n 100 /var/log/secure | logger -n ${LOG_SERVER} -P ${LOG_PORT}

# 收集应用日志
tail -n 100 /var/log/myapp/app.log | logger -n ${LOG_SERVER} -P ${LOG_PORT}

11. 日志监控和告警

11.1 日志监控脚本

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
# 日志监控脚本
# 功能: 监控错误日志并发送告警

LOG_FILE="/var/log/messages"
ERROR_COUNT=$(grep -i error ${LOG_FILE} | wc -l)
THRESHOLD=100

if [ ${ERROR_COUNT} -gt ${THRESHOLD} ]; then
echo "警告: 错误日志数量超过阈值 (${ERROR_COUNT})" | mail -s "日志告警" admin@example.com
fi

11.2 计划任务配置

1
2
# 每5分钟检查一次日志
*/5 * * * * /usr/bin/bash /soft/scripts/log_monitor.sh

实战优化