Linux Day23——第三部分复习补充

本文系统梳理Linux日志分析与systemd服务管理的关键技术:日志四段结构(时间戳/主机/程序[PID]/正文)及其局限性;journalctl四大限定(unit/boot/优先级/时间)及--list-boots、--disk-usage用法;logger测试日志链路验证;logrotate四大机制(rotate/compress/copytruncate/postrotate)及-d/-f行为差异;systemd unit三段结构([Unit]/[Service]/[Install])与服务启停边界(start/enable/stop/disable/mask)及依赖关系(Requires/After)。

---

type: learning-note

title: Linux:块 3 补验收——日志四段、journalctl 限定、logger、logrotate、systemd

date: 2026-10-19

description: 一行日志四段与正文局限、journalctl 四限定与 --list-boots/--disk-usage、logger 造/捞与验证边界、logrotate 四关键词与 -d/-f、unit 三段与 start/enable、stop/disable/mask、Requires/After

---

 

# 2026-10-19 学习笔记

 

> 📌 GitHub:https://github.com/AR-firefly

 

## 笔记区

 

### 核心观点

 

**一行日志四段:时间戳 / 主机 / 程序[PID] / 正文**

 

用户样本:`Oct 19 19:24:28 AR-firefly systemd-resolved[79]: Clock change detected. Flushing caches.`

 

- ① `Oct 19 19:24:28` = 时间戳:什么时候发生。

- ② `AR-firefly` = 主机:哪台机器写的。

- ③ `systemd-resolved[79]` = 程序[PID]:谁写的;`[79]` 是 **PID = 进程号**,系统给正在运行的程序分配的编号。

- ④ `Clock change detected. Flushing caches.` = 正文:程序自己输出的那句话。

 

四段是**常见形态,不是铁律**:有的行程序名不带 PID,格式随发行版变。

 

记忆:问四个问题——**什么时候、哪台机器、谁在说、说了什么**。

 

**正文不能单独当结论**

 

- 正文是**应用自己写的**,不是有保证的结构化事实。

- **PID 会重用**:同一个号在不同开机可能是不同程序;同一次开机里进程结束后号码也会被回收。

- 单行只知道「发生过一次」,不知道**频率、来源、时间窗、上下文**。

「这只能算是线索,具体的频率,谁,什么时间,上下文和是否成功都不能知道,那只是程序自己写的,不一定是事实」。

- 例:`Failed password for root` 可能是攻击,也可能是用户自己连错三次密码;单行证明不了意图。

 

**journalctl 四种限定:unit / boot / 优先级 / 时间**

 

| 问什么 | 选项 | 例子 |

| ------------ | --------------------- | --------------------------------- |

| 哪个**服务** | `-u 名字` | `journalctl -u systemd-resolved` |

| 哪次**开机** | `-b` / `-b -1` | `journalctl -b -1` |

| 多**严重** | `-p 等级` | `journalctl -p err` |

| 哪段**时间** | `--since` / `--until` | `journalctl --since "10 min ago"` |

 

- `-p` 是**门槛**:`-p err` = `err` 及更严重,不是正文里找 `err` 三个字母。

- 等级数字**越小越严重**:`emerg`(0) / `alert`(1) / `crit`(2) / `err`(3) / `warning`(4) / `notice`(5) / `info`(6) / `debug`(7)。

- `-n N` 是**最多几条**,不是必须 N 条;匹配只有 1 条就显示 1 条。

- 记忆:**谁、哪次、多严重、什么时候**。

 

**`--list-boots`:开机会话目录**

 

- 一行 = **一段「开机 → 关机」的会话**,不是一条日志,也不是一个程序。

- `0` = 本次开机,`-1` = 上一次,`-21` = 从现在往回数第 21 次。

- `BOOT ID` = 那一次开机的内部编号;日志背后带的 `_BOOT_ID` 就是它。

- `FIRST ENTRY` / `LAST ENTRY` = 那一段会话的**第一条**和**最后一条**日志时间。

