Linux Day16——日志


type: learning-note

title: Linux:日志全景------日志从哪来、存在哪、长什么样

date: 2026-10-08

description: 日志两个用途(排障/审计)、三个前提、链路四步、journald 与 rsyslog 并存、日志路径不能背要现查、一行四段、一行的局限、less/tail -n/tail -F 分工、--since 框时间窗、grep -n -C 3 带上下文、轮转边界;含今天拧正的点(/var 与 /usr、ps 第一列是用户、目录 x 只管通行)与旧知识回收


2026-10-08 学习笔记

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

笔记区

核心观点

**日志的两个用途:排障 + 审计**

原文(LabEx 官方中文版 `system-logging`):

> 日志记录由内核、服务、应用程序和安全组件发出的事件。它们可以帮助**排查问题和审计**,但前提是收集功能正常、时间戳得到正确理解,并且相关来源已包含在内。

**判据不是"日志长什么样",是"你要拿它回答什么问题"**:

| 用途 | 要回答的问题 | 问的是谁 |

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

| 排障 | 出了什么事、**为什么** | 机器 / 服务 |

| 审计 | **谁**、什么时候、做了**什么** | 人(账号) |

**同一条日志,两个用途都能用。** 用途不是日志上的标签,是**你带着的问题**决定的。

  • `session opened for user ar-26710`:审计问"谁登进来了"→答上了;排障问"连不上是**没登上**还是**登上了又断**"→有这条说明登上了,问题在别处

  • `systemd-logind: The system will power off now!`:这条是**正常**关机,但能拿来**排障**(问"机器为什么关了"→答上了:不是崩的,是走了正常关机流程)

**日志的三个前提**

> 但前提是**收集功能正常、时间戳得到正确理解,并且相关来源已包含在内**。

| 前提 | 具体 | 不满足会怎样 |

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

| ① 收集在跑 | 收集器(journald / rsyslog)活着 | 那段时间日志**空白**,但事情发生了 |

| ② 时间戳理解对 | 时区设对 + 时钟同步 | 按时间找,找到的是**错位**的行 |

| ③ 相关来源被包含 | 路由规则把它收进来了 | 翻 `/var/log/` 找不到那类日志 |

**三条的共同点:都是"日志里没有 ≠ 没发生"。** 这是排查时的**第一反应规则**------看到日志空白,先问"是不是收集这一环断了"。

本机三条都满足:

```

Time zone: Asia/Shanghai (CST, +0800)

System clock synchronized: yes

NTP service: active

systemd-journald: active

rsyslog: active

```

所以本机日志的时间戳带 `+08:00`(东八区记号)。

**日志链路四步(因果链,逐级依赖)**

原文:

> 1. 来源发出事件。2. 收集器接收事件并**补充信息**。3. **路由和保留**规则选择**存储位置或转发目的地**。4. 查看工具查询已存储的记录。

| 步 | 干什么 | 干完产生什么 |

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

| ① **来源** source | 事情发生,发出事件 | 一个**事件** |

| ② **收集器** collector | 接住它、补充信息 | **一条记录** |

| ③ **路由 / 保留** | 决定**存哪**、**留多久** | 记录**落到某个地方** |

| ④ **查看器** viewer | 查**已经存下来的**记录 | 读到的内容 |

**第 ④ 步依赖第 ③ 步**------记录没存下来,查看器看什么。

记忆锚:**发生 → 收下 → 存哪 → 去查**。

第 ② 步那个"**补充信息**"是关键:事件发出来可能只有一句话,**时间戳、主机名、`PID` 是收集器贴上去的**。

**`systemd-journald` 与 `rsyslog` 可并存,不是二选一**

| | systemd-journald | rsyslog |

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

| 谁自带 | systemd 自带 | 传统 syslog 的实现 |

| 写什么 | **二进制** journal(`/var/log/journal/`) | **纯文本**文件(`/var/log/syslog` 等) |

| 本机状态 | active(跑在 **root**) | active(跑在 **syslog** 用户) |

