2.5 时间管理与日志
预计阅读时间:19 分钟
📖 目录
学习目标
学完本章后,你将能够:
- 使用
date查看和格式化日期时间 - 使用
timedatectl管理时区和 NTP 同步 - 配置 chrony 实现精确的时间同步
- 使用
journalctl查询和过滤系统日志 - 理解 rsyslog 的结构和日志分类
- 配置 logrotate 实现日志轮转
核心知识
- date——显示和设置系统日期时间,支持丰富的输出格式
- NTP(Network Time Protocol)——网络时间协议,通过网络同步计算机时钟的协议
- chrony——现代 NTP 客户端/服务器实现,功能比 systemd-timesyncd 更丰富(需单独安装)
- journald——systemd 的日志守护进程,收集内核和服务的结构化日志
- journalctl——查询和管理 journald 日志的命令行工具
- rsyslog——传统的系统日志服务,将日志写入
/var/log/下的文本文件 - logrotate——日志轮转工具,自动压缩、切割、清理旧日志
知识关联
- 前置知识:2.2:配置文件与系统设置 的 timedatectl 提供了时间配置的基础;1.8:软件包管理 使用 apt 安装 chrony/rsyslog
- 后续影响:4.4:Shell 自动化实战(cron 定时任务)依赖准确的时间——时间不准导致定时任务乱执行
- 配套技术:1.7:用户与权限管理 的 grep/awk 用于搜索日志;1.6:文件查看与文本编辑 的 tail -f 实时监控日志输出
- 在整个体系中的位置:时间准确是系统可靠运行的前提(日志时序、证书验证、定时任务)。日志是排错的第一信息来源
原理讲解
如果所有计算机都直接从原子钟同步时间,原子钟的连接数会爆炸(全球数十亿台设备)。NTP 的分层设计(Stratum 0 原子钟 → Stratum 1 直连服务器 → Stratum 2 二级服务器 → ...)解决了这个问题:分担连接压力——每台 Stratum N 服务器只为下一层的有限数量客户端服务;容错——某个 Stratum 2 服务器故障,客户端可以切换到其他服务器;精度可控——每一层引入约 1-10ms 的额外延迟,但对绝大多数应用来说足够精确。这就是为什么你的 chrony 通常同步到 Stratum 2 或 3 的服务器——它们离真正的原子钟只有 1-2 跳。
传统 syslog 把每条日志写成一行文本,用 grep 搜索时需要逐行扫描。journald 选择二进制格式有四个关键优势:①结构化存储——每条日志自带 _PID、_UID、_SYSTEMD_UNIT 等元数据字段,可以按任意字段高效过滤(journalctl _PID=1234 不需要 grep 全文);② 压缩——二进制格式压缩率远高于文本(通常 5-10 倍),1GB 文本日志压缩后可能只有 100MB;③ 索引——journald 为时间、服务名、优先级等字段建索引,查询速度比 grep 文本快数十倍;④ 原子写入——二进制 journal 文件支持原子追加,不会出现文本日志"写到一半崩溃导致行损坏"的问题。代价是人类无法直接阅读 journal 文件——但 journalctl 工具提供了完整的查询和格式化输出能力。
ext4 和 xfs 等现代文件系统都使用日志(journal)机制防止断电或崩溃导致的数据损坏。原理:每次写入数据前,先将"要做什么"(如"在块 1000 写入 inode 500 的数据")写入日志区域——日志是连续的顺序写入,速度快。如果写入过程中断电,重启后文件系统只需要"重放日志"(replay),将未完成的操作重新执行一遍,保证数据一致性。日志模式有三种:data=writeback(只记录元数据,最快但不保护数据内容)、data=ordered(默认,先写数据再写元数据日志)、data=journal(数据和元数据都记日志,最安全但最慢)。服务器通常使用默认的 ordered 模式,在安全和性能之间取平衡。
1. date——查看和格式化日期时间
# 查看当前时间
date # 本地时间(默认格式)
# 输出: 2026年 07月 30日 星期四 14:30:00 CST
date -u # UTC 时间
# 输出: 2026年 07月 30日 星期四 06:30:00 UTC
date -R # RFC 2822 格式(适合邮件)
# 输出: Thu, 30 Jul 2026 14:30:00 +0800
date -I # ISO 8601 格式(YYYY-MM-DD)
# 输出: 2026-07-30
date +%s # Unix 时间戳(秒,自 1970-01-01)
# 输出: 1785393000
# 格式化输出(% + 格式符)
date "+%Y-%m-%d %H:%M:%S" # 2026-07-30 14:30:00
# 输出: 2026-07-30 14:30:00
date "+%A, %B %d, %Y" # Wednesday, July 30, 2026
# 输出: Thursday, July 30, 2026
date "+%s" # 时间戳
# 输出: 1785393000
date "+%Y%m%d_%H%M%S" # 20260730_143000(文件名友好)
# 输出: 20260730_143000
# 时间计算
date -d "next Friday" # 下周五
# 输出: 2026年 08月 07日 星期五 00:00:00 CST
date -d "last month" # 上个月的今天
# 输出: 2026年 06月 30日 14:30:00 CST
date -d "+2 weeks" # 两周后
# 输出: 2026年 08月 13日 14:30:00 CST
date -d "2026-12-25 3 days ago" # 2026-12-22
# 输出: 2026年 12月 22日 00:00:00 CST
# 从时间戳转回日期
date -d @1785393000 # 将 Unix 时间戳转回可读格式
# 输出: 2026年 07月 30日 星期四 14:30:00 CST
2. NTP 与时间同步原理
计算机的硬件时钟(RTC,Real-Time Clock)不准确——每天可能偏差数秒。NTP(Network Time Protocol)通过网络从高精度时间服务器同步系统时钟。
| 工具 | 操作对象 | 典型用途 |
|---|---|---|
timedatectl | 系统时钟 + RTC + 时区 + NTP | 一站式管理:查看/设置时区、开关 NTP、同步 RTC |
hwclock | 仅硬件时钟(RTC) | 直接读写 RTC(双系统时间修复、嵌入式设备) |
chronyc | chrony 客户端状态 | 查看 NTP 同步源、偏移量、精度 |
推荐:日常使用 timedatectl 即可;只有在双系统时间错乱或嵌入式场景才需要直接操作 hwclock。
NTP 分层体系(Stratum):
- Stratum 0:原子钟、GPS 时钟等物理时间源
- Stratum 1:直接连接到 Stratum 0 的服务器
- Stratum 2:从 Stratum 1 同步的服务器
- Stratum 3+:从上一级同步,层级越高精度越低
chrony 是一个功能完善的 NTP 实现(需 sudo apt install chrony)。它包含两个核心组件:chronyd(守护进程,持续同步)和 chronyc(命令行控制工具)。
# 查看 chrony 同步状态
chronyc sources -v
# 输出: MS Name/IP address Stratum Poll Reach LastRx Last sample
# 输出: ^+ ntp.tencent.com 2 6 377 43 -1248us[ -150us] +/- 47ms
# 输出: ^* ntp.aliyun.com 2 6 377 54 -432us[ +58us] +/- 32ms
# ^? 表示未连接,^+ 表示可用,^* 表示当前同步源
chronyc tracking
# 输出: Reference ID : A9FEA1B6 (ntp.aliyun.com)
# 输出: Stratum : 3
# 输出: Last offset : -0.000432 秒
# 输出: RMS offset : 0.001234 秒
# chrony 配置文件
cat /etc/chrony/chrony.conf
# 输出: pool ntp.aliyun.com iburst maxsources 4
# 输出: makestep 1.0 3
系统时钟 vs 硬件时钟(RTC):计算机里有两个时钟——主板上的硬件时钟(RTC,靠电池供电)和内核维护的系统时钟。开机时内核从 RTC 读取时间作为系统时钟起点,之后系统时钟由内核自己走时(精度更高)。NTP 同步的是系统时钟,而 RTC 的校准需要单独处理。
# 查看两个时钟的状态
timedatectl
# 输出: Local time: Thu 2026-07-30 14:30:00 CST
# 输出: Universal time: Thu 2026-07-30 06:30:00 UTC
# 输出: RTC time: Thu 2026-07-30 06:30:00
# 输出: Time zone: Asia/Shanghai (CST, +0800)
# 输出: System clock synchronized: yes
# 输出: NTP service: active
# 输出: RTC in local TZ: no
# RTC time 显示 UTC(RTC in local TZ: no)——Linux 推荐 RTC 存 UTC
# hwclock —— 直接操作硬件时钟
sudo hwclock --show # 读 RTC
sudo hwclock --systohc # 把系统时钟写入 RTC(同步硬件时钟)
sudo hwclock --hctosys # 把 RTC 读入系统时钟(开机时的默认动作)
# 为什么"重启后时间又变回去了"?
# 场景:date 手动改过时间,重启后复原 → RTC 没同步
# 解决:sudo hwclock --systohc # 让 RTC 记住新时间
# chrony 的 makestep 配置解读
# makestep 1.0 3 = 如果与时间源偏差超过 1 秒,前 3 次同步时直接跳变
# 而不是缓慢调校(缓慢调校对需要精确时序的服务更平滑,但收敛慢)
# 服务器被挂起(休眠)恢复后偏差可能达数小时,makestep 保证快速对齐
RealTimeIsUniversal=1,或 Linux 侧 timedatectl set-local-rtc 1(不推荐,Linux 侧保持 UTC 是正路)。3. journald——systemd 的结构化日志
systemd 的 journald 收集系统所有的日志——内核消息、服务日志、应用输出——并以二进制格式存储。相比传统的 syslog 文本格式,journald 提供结构化的字段和强大的查询能力。
# journalctl 基本用法
journalctl # 所有日志(默认分页,按 q 退出)
# 输出: (进入分页浏览,显示所有日志)
journalctl -n 50 # 最后 50 条
journalctl -f # 实时跟踪(类似 tail -f)
# 输出: (实时滚动显示日志条目)
journalctl -r # 最新在前(反向排序)
# 按服务过滤
journalctl -u nginx.service # 特定服务的日志
# 输出: -- Logs begin at Wed 2026-07-29 00:00:00 CST --
# 输出: Jul 30 14:30:00 ubuntu nginx[1234]: starting nginx
journalctl -u ssh.service # SSH 日志
journalctl -u nginx.service -u mysql.service # 多个服务
# 按时间过滤
journalctl --since "2026-07-29" # 从某天开始
journalctl --since "2 hours ago" # 最近 2 小时
journalctl --until "2026-07-30 12:00" # 到某个时间点
journalctl --since today # 今天的日志
# 按优先级过滤
journalctl -p err # 只显示错误级别及以上的日志
journalctl -p warning # 警告及以上
journalctl -p emerg # 仅紧急级别
# 优先级:emerg(0) alert(1) crit(2) err(3) warning(4) notice(5) info(6) debug(7)
# 按关键字
journalctl -u nginx.service | grep "failed"
# 更多输出选项
journalctl -o verbose # 显示所有字段
journalctl -o json # JSON 格式输出
# 输出: {"_PID":"1234","_COMM":"nginx","MESSAGE":"starting nginx"}
journalctl -o short # 经典 syslog 风格(默认)
# 查看日志占用的磁盘空间
journalctl --disk-usage
# 输出: Archived and active journals take up 320.0M in the file system.
# 清理日志
sudo journalctl --vacuum-size=500M # 保留最近 500MB
# 输出: Vacuuming done, freed 128.0M of archived journals
sudo journalctl --vacuum-time=30days # 保留 30 天
# 输出: Vacuuming done, freed 64.0M of archived journals
4. rsyslog——传统日志系统
虽然 journald 是新一代日志系统,传统 rsyslog 仍在广泛使用。日志文件存储在 /var/log/ 目录下。
$ ls /var/log/
# 输出: syslog # 系统总日志
# 输出: auth.log # 认证日志(登录、sudo)
# 输出: kern.log # 内核日志
# 输出: dmesg # 内核环缓冲区
# 输出: dpkg.log # 包管理日志
# 输出: nginx/ # Nginx 访问/错误日志
# 输出: mysql/ # MySQL 日志
# 输出: apt/ # apt 操作日志
# rsyslog 配置
cat /etc/rsyslog.conf
# 输出: # /etc/rsyslog.conf configuration file
# 输出: *.*;auth,authpriv.none /var/log/syslog
# 输出: auth,authpriv.* /var/log/auth.log
cat /etc/rsyslog.d/50-default.conf
# 输出: # Default rules for rsyslog
# 输出: kern.* /var/log/kern.log
# 日志格式:设施.优先级 /日志文件
# auth.* /var/log/auth.log
# *.info;auth.none /var/log/syslog
# kern.* /var/log/kern.log
5. logrotate——不让日志撑爆磁盘
日志文件会不断增长。logrotate 自动按策略切割、压缩、清理日志。
# logrotate 配置文件
cat /etc/logrotate.conf
# 输出: # see "man logrotate" for details
# 输出: weekly
# 输出: rotate 4
# 输出: create
# 输出: dateext
# 输出: compress
# 全局配置示例:
# weekly # 每周轮转
# rotate 4 # 保留 4 份旧日志
# create # 轮转后创建新日志文件
# dateext # 文件名加日期后缀
# compress # 压缩旧日志
# 特定服务的日志轮转策略
cat /etc/logrotate.d/nginx
# 输出: /var/log/nginx/*.log {
# 输出: daily
# 输出: missingok
# 输出: rotate 14
# 输出: compress
# 输出: delaycompress
# 输出: notifempty
# 输出: create 640 www-data adm
# 输出: sharedscripts
# 输出: postrotate
# 输出: [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
# 输出: endscript
# 输出: }
# 手动测试轮转
sudo logrotate -d /etc/logrotate.d/nginx # -d = debug(不实际执行)
# 输出: reading config file /etc/logrotate.d/nginx
# 输出: ...
# 强制轮转
sudo logrotate -f /etc/logrotate.conf
# 输出: (无输出)
6. journald 深入——按启动轮次与结构化字段查询
journalctl 最强大的能力是"按启动轮次(boot)"和"按结构化字段"过滤。系统每次开机都是一个新的 boot ID,排障"上次启动发生了什么"就靠它。
# 列出所有启动轮次
journalctl --list-boots
# 输出: -2 2026-07-28 08:00:12 CST—2026-07-29 09:15:03 CST
# 输出: -1 2026-07-29 09:20:01 CST—2026-07-30 06:30:00 CST
# 输出: 0 2026-07-30 06:35:22 CST—now
# 0 = 当前启动;-1 = 上一次;数字越大越久远
# 查看上一次启动的全部日志(排查"为什么重启后服务没起来")
journalctl -b -1
journalctl -b -1 -p err # 上一次启动的错误
journalctl -b -1 -u nginx # 上一次启动时 nginx 的日志
# 按字段精确过滤(-o verbose 查看可用字段,_ 前缀是系统注入字段)
journalctl _PID=1234 # 某进程的所有日志
journalctl _SYSTEMD_UNIT=nginx.service # 等价于 -u nginx.service
journalctl _TRANSPORT=syslog # 来自传统 syslog 的条目
journalctl _HOSTNAME=web-01 # 集中日志场景按主机过滤
journalctl _UID=1000 # 某用户的进程产生的日志
# 组合查询实例:排查磁盘不足告警
journalctl --since today -p warning | grep -i "no space"
# 输出: Jul 30 10:15:00 ubuntu kernel: EXT4-fs (sda2): No space left on device
# 让日志持久化(默认日志存在内存 /run/log/journal,重启即丢)
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald
# 之后重启日志也保留,才能用 journalctl -b -1 查历史
# journald 的容量控制
cat /etc/systemd/journald.conf
# 输出: SystemMaxUse=4G # 日志最多占 4G
# 输出: SystemKeepFree=1G # 给系统其他部分至少留 1G
# 输出: Compress=yes # 压缩归档日志
# 修改后:sudo systemctl restart systemd-journald
7. 日志排障实战——三个典型场景
把本章的工具串起来,解决三个最常见的"日志类"故障。
# 场景 1:服务启动失败,但 systemctl status 信息太少
sudo systemctl start nginx
# 输出: Job for nginx.service failed because the control process exited...
sudo journalctl -u nginx.service -n 30 --no-pager
# 输出: nginx[1234]: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
# 日志直接告诉你:80 端口被占。继续:ss -tlnp | grep :80 找到占用进程
# 场景 2:系统某天突然变慢,查"当时发生了什么"
journalctl --since "2026-07-29 09:15:00" --until "2026-07-29 09:20:00" -p warning
# 输出: Jul 29 09:17:00 ubuntu kernel: oom-killer: gfp_mask=...
# 输出: Jul 29 09:17:00 ubuntu kernel: Out of memory: Killed process 4567 (mysqld)
# 时间窗口内的内核消息直接揭示:OOM Killer 杀了 MySQL
# 场景 3:用户反映"SSH 登录失败"
sudo journalctl -u ssh -n 20
# 输出: Jul 30 13:00:01 ubuntu sshd[2345]: Failed password for alice from 1.2.3.4
# 输出: Jul 30 13:00:02 ubuntu sshd[2345]: Connection closed by 1.2.3.4
# 结合传统日志 /var/log/auth.log 交叉验证:
grep "Failed password" /var/log/auth.log | tail -5
# 多个来源交叉验证后,再判断是密码错误还是暴力破解(后者见 ch19 防火墙)
systemctl status 服务 看运行状态 ② journalctl -u 服务 -n 50 看最近日志 ③ 时间窗口过滤看异常时刻 ④ 与其他日志(kernel、auth)交叉验证。journald 和 /var/log/ 下的传统文件互为补充——journald 记录系统级事件,应用自己的日志(如 nginx access.log)仍在 /var/log/ 下。示例代码
# 练习 1:date 命令
date
# 输出: 2026年 07月 30日 星期四 14:30:00 CST
date -u
# 输出: 2026年 07月 30日 星期四 06:30:00 UTC
date "+%Y-%m-%d %H:%M:%S"
# 输出: 2026-07-30 14:30:00
date -d "next Monday"
# 输出: 2026年 08月 10日 星期一 00:00:00 CST
date -d "2026-07-01 14:30:00" +%s # 转时间戳
# 输出: 1782887400
# 练习 2:chrony 时间同步
timedatectl
# 输出: Local time: Thu 2026-07-30 14:30:00 CST
# 输出: Universal time: Thu 2026-07-30 06:30:00 UTC
# 输出: RTC time: Thu 2026-07-30 06:30:00
# 输出: Time zone: Asia/Shanghai (CST, +0800)
# 输出: System clock synchronized: yes
# 输出: NTP service: active
chronyc sources -v # 查看同步源
# 输出: MS Name/IP address Stratum Poll Reach LastRx Last sample
# 输出: ^* ntp.aliyun.com 2 6 377 54 -432us[ +58us] +/- 32ms
chronyc tracking # 查看同步精度
# 输出: Reference ID : A9FEA1B6 (ntp.aliyun.com)
# 输出: Stratum : 3
# 输出: Last offset : -0.000432 seconds
# 练习 3:journalctl 日志查询
journalctl -n 20 # 最近 20 条
# 输出: -- Logs begin at Wed 2026-07-29 00:00:00 CST --
# 输出: Jul 30 14:30:00 ubuntu systemd[1]: Started...
journalctl -u ssh.service -n 10 # SSH 最近 10 条
journalctl -p err --since "1 hour ago" # 过去 1 小时的错误
journalctl --disk-usage # 日志占用磁盘空间
# 输出: Archived and active journals take up 320.0M
# 练习 4:查看文本日志
tail -20 /var/log/syslog # 最近 20 条系统日志
# 输出: Jul 30 14:30:00 ubuntu systemd[1]: Started...
tail -f /var/log/syslog & # 实时跟踪(后台运行)
# 输出: [1] 12345
# 在另一个终端执行 sudo apt update 观察日志追加
fg %1 # 把 tail 调到前台
# 输出: tail -f /var/log/syslog
# 按 Ctrl+C 停止
# 练习 5:logrotate 配置测试
cat /etc/logrotate.d/nginx 2>/dev/null || echo "nginx not installed"
# 输出: nginx not installed
sudo logrotate -d /etc/logrotate.d/dpkg 2>/dev/null
# 输出: (debug 输出或空)
常见错误
| 错误/误区 | 解决方案 |
|---|---|
| "系统时间误差很大,以为是硬件坏了" | 先检查 chrony 是否运行:systemctl status chrony。如果没运行,sudo systemctl enable --now chrony。运行后等几分钟让 chrony 逐步校准时间。 |
| "journalctl -u 服务名 后没日志" | 确保服务名正确:systemctl list-units --type=service 查看准确名称。一些服务可能将日志写到了 /var/log/ 下面的文件而不是 journald。 |
| "误删了 /var/log/ 下的日志文件" | 如果文件被删除但进程仍然打开着,日志仍写入已删除的文件描述符中——需要重启进程释放。用 lsof | grep deleted 查看被删除但仍在写入的文件。 |
| "timedatectl set-time 提示 Failed to set time" | 如果 NTP 已启用(timedatectl set-ntp true),禁止手动设置时间。先 sudo timedatectl set-ntp false,再 sudo timedatectl set-time "...",完成后重新启用 NTP。 |
| "date -d 报错 invalid date" | date 的 -d 参数格式有要求。标准格式:"YYYY-MM-DD HH:MM:SS" 或相对时间 "next Friday"。某些语言环境可能影响解析,可以加 LC_ALL=C date -d "..."。 |
| "双系统时间差 8 小时" | Windows 认为 RTC 存本地时间,Linux 认为存 UTC。修复:Windows 注册表设置 RealTimeIsUniversal=1,或 Linux 侧 timedatectl set-local-rtc 1(不推荐)。 |
| "日志文件被删除但磁盘空间没释放" | 进程仍持有已删除文件的文件描述符。用 lsof | grep deleted 查看,重启相关进程释放。 |
最佳实践
| # | 建议 | 说明 |
|---|---|---|
| 1 | 始终开启 NTP 时间同步 | timedatectl set-ntp true。时间不准会导致 HTTPS 证书验证失败、日志时间混乱、cron 执行异常。 |
| 2 | 用 journalctl 而不是直接 cat 日志文件 | journalctl 提供结构化查询(按时间、服务、优先级),远比 grep syslog 高效。 |
| 3 | 配置 logrotate 防止日志撑满磁盘 | 未配置日志轮转的后果:/var/log 撑满 → 系统异常(无法登录、服务无法写日志)。默认配置通常足够。 |
| 4 | 日志集中管理 | 多台服务器时,用 rsyslog 的远程日志功能将所有日志发送到集中日志服务器,或使用 ELK/Loki 等方案。 |
| 5 | 用 ISO 8601 格式记录时间 | 在脚本和日志中使用 date -I 或 date "+%Y-%m-%dT%H:%M:%S%z"。这种格式按字母序排序也是正确的时序。 |
练习题
- (概念)chrony 中的 Stratum 层级是什么意思?Stratum 2 和 Stratum 10 的精度哪个更高?
- (概念)journald 和 rsyslog 的区别是什么?为什么说 journald 比传统 syslog 提供了更多信息?
- (实操)用
date生成一个格式为2026-07-30_14-30-00的时间戳(用+格式符)。 - (实操)用
journalctl --since "1 hour ago" -p err查看过去 1 小时内的系统错误日志。 - (实操)用
chronyc sources -v查看你系统的 NTP 服务器。用chronyc tracking查看同步精度。 - (探究 🔍)研究
journalctl -o verbose的输出,找出日志条目的所有字段(_PID、_SYSTEMD_UNIT、_TRANSPORT 等)。理解这些结构化字段如何让日志查询更强大。 - (探究 🔍)在
/etc/logrotate.d/中找一个配置文件,读懂每行配置的含义。手动运行sudo logrotate -d /etc/logrotate.d/软件名观察 debug 输出。
点击查看答案
- (概念)Stratum 层级表示 NTP 服务器在时间同步树中的位置。Stratum 0 是原子钟/GPS 等参考时钟,Stratum 1 直接从 Stratum 0 同步,Stratum 2 从 Stratum 1 同步,以此类推。层级越低精度越高——Stratum 2 比 Stratum 10 更精确。
- (概念)journald 是 systemd 的结构化二进制日志系统,自动记录 _PID、_UID、_SYSTEMD_UNIT 等丰富元数据,支持按字段高效过滤。rsyslog 是传统的纯文本日志系统,将日志写入 /var/log/ 下的文件。journald 优势:结构化查询、元数据丰富、压缩存储。
- (实操)`date +%Y-%m-%d_%H-%M-%S` 或 `date '+%Y%m%d_%H%M%S'`。`man date` 查看完整格式符列表。常用:`%F`(= %Y-%m-%d)、`%T`(= %H:%M:%S)、`%s`(Unix 时间戳)。格式符适合在脚本中生成日志文件名。
- (实操)`journalctl --since "1 hour ago" -p err`。`--since` 和 `--until` 组合使用可精确定位时间窗口。`-p err` 只显示 err 及以上级别(err/crit/alert/emerg)。`-p` 实际上是 `--priority=` 的简写。
- (实操)`chronyc sources -v` 显示 NTP 源列表:^* 表示当前同步源,^- 表示不可达,^+ 表示备选。`chronyc tracking` 查看同步精度:Stratum 层数、Last offset(与参考源的偏移量)、RMS offset(历史偏移均方根)。偏移量越小越好。
- (探究 🔍)`journalctl -o verbose`(或 -o json-pretty)显示完整结构化字段。关键字段:`_PID`(进程 ID)、`_SYSTEMD_UNIT`(systemd 单元)、`_TRANSPORT`(来源:journal/syslog/kernel/stdout)、`_COMM`(命令名)。利用这些字段可精确过滤:`journalctl _PID=1234`。
- (探究 🔍)`/etc/logrotate.d/` 下配置文件示例:`rotate 7`(保留 7 份历史)、`weekly`(每周轮转)、`compress`(gzip 压缩旧日志)、`delaycompress`(推迟一次压缩)、`postrotate`(轮转后重载服务)。`logrotate -d` 以调试模式运行,仅模拟不实际操作。
学习检查点
学完本章后,请检验自己是否掌握以下内容:
| 检查项 | 自测问题 | 验证方法 |
|---|---|---|
| 概念理解 | 能用自己的话解释 journald 和 rsyslog 双日志系统的分工 | 尝试向他人讲解 |
| 命令操作 | 能不查文档使用 journalctl 按时间、服务、优先级过滤日志 | 在终端实际执行 |
| 原理掌握 | 能说出 logrotate 日志轮转的工作原理和配置方法 | 画出轮转流程图 |
| 故障排查 | 能独立使用 dmesg 和 journalctl 排查系统启动和硬件问题 | 模拟故障并排查 |
| 最佳实践 | 能说明为什么应该配置 journald 持久化而不是默认的内存模式 | 对比不同存储模式 |
本章总结
时间管理和日志系统是系统管理员的两大基础设施。chrony 确保系统时间精确(认证、日志、定时任务都依赖它)。journalctl 提供了强大的日志查询能力——按服务、按时间、按优先级过滤秒级完成。logrotate 自动管理日志文件的增长,防止日志撑满磁盘。
速查表
| 概念 | 一句话定义 |
|---|---|
| date | 查看和格式化系统日期时间 |
| NTP / chrony | 网络时间协议及其客户端实现,自动同步系统时钟 |
| timedatectl | 查看和设置系统时区、NTP 状态的 systemd 工具 |
| journald / journalctl | systemd 的结构化日志系统及其查询工具 |
| rsyslog | 传统日志服务,将日志写入 /var/log/ 下的文本文件 |
| logrotate | 日志轮转工具,自动压缩、切割、清理旧日志 |
下一步:进入 2.6:硬件信息查看「硬件信息查看」,学习如何查看和管理计算机硬件信息。
延伸阅读
- chrony 官方文档——深入了解 chrony 配置和性能调优
- journalctl 官方手册——journalctl 所有选项的完整参考
- 命令:
systemd-tmpfiles——管理系统临时文件和运行时日志的清理策略 - 命令:
logger——从命令行向 syslog/journald 发送日志消息。脚本中常用logger "Backup completed"