- 本机 22 条记录(`-21` 到 `0`)。`-21` 那段 FIRST `23:22:51`、LAST `23:23:07`——只活了 **16 秒**;下一段 `-20` 从 `23:24:27` 开始。

- **不是总开机次数计数器**:只列**日志还留着**的场次;日志删了,对应的行就没了。

「一行 = 一段开机到关机的日志时段」。

 

**`--disk-usage`:journal 占多少磁盘**

 

`Archived and active journals take up 808.4M in the file system.` —— 归档的 + 正在写的都算。

 

**system 与 journal 两组名字(⭐)**

 

| 名字 | 角色 | 管什么 | 是不是命令 |

| -------------------------------- | ------------------- | ------------------------------------------ | -------------------- |

| `systemd` | 后台总管家(PID 1) | 启动、停止、管理服务(还有挂载、定时器等) | 不是命令,是后台进程 |

| `systemctl` | 给 systemd 的遥控器 | 查状态、起停服务、设开机自启 | 命令 |

| `systemd-journald`(`journald`) | 后台档案员 | 收集日志,存进 journal | 不是命令,是后台进程 |

| `journal` | 日志数据本身 | 存下来的日志记录 | 不是命令 |

| `journalctl` | 查日志的遥控器 | 按服务/开机/等级/时间查日志 | 命令 |

 

- 命名规律:**`d` = daemon(后台跑的服务);`ctl` = control(遥控器/命令行工具)**。

- `systemctl show`:查**服务属性**(`Id=...`),不是日志。

- `systemctl status`:主业是**服务状态**,顺带显示最近几行日志。

- `journalctl`:专门**查日志**。

- 记忆:**d 是后台,ctl 是遥控器;system 管服务,journal 管日志。**

 

**logger:造一条带 tag 的测试日志**

 

- `logger -t 标签 '内容'`:**写**一条测试日志;`-t` = tag(标签),给消息贴名字。

- `journalctl -t 标签`:**按标签捞回来**;`-t` 在这里 = 按 tag 筛。

- `-t` 两边都是 tag:**写的时候贴,读的时候按它找**。

- 默认值:不给 `-p` → `user.notice`;不给 `-t` → 当前用户名;内容不给则从 stdin 读。

- `-s`:同时把消息打到屏幕;**屏幕有输出 ≠ 已持久存下来**。

- **验证了什么**:写 → journald 收下 → 存 → 能按 tag 查回来,这条链路通了。

- **没验证什么**:别的日志源、轮转、远程转发、真实应用的日志格式。

- 用途:日志查不到时,先分清是**服务没写**,还是**日志系统坏了**。

「如果捞得到就是服务本身的问题,如果捞不到说明这条链路错了是日志系统的问题」;更精确:捞得到只能说问题**更可能**在服务本身,捞不到也可能是标签/命令写错。

 

**logrotate 四关键词**

 

- **轮转**:把正在写的日志换成一个新文件接着写,老的改名留下来。

- `rotate N`:最多留 **N 代老的**;活跃那个不算名额,**总文件数 = 1 + N**。本机 `rotate 4` → 5 个文件。

- `compress`:老代压缩(gzip → `.gz`)。

- `delaycompress`:刚退下来的那一代**先不压**,下一次轮转再压。

- `copytruncate`:**复制**一份当前日志,再把**原文件就地清空**;给「喊不动、不会重开日志」的程序用。

- `postrotate … endscript`:轮转后、压缩前跑一段脚本,通知程序**重新打开日志**;本机是 `/usr/lib/rsyslog/rsyslog-rotate`。

- 两条路:程序**喊得动** → 改名 + `postrotate`;程序**喊不动** → `copytruncate`。

- `copytruncate` 的代价:复制和清空之间有一小段窗口,期间新写进来的日志**可能丢**;所以它是折中,不是默认。

 

**logrotate `-d` vs `-f`**

 

- `-d`(debug / dry-run):只打印它「打算怎么做」;**不动日志文件,也不更新状态文件**。

