---
tags: 1092, LSA
---
Linux 讀書會 - 認識與分析登錄檔
===
[TOC]
## 什麼是 Log ?
- 可能是
| 對數(英語:logarithm)$$ log_2 (x)$$ |
|:---------------------------------------------:|
| ![](https://i.imgur.com/BBhgQcC.png =300x300) |
- 這次要講的是
| Log file |
|:--------------------------------------------------------------------:|
| 記錄系統在什麼時候由哪個程序做了什麼樣的行為時,發生了何種的事件等等 |
## 為什麼要有 Log
![](https://i.imgur.com/6bB3Y7B.png)
* 除錯
* 效能調教
* 稽核追蹤
* 鑑識
* 了解現況
* 備份、資料同步、回溯(常用在DB)
另外
* MySQL binary log, Oracle redo log, GIT
* log 也可拿來讓 monitor system 做近即時的狀態通報之類的,或是很簡單的統計流量或使用狀態 (eg. 把 httpd access log 用時間區段 (像是 1 min) group 就可以得到每分鐘的線上人數
> [reference - Log分析入門](https://github.com/sakura26/DADA/blob/master/log_analysis_intro.md)
## Log 的組成要件
- 以時間為主軸
- 主體(誰發起了這則 log)
- 事件描述
- 啟動此事件的服務名稱 (如 systemd, CROND 等) 或指令與函式名稱 (如 su, login..)
- 最好有 人、事、時、地、物
| 欄位 1 | 欄位 2 | 欄位 3 | 欄位 4 |
| ------ | ------ | --- | ------ |
| 事件發生的日期與時間 | 發生此事件的主機名稱 | 啟動此事件的服務名稱或指令與函式名稱 | 該訊息的實際資料內容 |
- 以 `/var/log/syslog` 為例
![](https://i.imgur.com/eMJujGx.png)
- 節錄部份做說明
![](https://i.imgur.com/btlYwBx.png)
:::success
<span class='say'>鳥哥 say:</span>
提供一個鳥哥常做的檢查方式。
當我老是無法成功的啟動某個服務時,我會在最後一次啟動該服務後,立即檢查登錄檔, 先
(1)找到現在時間所登錄的資訊『第一欄位』;
(2)找到我想要查詢的那個服務『第三欄位』,
(3)最後再仔細的查閱第四欄位的資訊,來藉以找到錯誤點。
:::
### syslog 的欄位
rsyslogd 的 syslog 格式
- TIMESTAMP
- 根據 RFC 3164 定義格式是 `Mmm dd hh:mm:ss`
- `Mmm` 是英文的月份縮寫
- Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
- `hh:mm:ss` local time
- `hh` 是 24 小時制,從 00 - 23
- `mm`, `ss` 從 00 - 59
- HOSTNAME
- 用於辨別發送訊息的機器
- 一般是 hostname,如果沒有會用 IP address
- 如果有多組 IP,則以傳送訊息的 interface 的 IP address 為準
- APP-NAME[PROCID]
- 用於辨別發送訊的 devicce 或 application 資訊
- `PROCID` process 在系統的 PID
- MSG
- 在 RFC 3164 被稱為 Content
- 自由格式
- 描述事件的資訊
- 根據 RFC 5424 定義字元集 (character set) 需要是 UNICODE
- RFC3629 指定會以 UTF-8 進行編碼(encode)
![](https://i.imgur.com/pZ43fIE.png)
[參考資料: RFC5424 - The Syslog Protocol](https://tools.ietf.org/html/rfc5424)
[參考資料: RFC3164](https://tools.ietf.org/html/rfc3164)
[參考資料: Wiki - syslog](https://en.wikipedia.org/wiki/Syslog)
[參考資料: Linux Logging Basics](https://www.loggly.com/ultimate-guide/linux-logging-basics/)
[參考資料: syslog 詳解](https://www.itread01.com/content/1548217114.html)
:::info
RFC5234 定義的 syslog 所有訊息格式
![](https://i.imgur.com/8Tl5h6Q.png)
![](https://i.imgur.com/kqVLiHM.png)
[圖片來源: RFC5424 - The Syslog Protocol](https://tools.ietf.org/html/rfc5424)
:::
> [Reference - 天菜妹ㄉ筆記](https://hackmd.io/@ncnu-opensource/By4H6JLNW/https%3A%2F%2Fhackmd.io%2F8mL0eZmORUK2kf6LstzY8w%3Fview?type=book#syslog-%E7%9A%84%E6%AC%84%E4%BD%8D)
## Log 的特性
* 訊息按照時序出現
* 出現過的訊息不會改變
* **Append Only**
![](https://i.imgur.com/IOAriNq.png)
> [The Log: What every software engineer should know about real-time data's unifying abstraction](https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying)
## Linux 常見的登錄檔檔名
- 系統重要的事件
- 僅有 root 能夠讀取
### `/var/log/boot.log`
- 開機啟動的資訊(這次, 上一次開機的不會被儲存)
### `/var/log/cron`
- crontab 排程的執行訊息
### `/var/log/dmesg`
- 可用 ` journalctl -k`
- `journalctl -k --since "2 hours ago"` 觀察最近 2 個小時以內的 log 資訊
> 節錄 `man journalctl`
>![](https://i.imgur.com/xWkiOYn.png)
> [reference - Where did the functionality of /var/log/dmesg go in xenial 16.04?](https://askubuntu.com/questions/859816/where-did-the-functionality-of-var-log-dmesg-go-in-xenial-16-04)
### `/var/log/wtmp`, `/var/log/faillog`
- 記錄正確登入系統者的帳號資訊 (wtmp)
- 錯誤登入時所使用的帳號資訊 (faillog)
- `wtmp`
- ![](https://i.imgur.com/GctbzxD.png)
- 可使用 `last` 來顯示
- ![](https://i.imgur.com/UN5nHfj.png)
> 在大型主機上看上線次數排名:
> `last | awk '{print $1}' | sort | uniq -c | sort -r`
>[name=JackKuo]
- `faillog`
- ![](https://i.imgur.com/R83wTJI.png)
:::info
`man last`
![](https://i.imgur.com/KqF6oQU.png)
:::
### `/var/log/lastlog`
- 系統上面所有的帳號最近一次登入系統時的相關資訊
- 可用 `lastlog` 指令來看此檔案的資訊
- ![](https://i.imgur.com/rZNQ0Fz.png)
- ![](https://i.imgur.com/fWHQv1u.png)
### ==補充:== `/var/log/wtmp` 與 `/var/log/lastlog`
| log file | wtmp | lastlog |
| -------- | -------- | -------- |
| 紀錄內容 | 記錄所有的登入登出紀錄,且會 **rotate** | 只記錄每位使用者最近一次的登入紀錄 |
> [Reference: wtmp 與 lastlog 差別](https://unix.stackexchange.com/questions/192078/difference-between-last-and-lastlog)
### `/var/log/maillog` 或 `/var/log/mail/*`
- 記錄郵件的往來資訊
- 主要是 postfix (SMTP 協定提供者) 與 IMAP、POP3 伺服器軟體
:::info
- SMTP : **發信**所使用的通訊協定
- POP3 : **收信**使用的通訊協定
- postfix: 達成通訊協定的軟體
:::
- ![](https://i.imgur.com/3zkmeyX.png)
### `/var/log/messages`
- 幾乎系統發生的錯誤訊息 (或者是重要的資訊) 都會記錄
- Ubuntu 已不再使用此檔案,相同的資訊被紀錄在 `/var/log/syslog`
| 檔案名稱 | `/var/log/messages` | `/var/log/syslog` |
| ---------- | --------------------- | ------------------------------------------------------------- |
| 儲存的資料 | non-critical messages | everything <br>(including critical and non-critical messages) |
- [re-enable logging to `/var/log/messages`](https://hereirestinremorse.wordpress.com/tag/ubuntu-10-04-varlogmessages/)
### `/var/log/secure`
- 只要牽涉到『需要輸入帳號密碼』的軟體,那麼當登入時 (不管登入正確或錯誤) 都會被記錄
- 在 Debian 系統中,已經找不到此檔案,相關資料儲存在 `/var/log/auth.log`
- ![](https://i.imgur.com/FSoYzd6.png)
### `/var/log/httpd/*`, `/var/log/samba/*`
- 個別服務所制訂的登錄檔
- EX: `/var/log/mosquitto/mosquitto.log`
![](https://i.imgur.com/lC7kW2N.png)
## 登錄檔所需相關服務 (daemon) 與程式
* **systemd-journald.service**:
* 最主要的訊息收受者,由 systemd 提供的
* `journalctl`
* **rsyslog.service**:
* 主要登錄系統與網路等服務的訊息
* **logrotate**:
* 主要在進行登錄檔的輪替功能
### rsyslog.service
- Linux 是否有啟動此服務
- `ps aux | grep rsyslog`
![](https://i.imgur.com/3TAPE2J.png)
- 是否有設定開機時啟動?
- `systemctl status rsyslog.service`
![](https://i.imgur.com/uYltQoz.png)
#### rsyslog 的設定檔:`/etc/rsyslog.conf`
- 記錄哪個服務的 Log 會被紀錄在哪個檔案
- `sudo vim /etc/rsyslog.d/50-default.conf`
![](https://i.imgur.com/SYooYvG.png)
- 同時也會被紀錄在
![](https://i.imgur.com/ml5vD2d.png)
- 規定內容
- (1)什麼服務
- Linux 核心的 syslog 函數自行制訂的服務名稱
![](https://i.imgur.com/NXLNdbG.png)
- `/usr/include/x86_64-linux-gnu/sys/syslog.h`會紀錄這些服務:
![](https://i.imgur.com/O4JLmM3.png)
![](https://i.imgur.com/xUKXqV9.png)
:::spoiler image info
舉例來說,sendmail 與 postfix 及 dovecot 都是與郵件有關的軟體,這些軟體在設計登錄檔記錄時,都會主動呼叫 syslog 內的 mail 服務名稱 (LOG_MAIL)。所以上述三個軟體 (sendmail, postfix, dovecot) 產生的訊息在 syslog 看起來,就會『是 mail 』類型的服務了
:::
- (2)什麼等級訊息
- 一般訊息 (information)
- 僅通知系統
- 警告訊息 (warn)
- 有出現還不至於影響到正常運作
![](https://i.imgur.com/wD49zmi.png)
- 重大問題訊息 (error 等等)
- 系統硬體發生嚴重錯誤
:::info
根據 syslog 分為 7 種等級
- 0(emerg) 到 6(info) 的等級:等級數值越高代表越沒事
- debug(錯誤偵測等級) / none (不需登錄等級):想要作一些錯誤偵測,或者是忽略掉某些服務的資訊
![](https://i.imgur.com/kVn2Iwp.png)
- 訊息等級之前的連結符號
* `.` :代表『比後面還要嚴重的等級 (含該等級) 都被記錄下來』的意思,例如: mail.info 代表只要是 mail 的資訊,而且該資訊等級嚴重於 info (含 info 本身)時,就會被記錄下來的意思。
* `.=` :代表所需要的等級就是後面接的等級而已, 其他的不要!
* `.!`:有點反向選擇的感覺,代表忽略大於等於這個等級的訊息! 亦即是低於這個等級的才會被紀錄的意思!
:::
- (3)需要被記錄在哪裡(裝置或檔案)
* 常見的放置處
* 檔案的絕對路徑:
* `/var/log`
* 印表機或其他:
* `/dev/lp0` (印表機裝置)
* 使用者名稱
* 遠端主機:
* 要對方主機也支援
* *:
* 目前在線上的所有人
### 服務、daemon 與函數名稱
| 服務、daemon 與函數名稱 | 實際用途|
|:-----------------------:|:---------------------------------------:|
| syslog | Linux 核心所提供的登錄檔設計指引 |
| rsyslogd | (軟體)進行訊息的分類 |
| rsyslog.service | (加入 systemd 的控制)啟動服務腳本設定 |
- 早期 CentOS 5.x 以前
- 要達成 syslog 的功能是由一隻名為 syslogd 的 daemon 來完成的
- 從 CentOS 6 以來 (包含 CentOS 7)
- 透過 rsyslogd 這個 daemon
### 預設的設定檔內容
![](https://i.imgur.com/J6I19LL.png)
- `auth, authpriv.*`:認證方面的訊息均寫入 `/var/log/auth.log`
- `*.*;auth,authpriv.none` : 除了認證方面的訊息,其餘皆寫入 `var/log/syslog`
- `kern.*` : 只要是核心產生的訊息,全部寫入到 `/var/log/kern.log`
- `mail.*` : 郵件方面的訊息則均寫入 `/var/log/maillog`
![](https://i.imgur.com/n9kmuSb.png)
- `*.emerg`:訊息以 wall 的方式廣播給所有在系統登入的帳號得知
:::info
檔案前的 `-` 是幹麻用的?
- 對應的檔案訊息很大量,因此會先存入 buffer,再大量寫入
- 優點:益於存取性能
- 缺點:不正常關機可能導致部份 log 還未寫入
:::
### 自行增加登錄檔檔案功能
1. 在 `/etc/rsyslog.d/` 目錄底下新增 `test.conf`
![](https://i.imgur.com/Xdxi9VP.png)
2. 內容自定義如下:
![](https://i.imgur.com/1BaoDnO.png)
3. 重新啟動服務:`sudo systemctl restart rsyslog.service`
![](https://i.imgur.com/exfpNgf.png)
### 登錄檔伺服器的設定
## 登錄檔的輪替 — `logrotate`
| rsyslog | logrotate |
|:------------------------:|:--------------:|
| 以 daemon 的方式隨時啟動 | 規定的時間執行 |
- 查看 `/etc/cron.daily/` 可以找到 `logrotate`
![](https://i.imgur.com/ykw5Yqp.png)
### 設定檔
設定 在什麼狀態下才將登錄檔進行輪替
![](https://i.imgur.com/eNeU6aG.png)
- `/etc/logrotate.conf`
- 我的電腦裡找不到了 :D
- `/etc/logrotate.d/`
- 以 `/etc/logrotate.d/syslog` 為例
![](https://i.imgur.com/cRu1HdM.png)
```
登錄檔的絕對路徑檔名 ... {
個別的參數設定值,如 monthly, compress 等等
}
```
* rotate 7:保留 7 個登錄檔
* daily:每天對登錄檔進行 1 次 rotate 的工作
* daily (每天)
* weekly (每星期)
* monthly (每月)
* yearly (每年)
* missingok
* 日誌不存在,分析下一個
* notifempty
* 空檔案不轉儲
* compress:進行壓縮工作
* postrotate
* endscript
- 執行腳本:可呼叫外部指令來進行額外的命令下達,這個設定需與 `sharedscripts`, ` endscript` 設定合用才行。至於可用的環境為:
- `prerotate`:在啟動 logrotate 之前進行的指令,例如修改登錄檔的屬性等動作
- `postrotate`:在做完 logrotate 之後啟動的指令,例如重新啟動 (kill -HUP) 某個服務
## systemd-journald.service
### 使用 `journalctl` 觀察登錄資訊
- 怎麼用呢?
- `man journalctl`
- 自己看 😈
- 舉例:
- 想看特定時間段的 log
- `journalctl --since "2020-09-01 00:00:00" --until "2020-10-31 00:00:00"`
- 列出所有錯誤訊息
- `journalctl -p err`
- 簡單測試:
- 開 2 個 terminal
- terminal 1: `journalctl -f`
![](https://i.imgur.com/4BKkrrr.png)
- terminal 2(寄信): `echo "testing" | mail -s 'test' <user_name>`
![](https://i.imgur.com/haKDO2S.png)
## 分析登錄檔
### `logwatch`
* `sudo apt install logwatch`
![](https://i.imgur.com/UmGMFuz.png)
![](https://i.imgur.com/uBgkLer.png)
* 將身份轉為 root 去收信(會每天自動寄信給 root)
![](https://i.imgur.com/AxsiXl5.png)
* ` /usr/share/logwatch/default.conf/logwatch.conf` 查看寄信對象
* 以 service 去觀察(以 ssh 為例)
![](https://i.imgur.com/KS63eQk.png)
### python logging
簡單實作一下
使用 python 的 `logging` 模組印出程式的系統訊息
| 等級 | 等級數值 | 輸出函數 | 說明 |
|:--------:|:--------:|:--------------------:|:--------:|
| NOTSET | 0 | 無對應的輸出函數 | 未設定 |
| DEBUG | 10 | `logging.debug()` | 除錯 |
| INFO | 20 | `logging.info()` | 訊息 |
| WARNING | 30 | `logging.warning()` | 警告 |
| ERROR | 40 | `logging.error()` | 錯誤 |
| CRITICAL | 50 | `logging.critical()` | 嚴重錯誤 |
```python=
# 我是裸奔的程式 A_A
import logging
# 等級設為 debug 所有訊息都會顯示
# logging.basicConfig(level=logging.DEBUG)
# 6 level of logging message
print('====== Number og each level ======')
print('\tNOTSET:\t',str(logging.NOTSET)) # 0
print('\tDEBUG:\t', str(logging.DEBUG)) # 10
print('\tINFO:\t',str(logging.INFO)) # 20
print('\tWARNING:',str(logging.WARNING)) # 30
print('\tERROR:\t',str(logging.ERROR)) # 40
print('\tCRITICAL:',str(logging.CRITICAL)) # 50
print('\n==================================')
print('====== 等級高於 info 才會印出 ======\n')
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
print('\n==================================')
print('======== test exception ==========\n')
try:
x = 5 / 0
y = 2 + 3
except:
print('* debug: ')
logging.debug('Catch an exception.', exc_info=True)
print('* info: ')
logging.info('Catch an exception.', exc_info=True)
print('* warning: ')
logging.warning('Catch an exception.', exc_info=True)
print('* critical: ')
logging.critical('Catch an exception.', exc_info=True)
```
> 可將 `logging.basicConfig(level=logging.DEBUG)` 註解拿掉,觀看輸出差異
## 補充
* `rsyslog` vs `journald`
> The Journal is a component of systemd that is responsible for viewing and management of log files. It can be used in parallel, or in place of a traditional syslog daemon, such as rsyslogd.
> By default, rsyslogd uses the imjournal module as a default input mode for journal files.
> With persistent logging enabled, journal files are stored in /var/log/journal which means they persist after reboot. Journal can then replace rsyslog for some users (but see the chapter introduction).
## Reference
* [鳥哥 — 認識與分析登錄檔](http://linux.vbird.org/linux_basic/0570syslog.php)
* [POGA — 萬事萬物皆是 LOG — 系統架構也來點科普](https://medium.com/@poga/%E8%90%AC%E4%BA%8B%E8%90%AC%E7%89%A9%E7%9A%86%E6%98%AF-log-%E7%B3%BB%E7%B5%B1%E6%9E%B6%E6%A7%8B%E4%B9%9F%E4%BE%86%E9%BB%9E%E7%A7%91%E6%99%AE-caf3029359f8)
* [The Log: What every software engineer should know about real-time data's unifying abstraction](https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying)
* [The Log song](https://www.youtube.com/watch?v=2C7mNr5WMjA&t=24s)
* [Using the Journal](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-viewing_and_managing_log_files#s1-Using_the_Journal)
* [23.7. Interaction of Rsyslog and Journal](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-viewing_and_managing_log_files#s1-interaction_of_rsyslog_and_journal)
* [23.10.5. Enabling Persistent Storage](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-viewing_and_managing_log_files#s2-Enabling_Persistent_Storage)
<style>
.say {
background-color: gray;
color: white;
font-size: 20px;
font-weight: bolder;
border-radius: 50% 20% / 10% 40%;
}
</style>