0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

systemd journal收集日志的三種方式

馬哥Linux運(yùn)維 ? 來(lái)源:博客園sparkdev ? 2024-10-23 11:50 ? 次閱讀

隨著 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ù)的聲明如下:

#include 
void syslog(int priority, const char *message, ... /* argument */);

創(chuàng)建下面的 C 語(yǔ)言代碼,并保存到文件 clog.c 文件中:

#include 


int 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)的日志:

e61b4f56-9081-11ef-a511-92fbcf53809c.png

這里筆者執(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

e6352da4-9081-11ef-a511-92fbcf53809c.png

筆者同樣執(zhí)行了三遍,這次輸出的是 python 代碼中的日志。

我們還可以通過 journalctl -o json-pretty -f 命令查看 json 格式的日志:

e63f5090-9081-11ef-a511-92fbcf53809c.png

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 文件中:

#include 


int 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)容:

e6690d86-9081-11ef-a511-92fbcf53809c.png

默認(rèn)情況下,這樣輸出的日志等級(jí)為 LOG_INFO(6),我們可以通過 json 格式的日志看到日志等級(jí)信息

e67a16c6-9081-11ef-a511-92fbcf53809c.png

我們還可以在打印日志時(shí)指定日志的等級(jí),比如在每行打印的內(nèi)容前加上"",N為需要指定的日志等級(jí)??聪旅娴?C 語(yǔ)言示例:

#include


#define PREFIX_NOTICE "<5>"


int main(void){
  printf(PREFIX_NOTICE "Hello World
");
  fprintf(stderr, "<3>Hello  Error
");


  return 0;
}

把上面的代碼編譯為 printlog 程序,再查看下日志,顯示的就是我們自己設(shè)置的日志等級(jí):

e6949f0a-9081-11ef-a511-92fbcf53809c.png

在 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ù)的聲明為:

#include 
int sd_journal_print(int priority, const char *format, ...);
int sd_journal_send(const char *format, ...);

把下面的示例代碼會(huì)把日志發(fā)送給 journal:

#include 


int 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)行這段代碼,你就可以從日志中看到它輸出的信息了:

e6afbf24-9081-11ef-a511-92fbcf53809c.png

展開成 json 格式看下:

e6ce5eac-9081-11ef-a511-92fbcf53809c.png

我們自定義的字段 FIELD2 和 FIELD3 也都輸出到日志中了。

總結(jié)

本文介紹了常見的一些往 systemd journal 中寫入日志的方式,了解這些日志的寫入方式可以幫助我們更好的設(shè)計(jì)應(yīng)用的日志輸出,并有助于我們通過日志解決問題。

鏈接:https://www.cnblogs.com/sparkdev/p/10509938.html

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 程序
    +關(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)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    伺服電機(jī)的三種控制方式

    伺服電機(jī)控制方式有脈沖、模擬量和通訊這三種,在不同的應(yīng)用場(chǎng)景下,我們?cè)撊绾芜x擇伺服電機(jī)的控制方式呢?
    發(fā)表于 08-17 11:01 ?7035次閱讀

    三種復(fù)位方式比較

    三種復(fù)位方式比較
    發(fā)表于 08-16 17:31

    步進(jìn)電機(jī)的三種驅(qū)動(dòng)方式

    步進(jìn)電機(jī)的三種驅(qū)動(dòng)方式
    發(fā)表于 01-12 17:03

    請(qǐng)問stm32啟動(dòng)的三種方式是什么意思?

    請(qǐng)群主詳細(xì)解釋下這三種啟動(dòng)方式,看了參考資料不是很明白其意!謝謝!
    發(fā)表于 07-17 04:35

    常見的三種無(wú)線接入方式是什么?

    藍(lán)牙無(wú)線組網(wǎng)的優(yōu)點(diǎn)是什么?常見的三種無(wú)線接入方式是什么?藍(lán)牙無(wú)線組網(wǎng)原理與上網(wǎng)方案分享
    發(fā)表于 05-26 06:33

    STM32三種啟動(dòng)方式是什么

    STM32三種啟動(dòng)方式是什么
    發(fā)表于 12-15 07:16

    壓供電系統(tǒng)的三種運(yùn)行方式

    我國(guó)低壓供電系統(tǒng)的三種運(yùn)行方式:國(guó)低壓供電系統(tǒng)主要有三種運(yùn)行方式:TN系統(tǒng)、TT系統(tǒng)、lT系統(tǒng)。
    發(fā)表于 05-26 17:06 ?9957次閱讀
    壓供電系統(tǒng)的<b class='flag-5'>三種</b>運(yùn)行<b class='flag-5'>方式</b>

    伺服電機(jī)的三種控制方式該如何應(yīng)用

    一般伺服都有三種控制方式:速度控制方式,轉(zhuǎn)矩控制方式,位置控制方式。大多數(shù)人想知道的就是這三種
    的頭像 發(fā)表于 12-14 23:12 ?5228次閱讀

    如何應(yīng)用伺服電機(jī)的三種控制方式

    一般伺服都有三種控制方式:速度控制方式,轉(zhuǎn)矩控制方式,位置控制方式。大多數(shù)人想知道的就是這三種
    發(fā)表于 01-22 06:30 ?7次下載
    如何應(yīng)用伺服電機(jī)的<b class='flag-5'>三種</b>控制<b class='flag-5'>方式</b>

    縮放模擬輸入信號(hào)的三種方式

    縮放模擬輸入信號(hào)的三種方式
    發(fā)表于 11-02 08:16 ?0次下載
    縮放模擬輸入信號(hào)的<b class='flag-5'>三種</b><b class='flag-5'>方式</b>

    如何使用journalctl來(lái)讀取、監(jiān)控和分析Linux中的日志

    Systemd是大多數(shù)主要Linux發(fā)行版的默認(rèn)的初始化程序。Systemd的主要功能之一收集日志以及為分析日志提供工具。
    的頭像 發(fā)表于 12-23 16:44 ?4388次閱讀

    刺激能量收集發(fā)展的三種解決方案

    新技術(shù)星期二:刺激能量收集發(fā)展的三種解決方案
    的頭像 發(fā)表于 12-30 09:40 ?540次閱讀

    Redis實(shí)現(xiàn)限流的三種方式分享

    當(dāng)然,限流有許多種實(shí)現(xiàn)的方式,Redis具有很強(qiáng)大的功能,我用Redis實(shí)踐了三種的實(shí)現(xiàn)方式,可以較為簡(jiǎn)單的實(shí)現(xiàn)其方式。
    的頭像 發(fā)表于 02-22 09:52 ?1017次閱讀

    MySQL三種日志講解

    MySQL 日志包含了錯(cuò)誤日志、查詢日志、慢查詢日志、事務(wù)日志、二進(jìn)制日志等,如果存儲(chǔ)引擎使用的
    的頭像 發(fā)表于 07-25 11:15 ?707次閱讀
    MySQL<b class='flag-5'>三種</b><b class='flag-5'>日志</b>講解

    linux日志管理之journalctl命令

    journalctl 用來(lái)查詢 systemd-journald 服務(wù)收集到的日志systemd-journald 服務(wù)是 systemd
    的頭像 發(fā)表于 08-14 18:18 ?2063次閱讀
    linux<b class='flag-5'>日志</b>管理之journalctl命令