- `-f`(force):**强行真转**,哪怕它判断「今天不该转」。

- 普通用户跑 `-d` 读不到 `/var/lib/logrotate/status` → `Permission denied; assuming empty state`;它按空状态继续算,**预演结果可能和 root 真跑不同**。

- `-d` 输出好看 ≠ 真跑一定成功:权限、脚本、磁盘空间、程序能不能重开,它验不了。

 

**systemd unit 三段**

 

| 段 | 管什么 | 常见指令 |

| ----------- | ------------------------------ | ---------------------------------------------------------- |

| `[Unit]` | 这个单元**是什么、跟谁有关系** | `Description=`、`After=`、`Before=`、`Wants=`、`Requires=` |

| `[Service]` | 它**怎么跑** | `ExecStart=`、`Type=`、`Restart=`、`User=` |

| `[Install]` | **开机时怎么挂上去** | `WantedBy=` |

 

- 本机 `systemd-resolved.service`:`ExecStart=/usr/lib/systemd/systemd-resolved` 在 `[Service]`;`WantedBy=sysinit.target` 在 `[Install]`。

- `[Install]` **只在 `enable` / `disable` 时被读**;平时 `start` 不看它。

- 用户原话:「unit告诉你这是什么和各文件间的关系,service告诉你怎么跑,install告诉怎么挂链接」。

 

**start vs enable;stop vs disable vs mask**

 

| 命令 | 正在跑的服务 | 开机自启 | 手动还能 `start` 吗 |

| --------- | -------------------------- | ------------------- | ------------------- |

| `stop` | **停** | 不变 | 能 |

| `disable` | **不停** | 删掉 `.wants/` 链接 | 能 |

| `mask` | **不停**(除非加 `--now`) | 禁止 | **不能** |

 

- `start` = **现在**立刻跑;重启后就没了。

- `enable` = **以后**开机自启,建 `.wants/` 里的符号链接;**不会顺带启动**。

- `systemctl enable --now` = 两个一起做;`disable --now` / `mask --now` = 顺带停。

- `mask` = 把 unit 名链到 `/dev/null`(黑洞);`enable` 和手动 `start` 都不行;要恢复得 `unmask`。

- 用户原话:「一个是启动,一个只是开机后建链接不启动」。

 

**Requires vs After:依赖与顺序正交**

 

| 指令 | 管什么 | 不管什么 |

| ------------ | --------------------------------------------------------------- | --------------- |

| `Wants=A` | **弱依赖**:想把 A 拉起来;A 失败,B 照跑 | 不管顺序 |

| `Requires=A` | **强依赖**:把 A 拉起来;A 被显式 stop/restart,B 也跟着停/重启 | 不管顺序 |

| `After=A` | **顺序**:B 等 A 启动之后再启动 | 不会把 A 拉进来 |

| `Before=A` | 顺序反过来(等价于在 A 里写 `After=B`) | 不会把 A 拉进来 |

 

- 只写 `Requires=A`:A 和 B 可能**同时启动**;A 启动失败也不一定拦住 B。

- 只写 `After=A`:B 会等 A,但**不会把 A 拉起来**;A 没被调度时,这条顺序没效果。

- 想「A 起不来 B 也不起,而且 A 先起」→ **`Requires=A` + `After=A` 两个都要写**。

- 用户原话:「只说明了依赖,谁先谁后定不下来,可能他们一起冲了」;「只写After=A,A有可能直接死在那不启动了」。

 

### 关键方法/流程

 

- 读一行:`journalctl -n 1 --no-pager`。

- 按服务:`journalctl -u 服务名`(`.service` 可省)。

- 按开机:`journalctl -b`(本次)/ `-b -1`(上次)。

- 按等级:`journalctl -p err`(`err` 及更严重)。

- 按时间:`journalctl --since "10 min ago"` / `--until`。

- 按条数:`journalctl -n 10`(上限,不是配额)。

- 拼起来:`journalctl -u 服务名 -p err -b --since "10 min ago" --no-pager`。