**同一条事件,两边各有一份**:

```

journal: Oct 08 17:49:47 AR-firefly systemd1: wsl-pro.service: Deactivated successfully.

syslog: 2026-10-08T17:49:47.417405+08:00 AR-firefly systemd1: wsl-pro.service: Deactivated successfully.

```

**但两边处理不完全一样**:rsyslog 会把重复消息**合并**成 `message repeated 16 times: ...`,journal 不会。

**日志路径不能背,要现查**

原文:

> 它们是很有用的起点,但**文件名和内容取决于路由策略,并不是 Linux 的统一保证**。

> 在使用兼容路由的 Debian 系发行版上,`/var/log/syslog` 很常见;其他系统则常使用 `/var/log/messages`。**只使用 journal 的主机可能没有这两个文件。**

| 同一类事件 | Debian 系(本机 Ubuntu) | Red Hat 系 |

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

| 通用日志 | `/var/log/syslog` | `/var/log/messages` |

| 认证日志 | `/var/log/auth.log` | `/var/log/secure` |

本机 `/var/log/README`(官方说明,`-> ../../usr/share/doc/systemd/README.logs`):

> You are running a systemd-based OS where traditional syslog has been **replaced with the Journal**. ...simply invoke "**journalctl**", which will output the logs in the **identical text-based format** the syslog files in /var/log used to be.

> ...implementations such as syslog-ng or **rsyslog may be installed side-by-side with the journal**.

两种机器:

  • **只有 journal** → `/var/log` 里那些传统文本文件**没有**

  • **额外装了 rsyslog** → 有,且与 journal **并存**(本机是这一种)

**现查三条命令**

| 命令 | 回答什么 |

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

| `systemctl --type=service --state=running \| grep -E 'journal\|syslog'` | **谁**在往日志里写 |

| `ls -la /var/log` | 已经有哪些日志文件 |

| `journalctl --disk-usage` | journal 占了多大 |

**一行日志四段**

原文:

> `Jan 27 07:41:32 icebox anacron4650: Job 'cron.weekly' started`

> 其中包含**时间戳、主机、程序和 PID,最后是消息**。

本机样本:

```

2026-10-08T22:29:27.099325+08:00 AR-firefly systemd1: wsl-pro.service: Deactivated successfully.

└──────── ① 时间戳 ────────┘ └② 主机┘ └③ 程序PID┘ └──────── ④ 正文 ────────┘

```

  • `systemd1` 里的 `1` 就是 **PID**

  • ④ 是**整行剩下的部分**,可以很长、可以带特殊字符(如 `message repeated 16 times: ...`)

  • 原文用的是"**可能如下**"(may look like)------**四段是常见形态,不是铁律**(有的行程序名不带 PID,格式随发行版变)

**一行日志的局限**

原文:

> 应把消息文本视为**应用程序输出,而不是有保证的结构化事实**。检查时**时区、时钟同步、启动 ID、PID 重用,以及事件前后的记录**。

> (认证日志)**单独一行很少能够证明用户意图或确认账户已被入侵**。

| 局限 | 说明 |

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

| ① 正文是**应用自己写的** | 不是"事实" |

| ② **PID 会重复** | 本机 `CRON1309` `CRON1425` `CRON1741` `CRON1813` `CRON1856` ------ 同一程序名、五个不同 PID;反过来同一 PID 在不同时间可能是不同程序 |

| ③ **要看前后** | 单独一行证明不了什么 |

**为什么**:每一行都是**某个程序自己写的**,每个程序**只知道它自己那一小块**:

  • `systemd` 只知道"有个进程没了" → 写 `Deactivated successfully`

  • `wsl-pro-service` 知道"为什么退出" → 写 `Exiting... check if the Windows agent...`

**两个程序各说各的,拼起来才是完整故事。**

**三种看日志的工具**

原文:

> 使用 `less` 进行**可控浏览**,使用 `tail` 查看**最新记录**。

