隨著 systemd 成了主流的 init 系統(tǒng),systemd 的功能也在不斷的增加,比如對(duì)系統(tǒng)日志的管理。Systemd 設(shè)計(jì)的日志系統(tǒng)好處多多,這里筆者就不再贅述了,本文筆者主要介紹 systemd journal 收集日志的三種方式:
程序使用 libc 庫(kù)中的 syslog() 函數(shù)輸出的日志
使用 printf() 函數(shù)打印的日志
任何服務(wù)進(jìn)程輸出到 STDOUT/STDERR 的所有內(nèi)容
說(shuō)明:本文的演示環(huán)境為 ubuntu 16.04。
syslog()
該函數(shù)的聲明如下:
#includevoid syslog(int priority, const char *message, ... /* argument */);
創(chuàng)建下面的 C 語(yǔ)言代碼,并保存到文件 clog.c 文件中:
#includeint main(int argc, char *argv[]) { syslog(LOG_NOTICE, "C Hello World"); return 0; }
用下面的命令編譯程序:
$ gcc -Wall clog.c -o clog
然后執(zhí)行編譯好的 clog 程序,就可以從 journal -f 的輸出中看到對(duì)應(yīng)的日志:
這里筆者執(zhí)行了三次 clog 程序,所以日志輸出了三遍。
代碼中的 LOG_NOTICE 代表日志的嚴(yán)重等級(jí),我們可以使用下面定義好的等級(jí):
#define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but significant condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */
下面嘗試在 python 代碼中做同樣的事情,把下面的代碼保存到文件 plog.py 中:
#!/usr/bin/evn python import syslog syslog.syslog('P Hello World')
然后執(zhí)行下面的命令:
$ python plog.py
筆者同樣執(zhí)行了三遍,這次輸出的是 python 代碼中的日志。
我們還可以通過 journalctl -o json-pretty -f 命令查看 json 格式的日志:
printf()
journal 可以捕獲服務(wù)進(jìn)程往 STDOUT/STDERR 輸出的所有內(nèi)容,比如 C 語(yǔ)言中 print 函數(shù)打印的內(nèi)容,Python 中 print 打印的內(nèi)容,以及 Shell 腳本中 echo 打印的內(nèi)容等等都可以被 journal 捕獲到并加入到日志中。注意,只有以 service 的方式運(yùn)行程序時(shí),journal 才會(huì)捕獲 STDOUT/STDERR 輸出的內(nèi)容。
創(chuàng)建下面的 C 語(yǔ)言代碼,并保存到文件 printlog.c 文件中:
#includeint main(int argc, char *argv[]) { printf("C Print Hello World. "); return 0; }
用下面的命令編譯程序:
$ gcc -Wall printlog.c -o printlog
配置一個(gè)簡(jiǎn)單的 service,先創(chuàng)建 一個(gè)配置文件 /lib/systemd/system/testlog.service,其內(nèi)容如下:
[Unit] Description=test log [Service] ExecStart=/home/nick/projects/journaldemo/printlog [Install] WantedBy=multi-user.target
$ sudo systemctl daemon-reload $ sudo systemctl start testlog.service
Journal 會(huì)捕獲 STDOUT/STDERR 輸出的內(nèi)容:
默認(rèn)情況下,這樣輸出的日志等級(jí)為 LOG_INFO(6),我們可以通過 json 格式的日志看到日志等級(jí)信息:
我們還可以在打印日志時(shí)指定日志的等級(jí),比如在每行打印的內(nèi)容前加上"
#include#define PREFIX_NOTICE "<5>" int main(void){ printf(PREFIX_NOTICE "Hello World "); fprintf(stderr, "<3>Hello Error "); return 0; }
把上面的代碼編譯為 printlog 程序,再查看下日志,顯示的就是我們自己設(shè)置的日志等級(jí):
在 Python 中的用法如下:
#!/usr/bin/env python print '<5>Hello World'
在 bash 中的用法如下:
#!/bin/bash echo "<5>Hello World"
Systemd 日志庫(kù)
Systemd 提供了原生的 C 語(yǔ)言庫(kù)(systemd/sd-journal.h) 用于向 journal 輸出日志(ubuntu 16.04 需要通過 sudo apt install libsystemd-dev 命令安裝 libsystemd-dev 包),相關(guān)函數(shù)的聲明為:
#includeint sd_journal_print(int priority, const char *format, ...); int sd_journal_send(const char *format, ...);
把下面的示例代碼會(huì)把日志發(fā)送給 journal:
#includeint main(int argc, char *argv[]) { sd_journal_print(LOG_NOTICE, "Hello World"); return 0; }
相比上文使用 print() 或者 syslog() 提交的日志,使用 sd_journal_print 可以直觀的指定 LOG 等級(jí)、日志內(nèi)容等等,另外輸出的日志會(huì)包含執(zhí)行代碼的位置信息,例如執(zhí)行到的函數(shù),代碼文件位置,代碼具體行數(shù),方便開發(fā)人員調(diào)試。
除了可以包含代碼信息,也可以向提交的日志中加入自定義段包含更多自定義信息,配合 journalctl 工具,可以更方便的過濾日志,如下面的代碼:
#include#include #include int main(int argc, char *argv[]) { sd_journal_send("MESSAGE=Hello World!", "MESSAGE_ID=52fb62f99e2c49d89cfbf9d6de5e3555", "PRIORITY=5", "HOME=%s", getenv("HOME"), "TERM=%s", getenv("TERM"), "PAGE_SIZE=%li", sysconf(_SC_PAGESIZE), "N_CPUS=%li", sysconf(_SC_NPROCESSORS_ONLN), NULL); return 0; }
我們?cè)谌罩局刑砑恿俗远x的字段,并且可以通過 journalctl 過濾這些字段。
除了 systemd 提供的一套C語(yǔ)言庫(kù),目前其他個(gè)別語(yǔ)言也衍生了 systemd 的相關(guān)擴(kuò)展,其中就包含了和 journald 相關(guān)的擴(kuò)展。下面是段 python 的演示代碼:
from systemd import journal journal.send('Hello world') journal.send('Hello, again, world', FIELD2='Greetings!', FIELD3='Guten tag')
在運(yùn)行上面的代碼前你需要先通過 pip 安裝 python 的 systemd 模塊(pip install systemd ),然后運(yùn)行這段代碼,你就可以從日志中看到它輸出的信息了:
展開成 json 格式看下:
我們自定義的字段 FIELD2 和 FIELD3 也都輸出到日志中了。
總結(jié)
本文介紹了常見的一些往 systemd journal 中寫入日志的方式,了解這些日志的寫入方式可以幫助我們更好的設(shè)計(jì)應(yīng)用的日志輸出,并有助于我們通過日志解決問題。
鏈接:https://www.cnblogs.com/sparkdev/p/10509938.html
-
程序
+關(guān)注
關(guān)注
116文章
3766瀏覽量
80763 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4285瀏覽量
62333 -
日志
+關(guān)注
關(guān)注
0文章
138瀏覽量
10626
原文標(biāo)題:高效日志管理:通過 Systemd Journal 收集日志的終極指南
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論