- 开机目录:`journalctl --list-boots --no-pager`。

- 占磁盘:`journalctl --disk-usage`。

- 造测试日志:`logger -t 标签 '内容'` → `journalctl -t 标签 -n 3 --no-pager`。

- 看轮转配置:`cat /etc/logrotate.d/rsyslog`。

- 预演轮转:`logrotate -d /etc/logrotate.d/rsyslog`;强制真转:`logrotate -f ...`。

- 看 unit:`systemctl cat 单元名`(第一行 `# /usr/lib/...` 是 `cat` 加的注释,不是文件内容)。

- 起停/自启:`systemctl start` / `stop`;`systemctl enable` / `disable`;彻底封死用 `mask`,恢复用 `unmask`。

- 问状态:`systemctl is-active 单元`(现在跑不跑);`systemctl is-enabled 单元`(开不自启)。

 

### 实战记录

 

**① 一行日志四段**

 

```

$ journalctl -n 1 --no-pager

Oct 19 19:24:28 AR-firefly systemd-resolved[79]: Clock change detected. Flushing caches.

```

 

时间戳 `Oct 19 19:24:28` / 主机 `AR-firefly` / 程序 `systemd-resolved[79]` / 正文 `Clock change detected. Flushing caches.`

 

**② logger 造一条、按 tag 捞回**

 

```

$ logger -t AIDC '自己的测试内容'

$ journalctl -t AIDC -n 3 --no-pager

Oct 19 20:08:42 AR-firefly AIDC[10017]: 自己的测试内容

```

 

只捞回 1 条:`-n 3` 是上限,不是必须 3 条。

 

**③ 开机会话目录**

 

```

$ journalctl --list-boots --no-pager

IDX BOOT ID FIRST ENTRY LAST ENTRY

-21 8ebd3f016c6740e59e417ec2128c8a1e Mon 2026-09-07 23:22:51 CST Mon 2026-09-07 23:23:07 CST

-20 de20ece7cd234c5999cd694cf6b2b571 Mon 2026-09-07 23:24:27 CST Thu 2026-09-10 18:34:20 CST

```

 

`-21` 那段只活了 16 秒;`-20` 那段活了 3 天。

 

---

 

## 线索区(学完后合上材料,自问自答)

 

**Q: 一行日志的四段是什么?**

A: 时间戳 / 主机 / 程序[PID] / 正文;顺序固定,PID 是进程号。

 

**Q: 为什么正文不能单独当结论?**

A: 正文是应用自己写的,不是保证准确的结构化事实;PID 会重用;单行不知道频率、来源、时间窗、上下文。

 

**Q: `journalctl` 的四种限定各是什么?**

A: `-u` 单元 / `-b` 开机 / `-p` 优先级 / `--since`、`--until` 时间窗。

 

**Q: `-p err` 是「只要 err」吗?**

A: 不是,是 `err` 及更严重(0–3 档);级别数字越小越严重。

 

**Q: `--list-boots` 列的是什么?**

A: 每一段「开机 → 关机」的会话;一行一段,`0` 是本次,`-1` 是上次。

 

**Q: `--list-boots` 是无上限的总开机计数器吗?**

A: 不是;只列日志还留着的场次,日志删了对应的行也会消失。

 

**Q: `--disk-usage` 回答什么?**

A: journal 一共占多少磁盘;归档的和正在写的都算。

 

**Q: `systemd`、`systemctl`、`journald`、`journal`、`journalctl` 各是什么?**

A: 两个后台(`systemd` 管服务、`journald` 收日志)+ 两个命令(`systemctl` 控服务、`journalctl` 查日志)+ `journal` 是日志数据本身。

 

**Q: `logger -t` 和 `journalctl -t` 各干什么?**

A: `logger -t` 写时贴标签;`journalctl -t` 读时按标签筛。

 

**Q: 用 `logger` 造一条再捞回来,验证了什么、没验证什么?**

A: 验证「写 → 收 → 存 → 查」这条链路通了;没验证别的日志源、轮转、远程转发、真实应用格式,`-s` 屏幕有输出也不算持久化。

 