> 在有限时间的重现过程中,可用 `tail -F FILE` **跟踪新追加的行**。与简单快照不同,**当文件在轮转期间被替换时,`-F` 会重试**。使用 `Ctrl-C` 停止跟踪。

| 工具 | 干什么 | 什么场景 |

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

| `less 文件` | **翻阅**(上下滚、搜) | 要**通读**一段、慢慢找 |

| `tail -n 100 文件` | 看**最后 100 行**(快照) | 只关心**最近** |

| `tail -F 文件` | **跟着看**,新行实时显示 | 一边复现一边盯 |

`-F` 的关键:**日志轮转把旧文件换掉后,`-F` 会重新找到新文件继续盯**(普通 `tail -f` 会"瞎掉")。

`less` 操作:`空格` 翻页 / `b` 后退 / `/关键词` 搜 / `n` 下一个 / **`q` 退出**。

名字来历:`more` 只能往下翻,`less` 是升级版------"**less is more**"。

**先框时间窗**

原文:

> **应先使用有边界的查询,而不是倾倒整个 journal。**

> `journalctl --since '2026-08-31 09:00' --until '2026-08-31 09:15'`

| 选项 | 意思 |

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

| `--since` | **从**什么时候**起** |

| `--until` | **到**什么时候**止** |

时间可以写得很灵活:`"10 min ago"` / `"1 hour ago"` / `"today"` / `"2026-10-08 17:00"`。

本机实测:

```

journal 全量 52942 行

最近 10 分钟 3 行

最后 10 行 10 行

```

**两条不同的轴**:

  • `--since "10 min ago"` = 框**时间**(这 10 分钟内**所有**,条数不定)

  • `-n 10` = 框**条数**(**不管时间**,就是最后 10 条)

**`--since` 和 `--until` 方向相反**,可以一起用来"掐出某一段"。

**带上下文搜**

原文:

> `grep -n -C 3 'connection refused' /var/log/example.log`

> **既要记录成功事件,也要记录失败事件,并保留周边行,因为原因可能早于可见错误。**

| 选项 | 意思 |

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

| `-n` | 标**行号** |

| `-B 3` | 命中行**前面**带 3 行(before) |

| `-A 3` | 命中行**后面**带 3 行(after) |

| `-C 3` | **前后各带 3 行**(context) |

**本机实证**------只有带上下文才看得到:

```

89: 21:16:14 systemd1: wsl-pro.service: Scheduled restart job, restart counter is at 8.

100: 21:47:18 systemd1: wsl-pro.service: Scheduled restart job, restart counter is at 9.

109: 22:18:22 systemd1: wsl-pro.service: Scheduled restart job, restart counter is at 10.

117: 22:49:27 systemd1: wsl-pro.service: Scheduled restart job, restart counter is at 11.

```

  • **不带 `-C 3`**:只看到 10 条孤立的 `Exiting`(每约 31 分钟一条)→ 会以为"它每半小时**主动**退一次"

  • **带上**:真相是 **systemd 在无限重启它**(`restart counter is at 11`)

**轮转边界(了解层,不深挖)**

原文:

> **一次事件可能跨越日志轮转边界。** 活动文件、编号归档和压缩文件可能分别包含**同一事件序列的不同部分**。

> `zgrep -n 'connection refused' /var/log/example.log*.gz`

> **应按实际时间戳排列结果,而不是只看文件后缀。**

  • `.1` / `.2.gz` / `.3.gz` 是**同一串日志被切成几段**

  • `zgrep` / `zless` 能**直接读 `.gz`**,不用先解压

  • **按时间戳排,别按文件后缀排**

本机实证:`auth.log.2.gz` 里装的是 **9 月 29 日**的日志,而当前 `auth.log` 是 **10 月 8 日**------**只搜当前那个文件就漏了**。

