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——日志轮转工具,自动压缩、切割、清理旧日志

知识关联

原理讲解

📝 为什么 NTP 采用分层体系(Stratum)?

如果所有计算机都直接从原子钟同步时间,原子钟的连接数会爆炸(全球数十亿台设备)。NTP 的分层设计(Stratum 0 原子钟 → Stratum 1 直连服务器 → Stratum 2 二级服务器 → ...)解决了这个问题:分担连接压力——每台 Stratum N 服务器只为下一层的有限数量客户端服务;容错——某个 Stratum 2 服务器故障,客户端可以切换到其他服务器;精度可控——每一层引入约 1-10ms 的额外延迟,但对绝大多数应用来说足够精确。这就是为什么你的 chrony 通常同步到 Stratum 2 或 3 的服务器——它们离真正的原子钟只有 1-2 跳。

📝 journald 为什么用二进制格式而不是纯文本?

传统 syslog 把每条日志写成一行文本,用 grep 搜索时需要逐行扫描。journald 选择二进制格式有四个关键优势:①结构化存储——每条日志自带 _PID、_UID、_SYSTEMD_UNIT 等元数据字段,可以按任意字段高效过滤(journalctl _PID=1234 不需要 grep 全文);② 压缩——二进制格式压缩率远高于文本(通常 5-10 倍),1GB 文本日志压缩后可能只有 100MB;③ 索引——journald 为时间、服务名、优先级等字段建索引,查询速度比 grep 文本快数十倍;④ 原子写入——二进制 journal 文件支持原子追加,不会出现文本日志"写到一半崩溃导致行损坏"的问题。代价是人类无法直接阅读 journal 文件——但 journalctl 工具提供了完整的查询和格式化输出能力。

📝 文件系统日志(journal)如何保证一致性?

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(双系统时间修复、嵌入式设备)
chronycchrony 客户端状态查看 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 保证快速对齐
📝 双系统时间错乱问题 同一台机器装 Linux 和 Windows 双系统,时间常错乱 8 小时:Windows 认为 RTC 存的是本地时间,Linux 认为存的是 UTC。修复:Windows 注册表设置 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 -Idate "+%Y-%m-%dT%H:%M:%S%z"。这种格式按字母序排序也是正确的时序。

练习题

  1. (概念)chrony 中的 Stratum 层级是什么意思?Stratum 2 和 Stratum 10 的精度哪个更高?
  2. (概念)journald 和 rsyslog 的区别是什么?为什么说 journald 比传统 syslog 提供了更多信息?
  3. (实操)date 生成一个格式为 2026-07-30_14-30-00 的时间戳(用 + 格式符)。
  4. (实操)journalctl --since "1 hour ago" -p err 查看过去 1 小时内的系统错误日志。
  5. (实操)chronyc sources -v 查看你系统的 NTP 服务器。用 chronyc tracking 查看同步精度。
  6. (探究 🔍)研究 journalctl -o verbose 的输出,找出日志条目的所有字段(_PID、_SYSTEMD_UNIT、_TRANSPORT 等)。理解这些结构化字段如何让日志查询更强大。
  7. (探究 🔍)/etc/logrotate.d/ 中找一个配置文件,读懂每行配置的含义。手动运行 sudo logrotate -d /etc/logrotate.d/软件名 观察 debug 输出。
点击查看答案
  1. (概念)Stratum 层级表示 NTP 服务器在时间同步树中的位置。Stratum 0 是原子钟/GPS 等参考时钟,Stratum 1 直接从 Stratum 0 同步,Stratum 2 从 Stratum 1 同步,以此类推。层级越低精度越高——Stratum 2 比 Stratum 10 更精确。
  2. (概念)journald 是 systemd 的结构化二进制日志系统,自动记录 _PID、_UID、_SYSTEMD_UNIT 等丰富元数据,支持按字段高效过滤。rsyslog 是传统的纯文本日志系统,将日志写入 /var/log/ 下的文件。journald 优势:结构化查询、元数据丰富、压缩存储。
  3. (实操)`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 时间戳)。格式符适合在脚本中生成日志文件名。
  4. (实操)`journalctl --since "1 hour ago" -p err`。`--since` 和 `--until` 组合使用可精确定位时间窗口。`-p err` 只显示 err 及以上级别(err/crit/alert/emerg)。`-p` 实际上是 `--priority=` 的简写。
  5. (实操)`chronyc sources -v` 显示 NTP 源列表:^* 表示当前同步源,^- 表示不可达,^+ 表示备选。`chronyc tracking` 查看同步精度:Stratum 层数、Last offset(与参考源的偏移量)、RMS offset(历史偏移均方根)。偏移量越小越好。
  6. (探究 🔍)`journalctl -o verbose`(或 -o json-pretty)显示完整结构化字段。关键字段:`_PID`(进程 ID)、`_SYSTEMD_UNIT`(systemd 单元)、`_TRANSPORT`(来源:journal/syslog/kernel/stdout)、`_COMM`(命令名)。利用这些字段可精确过滤:`journalctl _PID=1234`。
  7. (探究 🔍)`/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 / journalctlsystemd 的结构化日志系统及其查询工具
rsyslog传统日志服务,将日志写入 /var/log/ 下的文本文件
logrotate日志轮转工具,自动压缩、切割、清理旧日志

下一步:进入 2.6:硬件信息查看「硬件信息查看」,学习如何查看和管理计算机硬件信息。

延伸阅读

  • chrony 官方文档——深入了解 chrony 配置和性能调优
  • journalctl 官方手册——journalctl 所有选项的完整参考
  • 命令systemd-tmpfiles——管理系统临时文件和运行时日志的清理策略
  • 命令logger——从命令行向 syslog/journald 发送日志消息。脚本中常用 logger "Backup completed"

常见问题

磁盘空间满了但 df 显示还有空间?
可能是 inode 耗尽:df -i 查看 inode 使用率。如果 inode 用完,即使有磁盘空间也无法创建新文件(包括目录),常见于存在大量小文件(如 Maildir 邮件目录、PHP session 文件)。查找 inode 高的目录:find / -xdev -printf '%h\n' | sort | uniq -c | sort -k1 -rn | head。
fstab 配错导致无法启动怎么办?
在 GRUB 启动菜单选"高级选项"进入恢复模式(recovery mode),选 root shell 挂载为读写(mount -o rw,remount /),然后修复 /etc/fstab 中的错误行。如果不记得正确配置,把该行注释掉(行首加 #),重启后再修正。
LVM 和传统分区怎么选?
LVM 的最大优势是弹性:可以在线扩展卷组、跨磁盘聚合空间、创建快照。缺点是多了一层抽象,配置稍复杂。服务器建议用 LVM(/boot 分区除外),桌面或单用途系统可以直接用传统分区。近年 Btrfs 和 ZFS 提供了类似 LVM+文件系统的集成方案。
↑ 回到顶部