**Q: logrotate 的 `rotate` / `compress` / `copytruncate` / `postrotate` 各管什么?**

A: `rotate` 留几代老的;`compress` 压老代;`copytruncate` 复制 + 原地清空;`postrotate` 轮转后通知程序重开。

 

**Q: `copytruncate` 的代价是什么?**

A: 复制和清空之间有一小段窗口,可能丢日志;所以只在程序喊不动时用。

 

**Q: `-d` 和 `-f` 差在哪?**

A: `-d` 只预演,不动日志也不更新状态文件;`-f` 强制真转。

 

**Q: unit 文件三段各管什么?**

A: `[Unit]` 是什么/跟谁有关系;`[Service]` 怎么跑;`[Install]` 开机怎么挂。

 

**Q: `start` 和 `enable` 差在哪?**

A: `start` 现在跑;`enable` 建开机自启链接、不启动。

 

**Q: `stop` / `disable` / `mask` 三者边界?**

A: `stop` 现在停;`disable` 取消自启但手动还能起;`mask` 链到 `/dev/null`,连手动 `start` 都不行。

 

**Q: `Requires` 和 `After` 为什么是两套?**

A: 依赖管要不要,顺序管先先后;只写 `Requires` 可能同时启动,只写 `After` 不会拉起对方;要写两个。

 

---

 

## 总结(50字以内,用自己的话概括今天学到了什么)

 

块 3 五条验收补完:日志四段看线索、journalctl 四限定、logger 验链路、logrotate 四关键词、systemd 三段与启停边界。

 

---

 

## 复习卡片

 

| 概念 | 必学/了解 | 一句话 | 场景 |

| --------------------- | --------- | --------------------------------------------------------- | -------------- |

| 一行日志四段 | 必学 | 时间 / 主机 / 程序[PID] / 正文 | 读日志 |

| 正文局限 | 必学 | 应用自己写的,不是结构化事实 | 判结论 |

| `-u` | 必学 | 按单元/服务筛 | 查某服务 |

| `-b` | 必学 | 按开机筛(`0` 本次,`-1` 上次) | 跨开机 |

| `-p` | 必学 | 按级别筛,含更严重;数字越小越严重 | 找错误 |

| `--since` / `--until` | 必学 | 时间窗 | 限定时间 |

| `-n` | 必学 | 最多几条,不是配额 | 限条数 |

| `--list-boots` | 必学 | 列开机会话,一行一段 | 选开机 |

| `--disk-usage` | 必学 | journal 占多少磁盘 | 查占用 |

| `systemd` | 必学 | 后台总管家(PID 1) | 服务管理 |

| `systemctl` | 必学 | 控制 systemd 的命令 | 起停服务 |

| `journald` | 必学 | 收日志的后台 | 日志收集 |

| `journal` | 必学 | 日志数据本身 | 存储 |

| `journalctl` | 必学 | 查 journal 的命令 | 查日志 |

| `logger -t` | 必学 | 写一条带 tag 的测试日志 | 验证链路 |

| `journalctl -t` | 必学 | 按 tag 捞日志 | 验证链路 |

| `rotate N` | 必学 | 留 N 代老的,总数 1 + N | 轮转配置 |

| `compress` | 必学 | 老代压缩(gzip → `.gz`) | 省空间 |

| `delaycompress` | 必学 | 晚一轮再压 | 程序还没松手 |

| `copytruncate` | 必学 | 复制 + 原地清空;喊不动时用 | 不能重开的程序 |

| `postrotate` | 必学 | 轮转后通知程序重开 | 能重开的程序 |

| `-d` | 必学 | 预演,不动文件/状态 | 改配置前 |

| `-f` | 必学 | 强制真转 | 测试 |

| `[Unit]` | 必学 | 是什么/关系 | unit 三段 |

| `[Service]` | 必学 | 怎么跑 | unit 三段 |

| `[Install]` | 必学 | 开机怎么挂 | enable/disable |