关键方法/流程

  • **现查日志**(到一台新机器):`systemctl --type=service --state=running | grep -E 'journal|syslog'` → `ls -la /var/log`

  • **看一行**:`tail -n N 文件` / `less 文件`

  • **跟着看**:`tail -F 文件`(`Ctrl-C` 停)

  • **框时间**:`journalctl --since "10 min ago"`(可加 `--until`)

  • **带上下文搜**:`grep -n -C 3 '关键词' 文件`

  • **读压缩档**:`zgrep '关键词' 文件*.gz`

  • **看 journal**:`journalctl`(二进制,不能 `cat`)

  • **看服务状态**:`systemctl is-active 名字` / `systemctl --type=service --state=running`

  • **看进程**:`ps aux | grep 名字 | grep -v grep`

实战记录

**① 复习抽考:目录的 `x` 只管"通行"**

```

mkdir -p /tmp/xtest/d && touch /tmp/xtest/d/a.txt /tmp/xtest/d/b.txt

chmod 100 /tmp/xtest/d → d--x------

cd /tmp/xtest/d → 进去了

ls → Permission denied (没有 r)

```

对照(`chmod 500` = `r-x`):能 `ls`,但 `rm` / `touch` 都 `Permission denied`(没有 w)。

**② 现查收集器**

```

$ systemctl is-active systemd-journald rsyslog → active / active

$ ls -d /var/log/*/ → apt/ chrony/ dist-upgrade/ journal/ landscape/ private/ unattended-upgrades/

$ ps aux | grep -E 'rsyslog|systemd-journald' → root 47 systemd-journald / syslog 210 rsyslogd

```

**③ 读 `/var/log/README`**------官方说明 journal 与 rsyslog 的关系

**④ 标四段**

```

2026-10-08T22:49:27.267866+08:00 AR-firefly systemd1: Started wsl-pro.service - Bridge to Ubuntu Pro agent on Windows.

时间戳:2026-10-08T22:49:27.267866+08:00

主机:AR-firefly

程序:systemd1

正文:Started wsl-pro.service - Bridge to Ubuntu Pro agent on Windows

```

**⑤ 一行 vs 上下文**

```

106: 21:58:22.846364 wsl-pro-service1823: WARNING Exiting after <nil>: check if the Windows agent is installed and running.

107: 21:58:22.852580 systemd1: wsl-pro.service: Deactivated successfully.

```

只看 107 → "服务停用成功,像正常";加 106 → **是它自己退出的**(连不上 Windows agent)。

**⑥ 时间窗**

```

$ journalctl --since "10 min ago" --no-pager → -- No entries --

```

(跑的时候那几条已经**出窗**了------"查不到"≠"没发生",也可能是**范围不对**)

**⑦ 带上下文搜出重启循环**------见上面"带上下文搜"

**⑧ `--until` 存在**

```

$ journalctl --until "10 min ago" --no-pager | wc -l → 52942

```

**⑨ `zgrep` 跨档搜**

```

$ zgrep -n 'session opened' /var/log/auth.log*.gz

/var/log/auth.log.2.gz:1:2026-09-20T00:17:01 ... CRON13544: ... session opened ...

```


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

**Q: 日志的两个用途是什么?判据是看日志的哪一部分?**

A: 排障 + 审计。判据**不是看日志长什么样**,是看**你要拿它回答什么问题**------排障问"出了什么事/为什么",审计问"谁/什么时候/做了什么"。

**Q: 同一条日志能同时属于两个用途吗?**

A: 能。用途不是日志上的标签,是你带着的问题决定的。`session opened` 最常见是审计,但"SSH 连不上、到底是**根本没登上**还是**登上又断**"这个问题,也用它回答。

**Q: 日志可信的三个前提是什么?三条的共同点是什么?**

A: ① 收集在跑 ② 时间戳理解对 ③ 相关来源被包含。共同点:**都是"日志里没有 ≠ 没发生"**。

**Q: 日志链路四步是哪四步?哪一步决定"存哪"?**

A: 来源 → 收集器 → 路由/保留 → 查看器。**第 ③ 步**(路由/保留)定"存哪、留多久"。

