0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

systemd journal收集日志的三种方式

马哥Linux运维 来源:博客园sparkdev 2024-10-23 11:50 次阅读

随着 systemd 成了主流的 init 系统,systemd 的功能也在不断的增加,比如对系统日志的管理。Systemd 设计的日志系统好处多多,这里笔者就不再赘述了,本文笔者主要介绍 systemd journal 收集日志的三种方式:

程序使用 libc 库中的 syslog() 函数输出的日志

使用 printf() 函数打印的日志

任何服务进程输出到 STDOUT/STDERR 的所有内容

说明:本文的演示环境为 ubuntu 16.04。

syslog()

该函数的声明如下:

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

创建下面的 C 语言代码,并保存到文件 clog.c 文件中:

#include 


int main(int argc, char *argv[]) {
        syslog(LOG_NOTICE, "C Hello World");
        return 0;
}

用下面的命令编译程序:

$ gcc -Wall clog.c -o clog

然后执行编译好的 clog 程序,就可以从 journal -f 的输出中看到对应的日志:

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

这里笔者执行了三次 clog 程序,所以日志输出了三遍。
代码中的 LOG_NOTICE 代表日志的严重等级,我们可以使用下面定义好的等级:


#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')

然后执行下面的命令:

$ python plog.py

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

笔者同样执行了三遍,这次输出的是 python 代码中的日志。

我们还可以通过 journalctl -o json-pretty -f 命令查看 json 格式的日志:

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

printf()

journal 可以捕获服务进程往 STDOUT/STDERR 输出的所有内容,比如 C 语言中 print 函数打印的内容,Python 中 print 打印的内容,以及 Shell 脚本中 echo 打印的内容等等都可以被 journal 捕获到并加入到日志中。注意,只有以 service 的方式运行程序时,journal 才会捕获 STDOUT/STDERR 输出的内容。
创建下面的 C 语言代码,并保存到文件 printlog.c 文件中:

#include 


int main(int argc, char *argv[]) {
    printf("C Print Hello World.
");
    return 0;
}

用下面的命令编译程序:

$ gcc -Wall printlog.c -o printlog

配置一个简单的 service,先创建 一个配置文件 /lib/systemd/system/testlog.service,其内容如下:


[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 会捕获 STDOUT/STDERR 输出的内容:

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

默认情况下,这样输出的日志等级为 LOG_INFO(6),我们可以通过 json 格式的日志看到日志等级信息

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

我们还可以在打印日志时指定日志的等级,比如在每行打印的内容前加上"",N为需要指定的日志等级。看下面的 C 语言示例:

#include


#define PREFIX_NOTICE "<5>"


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


  return 0;
}

把上面的代码编译为 printlog 程序,再查看下日志,显示的就是我们自己设置的日志等级:

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

在 Python 中的用法如下:


#!/usr/bin/env python
print '<5>Hello World'

在 bash 中的用法如下:

#!/bin/bash
echo "<5>Hello World"

Systemd 日志库

Systemd 提供了原生的 C 语言库(systemd/sd-journal.h) 用于向 journal 输出日志(ubuntu 16.04 需要通过 sudo apt install libsystemd-dev 命令安装 libsystemd-dev 包),相关函数的声明为:

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

把下面的示例代码会把日志发送给 journal:

#include 


int main(int argc, char *argv[]) {
        sd_journal_print(LOG_NOTICE, "Hello World");
        return 0;
}

相比上文使用 print() 或者 syslog() 提交的日志,使用 sd_journal_print 可以直观的指定 LOG 等级、日志内容等等,另外输出的日志会包含执行代码的位置信息,例如执行到的函数,代码文件位置,代码具体行数,方便开发人员调试。

除了可以包含代码信息,也可以向提交的日志中加入自定义段包含更多自定义信息,配合 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;
}

我们在日志中添加了自定义的字段,并且可以通过 journalctl 过滤这些字段。

除了 systemd 提供的一套C语言库,目前其他个别语言也衍生了 systemd 的相关扩展,其中就包含了和 journald 相关的扩展。下面是段 python 的演示代码:


from systemd import journal
journal.send('Hello world')
journal.send('Hello, again, world', FIELD2='Greetings!', FIELD3='Guten tag')

在运行上面的代码前你需要先通过 pip 安装 python 的 systemd 模块(pip install systemd ),然后运行这段代码,你就可以从日志中看到它输出的信息了:

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

展开成 json 格式看下:

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

我们自定义的字段 FIELD2 和 FIELD3 也都输出到日志中了。

总结

本文介绍了常见的一些往 systemd journal 中写入日志的方式,了解这些日志的写入方式可以帮助我们更好的设计应用的日志输出,并有助于我们通过日志解决问题。

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

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 程序
    +关注

    关注

    115

    文章

    3747

    浏览量

    80663
  • 函数
    +关注

    关注

    3

    文章

    4259

    浏览量

    62227
  • 日志
    +关注

    关注

    0

    文章

    132

    浏览量

    10616

原文标题:高效日志管理:通过 Systemd Journal 收集日志的终极指南

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    伺服电机的三种控制方式

    伺服电机控制方式有脉冲、模拟量和通讯这三种,在不同的应用场景下,我们该如何选择伺服电机的控制方式呢?
    发表于 08-17 11:01 7011次阅读

    三种复位方式比较

    三种复位方式比较
    发表于 08-16 17:31

    步进电机的三种驱动方式

    步进电机的三种驱动方式
    发表于 01-12 17:03

    请问stm32启动的三种方式是什么意思?

    请群主详细解释下这三种启动方式,看了参考资料不是很明白其意!谢谢!
    发表于 07-17 04:35

    常见的三种无线接入方式是什么?

    蓝牙无线组网的优点是什么?常见的三种无线接入方式是什么?蓝牙无线组网原理与上网方案分享
    发表于 05-26 06:33

    STM32三种启动方式是什么

    STM32三种启动方式是什么
    发表于 12-15 07:16

    压供电系统的三种运行方式

    我国低压供电系统的三种运行方式:国低压供电系统主要有三种运行方式:TN系统、TT系统、lT系统。
    发表于 05-26 17:06 9642次阅读
    压供电系统的<b class='flag-5'>三种</b>运行<b class='flag-5'>方式</b>

    伺服电机的三种控制方式该如何应用

    一般伺服都有三种控制方式:速度控制方式,转矩控制方式,位置控制方式。大多数人想知道的就是这三种
    的头像 发表于 12-14 23:12 5162次阅读

    如何应用伺服电机的三种控制方式

    一般伺服都有三种控制方式:速度控制方式,转矩控制方式,位置控制方式。大多数人想知道的就是这三种
    发表于 01-22 06:30 7次下载
    如何应用伺服电机的<b class='flag-5'>三种</b>控制<b class='flag-5'>方式</b>

    缩放模拟输入信号的三种方式

    缩放模拟输入信号的三种方式
    发表于 11-02 08:16 0次下载
    缩放模拟输入信号的<b class='flag-5'>三种</b><b class='flag-5'>方式</b>

    如何使用journalctl来读取、监控和分析Linux中的日志

    Systemd是大多数主要Linux发行版的默认的初始化程序。Systemd的主要功能之一收集日志以及为分析日志提供工具。
    的头像 发表于 12-23 16:44 4271次阅读

    刺激能量收集发展的三种解决方案

    新技术星期二:刺激能量收集发展的三种解决方案
    的头像 发表于 12-30 09:40 529次阅读

    Redis实现限流的三种方式分享

    当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单的实现其方式
    的头像 发表于 02-22 09:52 982次阅读

    MySQL三种日志讲解

    MySQL 日志包含了错误日志、查询日志、慢查询日志、事务日志、二进制日志等,如果存储引擎使用的
    的头像 发表于 07-25 11:15 689次阅读
    MySQL<b class='flag-5'>三种</b><b class='flag-5'>日志</b>讲解

    linux日志管理之journalctl命令

    journalctl 用来查询 systemd-journald 服务收集到的日志systemd-journald 服务是 systemd
    的头像 发表于 08-14 18:18 1623次阅读
    linux<b class='flag-5'>日志</b>管理之journalctl命令