--- 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>