**Q: 为什么查看器必须在最后?**

A: 四步是**因果链**,第 ④ 步依赖第 ③ 步------记录没存下来,查看器看什么。

**Q: `systemd-journald` 和 `rsyslog` 是什么关系?**

A: **可并存,不是二选一**。journald 写二进制 journal、rsyslog 写纯文本文件,同一条事件两边各收一份(内容可能不同:rsyslog 会合并重复消息)。

**Q: 为什么不能背"日志在 `/var/log/syslog`"?**

A: 文件名**取决于发行版和路由配置**,不是 Linux 统一保证。Debian 系 `syslog` / RH 系 `messages`;只跑 journal 的机器两个都没有。**要现查**。

**Q: 到一台新机器,怎么现查"日志在哪、谁在写"?**

A: `systemctl --type=service --state=running | grep -E 'journal|syslog'`(谁在写)+ `ls -la /var/log`(有哪些文件)。

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

A: 时间戳 / 主机 / 程序PID / 正文。

**Q: `journalctl` 是干什么的?为什么不能直接 `cat` journal?**

A: 它是读 journal 的**查看器**。journal 是**二进制**(压缩、带索引),`cat` 出来是乱码;`journalctl` 负责解出来、用文本格式打出来。

**Q: `journalctl` 默认时间戳 `Oct 08 22:54:30` 比 syslog 里的少了哪两样?各会带来什么麻烦?**

A: 少**年份**、少**时区**。缺年份 → 跨年翻日志分不清先后;缺时区 → 换台 UTC 的机器,时间跟手表差 8 小时。

**Q: 为什么说"单独一行日志证明不了什么"?**

A: 正文是**应用自己写的输出**不是事实;每个程序**只知道它那一小块**(`systemd` 只知道"进程没了",不知道"为什么")。加上下文才拼出完整故事。

**Q: `less`、`tail -n`、`tail -F` 各什么场景?**

A: `less` 翻阅(通读、搜);`tail -n` 看最后 N 行(快照);`tail -F` 跟着看(实时,**轮转后还会重新接上**)。

**Q: `--since "10 min ago"` 和 `-n 10` 差在哪?**

A: 两条**不同的轴**------`--since` 框**时间**(这 10 分钟内所有,条数不定),`-n 10` 框**条数**(不管时间,最后 10 条)。

**Q: `--since` 和 `--until` 方向一样吗?**

A: **相反**。`--since` = 从某时刻**往后**到现在;`--until` = 从最早到某时刻(把之后的开除)。

**Q: 为什么搜日志要带 `-C 3`?**

A: **原因常出现在命中行的前后**。不带就只能看到孤立的一行、看不出因果------本机那个例子:不带只看到 10 条 `Exiting`,带上才看到 `restart counter is at 11`(**服务在无限重启**)。

**Q: 轮转档是什么?(了解层)**

A: `.1` / `.2.gz` / `.3.gz` 是**同一串日志被切成几段**;`zgrep` 能直接读 `.gz`;**按时间戳排,别按后缀排**。


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

日志从哪来(四步链路)、在哪(要现查不能背)、长什么样(四段)、怎么捞(框时间窗 + 带上下文搜)。


复习卡片

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

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

| 日志两个用途 | 必学 | 排障 + 审计;用途由**你要问什么**决定 | 拿到日志先想"在问什么" |

| 三个前提 | 必学 | 收集在跑 / 时间戳对 / 来源被包含 | **日志没有 ≠ 没发生** |

| 链路四步 | 必学 | 来源 → 收集器 → 路由/保留 → 查看器 | 讲日志怎么流动 |

| 收集器"补充信息" | 必学 | 时间戳/主机/PID 是收集器**贴上去的** | 理解四段的来源 |

| journald vs rsyslog | 必学 | **可并存**;二进制 vs 纯文本 | 看日志服务 |

| 不能背路径 | 必学 | Debian `syslog` / RH `messages`;只跑 journal 的都没有 | 换机器 |

