# 日志管理（journalctl）

URL: https://caijiao.org/rockylinux/log-management
Source: docs/rockylinux/log-management.md
Description: 详细介绍 Rocky Linux 中使用 journalctl 命令管理和查询 systemd 日志的方法，包括日志查看、过滤、导出等操作

在现代 Linux 系统中，日志管理是系统管理和故障排查的重要组成部分。从 Rocky Linux 8 开始，系统默认使用 systemd 的日志系统（journald）来管理系统日志，而 journalctl 命令则是用于查询和管理这些日志的主要工具。本教程将详细介绍如何使用 journalctl 命令有效地管理和分析系统日志。

## systemd 日志系统概述

systemd 日志系统由两个主要组件组成：

1. **journald**：一个系统服务，负责收集和存储日志数据
2. **journalctl**：一个命令行工具，用于查询和显示日志数据

与传统的 syslog 系统相比，systemd 日志系统有以下优势：

- **二进制格式存储**：提高了日志的写入和查询性能
- **结构化数据**：每条日志包含元数据（如用户 ID、进程 ID、优先级等）
- **跨系统兼容性**：日志格式在不同系统上保持一致
- **自动轮转和压缩**：内置日志管理功能
- **支持多种日志源**：包括内核、系统服务、用户进程等

## journalctl 基本用法

### 查看所有日志

```bash
# 查看所有日志（默认按时间倒序）
journalctl

# 查看所有日志（按时间正序）
journalctl --no-pager
```

### 分页显示控制

```bash
# 不分页显示
journalctl --no-pager

# 控制分页器
journalctl | less
```

### 查看最新的日志条目

```bash
# 查看最新的 10 行日志
journalctl -n 10

# 持续显示新的日志（类似 tail -f）
journalctl -f

# 持续显示新的日志，显示更多上下文
journalctl -f -n 50
```

## 按时间过滤日志

### 查看特定时间范围的日志

```bash
# 查看今天的日志
journalctl --since "today"

# 查看昨天的日志
journalctl --since "yesterday" --until "today"

# 查看特定日期的日志
journalctl --since "2023-01-01" --until "2023-01-02"

# 查看特定时间范围的日志
journalctl --since "10:00" --until "11:30"

# 查看过去 24 小时的日志
journalctl --since "24 hours ago"

# 查看过去 1 小时内的日志
journalctl --since "1 hour ago"
```

## 按服务和单元过滤日志

### 查看特定服务的日志

```bash
# 查看特定服务的日志（例如 sshd）
journalctl -u sshd.service

# 查看多个服务的日志
journalctl -u sshd.service -u httpd.service

# 查看服务的最新日志
journalctl -u sshd.service -n

# 持续查看服务的新日志
journalctl -u sshd.service -f
```

### 查看系统启动的日志

```bash
# 查看当前启动的日志
journalctl -b

# 查看前一次启动的日志
journalctl -b -1

# 查看特定启动的日志（通过 boot ID）
journalctl -b <boot_id>

# 列出所有可用的启动记录
journalctl --list-boots
```

## 按优先级过滤日志

### 按日志优先级查看

```bash
# 查看错误级别及以上的日志
journalctl -p err

# 查看特定优先级范围的日志
journalctl -p 3..5

# 查看紧急级别日志
journalctl -p emerg
```

### 日志优先级级别

systemd 使用的日志优先级从高到低依次为：

- **emerg (0)**：紧急情况，系统不可用
- **alert (1)**：必须立即采取行动
- **crit (2)**：严重错误
- **err (3)**：一般错误
- **warning (4)**：警告
- **notice (5)**：普通但重要的信息
- **info (6)**：信息性消息
- **debug (7)**：调试信息

## 按进程和用户过滤日志

### 按进程 ID 过滤

```bash
# 查看特定进程的日志
journalctl _PID=1234

# 查看特定可执行文件的日志
journalctl /usr/bin/sshd
```

### 按用户 ID 或名称过滤

```bash
# 按用户 ID 过滤
journalctl _UID=1000

# 按用户名称过滤
journalctl USER=username
```

### 按组过滤

```bash
# 按组 ID 过滤
journalctl _GID=1000

# 按组名称过滤
journalctl GROUP=groupname
```

## 高级过滤选项

### 按系统字段过滤

```bash
# 按设备过滤
journalctl _DEVICE=sda

# 按子系统过滤
journalctl _SUBSYSTEM=block

# 按机器 ID 过滤
journalctl _MACHINE_ID=machine_id
```

### 按消息内容过滤

```bash
# 按消息内容搜索（使用 grep）
journalctl | grep "error"

# 按消息内容搜索并显示上下文
journalctl | grep -A 5 -B 5 "error"

# 使用 journalctl 的搜索功能
journalctl -g "error"
```

### 组合多个过滤条件

```bash
# 组合多个过滤条件
journalctl -u sshd.service --since "today" -p err

# 显示特定时间范围内的错误日志
journalctl --since "1 hour ago" -p err..emerg
```

## 日志格式控制

### 更改日志输出格式

```bash
# 以简洁格式显示
journalctl --no-full

# 以 JSON 格式显示
journalctl -o json

# 以 JSON 格式（单行）显示
journalctl -o json-pretty

# 以可读格式显示所有字段
journalctl -o verbose

# 以传统 syslog 格式显示
journalctl -o short

# 以不包含主机名的格式显示
journalctl -o short-monotonic

# 以经典 syslog 格式显示
journalctl -o syslog
```

### 显示日志字段

```bash
# 显示所有可用字段
journalctl -o verbose | grep -E "^\s+\w+="

# 自定义输出字段
journalctl -o verbose | awk '/MESSAGE=/{print $0} /PRIORITY=/{print $0}'
```