| `start` | 必学 | 现在跑 | 立即启动 |

| `enable` | 必学 | 建开机自启链接,不启动 | 开机自启 |

| `stop` | 必学 | 现在停 | 立即停止 |

| `disable` | 必学 | 删自启链接,手动还能起 | 取消自启 |

| `mask` | 必学 | 链到 `/dev/null`,手动也不行 | 彻底封死 |

| `Requires` | 必学 | 强依赖 | 依赖 |

| `After` | 必学 | 顺序 | 先后 |

| `Wants` | 必学 | 弱依赖,失败也照跑 | 依赖 |

| 了解层(合并一行) | 了解 | `BindsTo` / `Requisite` / `.requires/` / `mask --runtime` | 用到再查 |

 

---

 

## 旧知识回收(今天暴露出来的)

 

| 概念 | 一句话 | 出处 |

| ------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------- |

| inode 不存文件名 | 文件名在**目录**里(名字 → inode 号的对照表) | 今天 Q2;09-30 曾答成「存 inode 号」后重考 |

| `df` / `du` | `df` 看账本、`du` 挨家数;对不上五条:删 / 留 / 挂 / 权 / 稀 | 今天 Q3 先答不出,补地基后用「删 / 挂 / 权」三个场景通过 |

| 5% 预留 | 是文件系统的空闲空间,归 `df` 看;不是 `du` 数的文件 | 用户曾误以为 `sudo` 会把 5% 加进去 |

| `remove` vs `purge` | `remove` 留配置、`purge` 连配置删;看 `dpkg -l` 的 `rc` vs 整行消失 | 今天 Q4 答对 |

| `/var` / `/usr` | `/var` 放会变的;`/usr` 放软件;`usr` 原始 = user,现代解作 Unix System Resources | 今天 Q1 已答对,跳过不重考 |

| `-n` 两义 | `journalctl -n` = 条数;`logger -n` = 远程服务器 | 今天讲 logger 时点出 |

 

---

 

## 今日产出验收

 

| 条 | 标准 | 结果 / 证据 |

| --- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

| ② | 读懂一行日志四段,说清为什么正文不能单独当结论 | ✅ 拆对 `Oct 19 19:24:28 / AR-firefly / systemd-resolved[79] / 正文`;重考答出「只是线索,频率/谁/时间/上下文不知道,正文是程序写的,不一定事实」 |

| ③ | 会用 journalctl 按 unit / boot / 优先级 / 时间限定;知道 `--list-boots`、`--disk-usage` | ✅ 写出并跑通 `-u systemd-resolved`、`-b`、`-p err`、`--since "10 min ago"`,组合命令 `-u ... -p err -b --since ...` 跑通(`-- No entries --` 是空结果,不是报错);说清 `--list-boots` = 开机会话目录、`--disk-usage` = 占磁盘 |

| ④ | 用 `logger` 造带 tag 的日志并捞回;说清验证/没验证什么 | ✅ 亲手跑 `logger -t AIDC '自己的测试内容'` + `journalctl -t AIDC -n 3` 捞回;说清验证「写→收→存→查」,没验证其他来源/轮转/远程/真实应用 |

| ⑤ | 读懂 logrotate 配置;`rotate` / `compress` / `copytruncate` / `postrotate` 各管什么;`-d` 预演 | ✅ 读本机配置;说清 `rotate 4` = 留 4 代老的(总 5 个)、`compress`/`delaycompress`、`postrotate`;`copytruncate` 选对并纠正为「先复制再清空」;`-d` 与 `-f` 区别、`-d` 不动文件/状态说清 |

| ⑥ | unit 三段;`start` vs `enable`;`stop` vs `disable`;`disable` vs `mask`;`Requires`/`After` | ✅ 三段职责说清(「unit告诉你这是什么和各文件间的关系,service告诉你怎么跑,install告诉怎么挂链接」);`start`/`enable`、`stop`/`disable`/`mask`、`Requires`/`After` 全部答对,明确「两个都要写」 |

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值