| 现查两条 | 必学 | `systemctl ... --state=running` + `ls -la /var/log` | 到新机器第一步 |

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

| 一行 ≠ 事实 | 必学 | 正文是应用输出;**PID 会重复**;要看前后 | 别单行下结论 |

| `journalctl` | 必学 | 读 journal 的工具(二进制得靠它解) | 看 journal |

| journal 默认时间戳 | 必学 | `Oct 08 22:54:30` ------ **缺年份、缺时区** | 跨年/跨时区 |

| `less` | 必学 | 翻阅;`q` 退、`/` 搜 | 通读 |

| `tail -n` | 必学 | 最后 N 行(快照) | 看最近 |

| `tail -F` | 必学 | 跟着看;**轮转后重试** | 复现时盯着 |

| `--since` / `--until` | 必学 | 从...起 / 到...止;**方向相反** | 框时间 |

| `-n` vs `--since` | 必学 | 条数 vs 时间,两条轴 | 别混 |

| `grep -n -C 3` | 必学 | 前后各带 3 行 + 行号 | **日志 grep 排查的核心** |

| `-A` / `-B` / `-C` | 必学 | after / before / 前后 | 记选项 |

| `zgrep` / `zless` | 了解 | 直接读 `.gz` | 跨轮转边界 |

| 轮转档 | 了解 | `.1` / `.2.gz` 是同一串日志的片段;按时间戳排不按后缀 | 搜不到时往外找 |


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

| 概念 | 一句话 | 出处 |

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

| **目录的 `x` 只管"通行"** | 目录 `x` = 能进去/能穿过;**`r` 才管能不能列、`w` 才管能不能建删** | 今天抽考 09-08:答"能进去**操作**",用 `chmod 100` 反例撞破 |

| **改权限的人 = 主人 + root** | 机制是系统查"**你是不是主人**",**不看 rwx** | 今天抽考 09-08:**漏了 root**,且把机制说成目的("防止别人搞烂") |

| **`ls -ld` 看目录自己** | 加 `-d` 才不展开;`ls -l 目录` 列的是**里面** | 今天抽考 09-08:答 `ls -l`,差一个 `d` |

| **`/var` vs `/usr`** | `/var` = **会变**的(日志/缓存/spool);`/usr` = 放**软件** | 点 6 练里记反了(说"日志该放 /usr") |

| **`ps aux` 第一列是 USER** | 第 1 列 = **谁在跑**(用户名);最后一列 `COMMAND` 才是程序 | 点 6 练里把 `syslog`(用户)当成程序 |

| **`grep` 会把表头滤掉** | `ps aux \| grep xxx` 时表头那行不含关键词 → 被滤掉 → 看不到列名 | 同上,这是误读第 1 列的直接原因 |

相关推荐
小HANN1 小时前
华为云企业网站上云实战|从零搭建高可用WordPress(ECS+RDS+ELB+弹性伸缩+云监控全流程落地)
linux·运维·服务器·经验分享
eBest数字化转型方案2 小时前
经销商对账自动化:从五本账模型到票据识别的工程实现
运维·自动化
Elastic 中国社区官方博客2 小时前
AWS 自动化根因分析:从 CloudWatch 告警到完成故障诊断,仅需 36 秒
大数据·运维·elasticsearch·自动化·aws
susplus2 小时前
【IMX6ULL Linux系统移植】SD卡分区 | uboot详解
linux·arm·u-boot
@三十一Y2 小时前
Linux:实现简易的shell
linux
智能直播2 小时前
OpenGL驱动的实时绿幕抠图:GPU着色器色度键控原理
运维·服务器
HUIBUR科技3 小时前
多系统整合不必搭建中台:AI中枢带来轻量化数字化集成
大数据·运维·人工智能
凯歌的博客3 小时前
docker镜像代理
运维·docker·容器
2301_777998343 小时前
TCP连接断开:进程终止、主机断电与网络断开
linux·服务器·网络·tcp/ip