## 日志管理

### 查看日志使用情况

```bash
# 查看日志占用的磁盘空间
journalctl --disk-usage

# 查看日志统计信息
journalctl --header
```

### 清理旧日志

```bash
# 保留最近 2 天的日志
journalctl --vacuum-time=2d

# 保留最近 500MB 的日志
journalctl --vacuum-size=500M

# 保留最近 10000 条日志条目
journalctl --vacuum-files=10000
```

### 配置日志保留策略

编辑 journald 配置文件：

```bash
sudo vim /etc/systemd/journald.conf
```

主要配置选项：

```
[Journal]
# 日志文件的最大大小
SystemMaxFileSize=100M

# 所有日志文件的总大小限制
SystemMaxUse=500M

# 单个用户日志的大小限制
RuntimeMaxUse=100M

# 日志保留的最大时间
MaxRetentionSec=1month

# 同步写入磁盘的间隔
SyncIntervalSec=5m

# 是否压缩旧日志
Compress=yes

# 是否自动轮转日志
AutoRotate=yes
```

修改配置后需要重启 journald 服务：

```bash
sudo systemctl restart systemd-journald
```

## 日志持久化

### 配置日志持久化

默认情况下，journald 可能只在内存中存储日志或限制磁盘日志的大小。要启用完全的日志持久化：

1. 创建持久化日志目录：

```bash
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
```

2. 设置正确的权限：

```bash
sudo chown root:systemd-journal /var/log/journal
sudo chmod 2755 /var/log/journal
```

3. 编辑 journald 配置文件：

```bash
sudo vim /etc/systemd/journald.conf
```

确保以下设置：

```
[Journal]
Storage=persistent
```

4. 重启 journald 服务：

```bash
sudo systemctl restart systemd-journald
```

## 导出和归档日志

### 导出日志

```bash
# 导出特定时间范围的日志到文件
journalctl --since "2023-01-01" --until "2023-01-02" > logs.txt

# 导出为二进制格式
journalctl --since "2023-01-01" --until "2023-01-02" -o export > logs.journal

# 导出特定服务的日志
journalctl -u sshd.service --since "today" > sshd_logs.txt
```

### 从导出的日志中恢复数据

```bash
# 从二进制日志文件中读取
journalctl --file=logs.journal

# 从多个二进制日志文件中读取
journalctl --file=logs1.journal --file=logs2.journal
```

## 与传统 syslog 的集成

### 安装和配置 rsyslog

虽然 systemd journal 已经提供了强大的日志功能，但您仍然可以安装 rsyslog 以兼容传统的日志管理工具：

```bash
# 安装 rsyslog
sudo dnf install rsyslog -y

# 启动 rsyslog 服务
sudo systemctl start rsyslog
sudo systemctl enable rsyslog
```

### 查看传统日志文件

传统的日志文件通常位于 `/var/log/` 目录下：

```bash
# 系统日志
/var/log/messages

# 安全日志
/var/log/secure

# 应用程序日志
/var/log/application.log
```

## 日志监控与告警

### 使用 systemd-cat 发送自定义日志

```bash
# 发送自定义日志消息
echo "自定义日志消息" | systemd-cat -p info -t myapp

# 检查发送的日志
journalctl -t myapp
```

### 设置日志监控

可以使用简单的脚本结合 journalctl 来监控特定的日志模式并发送告警：

```bash
#!/bin/bash

# 监控错误日志并发送邮件告警
journalctl -f -p err --since "10 minutes ago" | grep --line-buffered "error" | \
while read line; do
    echo "$line" | mail -s "系统错误告警" admin@example.com
done
```

## 故障排查技巧

### 常见问题排查

#### 系统无法启动

```bash
# 查看启动失败的服务
journalctl -b -p err

# 查看特定服务的启动失败原因
journalctl -b -u failed_service.service
```

#### 网络连接问题

```bash
# 查看网络相关服务的日志
journalctl -u NetworkManager.service
journalctl -u firewalld.service

# 搜索网络相关的错误
journalctl -g "network|connection|interface"
```

#### 认证失败问题

```bash
# 查看认证相关的日志
journalctl -u sshd.service | grep "Failed"

# 查看所有认证失败记录
journalctl -g "authentication failure"
```

### 生成系统状态报告

```bash
# 生成 systemd 状态报告
sudo systemd-analyze blame

# 生成启动时间图表
sudo systemd-analyze plot > boot_chart.svg

# 生成依赖图
sudo systemd-analyze dot | dot -Tsvg > systemd_dependencies.svg
```

## journalctl 最佳实践

1. **定期清理日志**：定期清理旧日志以避免磁盘空间耗尽
2. **启用日志持久化**：对于重要服务器，确保日志持久化存储
3. **设置适当的权限**：确保日志文件权限设置正确，防止未授权访问
4. **配置日志转发**：考虑将日志转发到集中式日志服务器
5. **创建日志监控脚本**：针对关键服务和错误创建自定义监控
6. **备份重要日志**：定期备份重要的日志数据
7. **使用结构化查询**：利用 journalctl 的结构化查询功能进行高效分析

## 总结

journalctl 是 Rocky Linux 中管理 systemd 日志的强大工具，它提供了丰富的过滤、查询和管理功能。通过有效地使用 journalctl，系统管理员可以快速定位和解决各种系统问题，监控系统状态，并维护系统的正常运行。

本教程介绍了 journalctl 的基本用法、过滤选项、格式控制、日志管理以及与传统日志系统的集成。掌握这些技能将大大提高您管理和维护 Rocky Linux 系统的能力。

记住，日志是系统健康的重要指标，定期检查日志并建立有效的日志管理策略是系统管理工作中不可或缺的部分。
