简体   繁体   English

使用 rsyslog 捕获 journald 属性

[英]capture journald properties with rsyslog

I am struggling on how to capture systemd-journald properties into rsyslog files.我正在努力研究如何将systemd-journald属性捕获到rsyslog文件中。

My setup我的设置

  • ubuntu inside docker on arm (raspberrypi): FROM arm64v8/ubuntu:20.04 ubuntu 在 arm(树莓派)上的 docker 内: FROM arm64v8/ubuntu:20.04

  • docker command (all subsequent actions taken inside running docker container) docker 命令(在运行 docker 容器内执行的所有后续操作)

     $ docker run --privileged -ti --cap-add SYS_ADMIN --security-opt seccomp=unconfined --cgroup-parent=docker.slice --cgroupns private --tmpfs /tmp --tmpfs /run --tmpfs /run/lock systemd:origin
  • rsyslog under $ sytemctl status rsyslog $ sytemctl status rsyslog rsyslog的 rsyslog

     ● rsyslog.service - System Logging Service Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor prese> Active: active (running)... [origin software="rsyslogd" swVersion="8.2001.0" x-pid="39758" x-info="https://www.rsyslog.com"] start...

My plan我的计划

Having a small c program to put some information into journal:有一个小的 c 程序可以将一些信息放入日志中:

    #include <systemd/sd-journal.h>
    #include <stdio.h>
    #include <unistd.h>

    int main(int arcg, char** args) {
      char buffer [50];

      sprintf (buffer, "%lu", (unsigned long)getpid());

      printf("writing to journal\n");

      sd_journal_print(LOG_WARNING, "%s", "a little journal test message");
      sd_journal_send("MESSAGE=%s", "there shoud be a text", "SYSLOG_PID=%s", buffer, "PRIORITY=%i", LOG_ERR, "DOCUMENTATION=%s", "any doc link", "MESSAGE_ID=%s", "e5e4132e441541f89bca0cc3e7be3381", "MEAS_VAL=%d", 1394, NULL);

      return 0;
    }

Compile it: $ gcc joutest.c -lsystemd -o jt编译它: $ gcc joutest.c -lsystemd -o jt

Execute it: $./jt执行它: $./jt

This results inside the journal as $ journalctl -r -o json-pretty :这在日志中的结果为$ journalctl -r -o json-pretty

    {
      "_GID" : "0",
      "MESSAGE" : "there shoud be a text",
      "_HOSTNAME" : "f1aad951c039",
      "SYSLOG_IDENTIFIER" : "jt",
      "_TRANSPORT" : "journal",
      "CODE_FILE" : "joutest.c",
      "DOCUMENTATION" : "any doc link",
      "_BOOT_ID" : "06a36b314cee462591c65a2703c8b2ad",
      "CODE_LINE" : "14",
      "MESSAGE_ID" : "e5e4132e441541f89bca0cc3e7be3381",
      "_CAP_EFFECTIVE" : "3fffffffff",
      "__REALTIME_TIMESTAMP" : "1669373862349599",
      "_SYSTEMD_UNIT" : "init.scope",
      "CODE_FUNC" : "main",
      "_MACHINE_ID" : "5aba31746bf244bba6081297fe061445",
      "SYSLOG_PID" : "39740",
      "PRIORITY" : "3",
      "_COMM" : "jt",
      "_SYSTEMD_SLICE" : "-.slice",
      "MEAS_VAL" : "1394",
      "__MONOTONIC_TIMESTAMP" : "390853282189",
      "_PID" : "39740",
      "_SOURCE_REALTIME_TIMESTAMP" : "1669373862336503",
      "_UID" : "0",
      "_SYSTEMD_CGROUP" : "/init.scope",
      "__CURSOR" : "s=63a46a30bbbb4b8c9288a9b12c622b37;i=6cb;b=06a36b314cee46>
    }

Now as a test, extracting all properties from that journal entry via rsyslog ;现在作为测试,通过rsyslog从该日志条目中提取所有属性; property in the jargon of rsyslog in principle is the name of a key in the formatted json entry. rsyslog术语中的属性原则上是格式化的 json 条目中的键的名称。 But if a property (or key name) matches, the whole dictionary item (key and value) shall be captured但如果属性(或键名)匹配,则应捕获整个字典项(键和值)

To start with this, I've configured rsyslog as:首先,我将rsyslog配置为:

    module(load="imjournal")
    module(load="mmjsonparse")

    action(type="mmjsonparse")

    if $programname == 'jt' and $syslogseverity == 3 then
      action(type="omfile" file="/var/log/jt_err.log" template="RSYSLOG_DebugFormat")

This config is located in /etc/rsyslog.d/filter.conf and gets automatically included by /etc/rsyslog.conf :此配置位于/etc/rsyslog.d/filter.conf并自动包含在/etc/rsyslog.conf

    # /etc/rsyslog.conf configuration file for rsyslog
    #
    # For more information install rsyslog-doc and see
    # /usr/share/doc/rsyslog-doc/html/configuration/index.html
    #
    # Default logging rules can be found in /etc/rsyslog.d/50-default.conf
    
    
    #################
    #### MODULES ####
    #################
    
    #module(load="imuxsock") # provides support for local system logging
    #module(load="immark")  # provides --MARK-- message capability
    
    # provides UDP syslog reception
    #module(load="imudp")
    #input(type="imudp" port="514")
    
    # provides TCP syslog reception
    #module(load="imtcp")
    #input(type="imtcp" port="514")
    
    # provides kernel logging support and enable non-kernel klog messages
    module(load="imklog" permitnonkernelfacility="on")
    
    ###########################
    #### GLOBAL DIRECTIVES ####
    ###########################
    
    #
    # Use traditional timestamp format.
    # To enable high precision timestamps, comment out the following line.
    #
    $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
    
    # Filter duplicated messages
    $RepeatedMsgReduction on
    
    #
    # Set the default permissions for all log files.
    #
    $FileOwner syslog
    $FileGroup adm
    $FileCreateMode 0640
    $DirCreateMode 0755
    $Umask 0022
    $PrivDropToUser syslog
    $PrivDropToGroup syslog
    
    #
    # Where to place spool and state files
    #
    $WorkDirectory /var/spool/rsyslog
    
    #
    # Include all config files in /etc/rsyslog.d/
    #
    $IncludeConfig /etc/rsyslog.d/*.conf

Applied this config: $ systemctl restart rsyslog应用此配置: $ systemctl restart rsyslog

Which results in the following: $ cat /var/log/jt_err.log结果如下: $ cat /var/log/jt_err.log

    Debug line with all properties:
    FROMHOST: 'f1aad951c039', fromhost-ip: '127.0.0.1', HOSTNAME: 
    'f1aad951c039', PRI: 11,
    syslogtag 'jt[39765]:', programname: 'jt', APP-NAME: 'jt', PROCID: 
    '39765', MSGID: '-',
    TIMESTAMP: 'Nov 25 11:47:50', STRUCTURED-DATA: '-',
    msg: ' there shoud be a text'
    escaped msg: ' there shoud be a text'
    inputname: imuxsock rawmsg: '<11>Nov 25 11:47:50 jt[39765]: there 
    shoud be a text'
    $!:{ "msg": "there shoud be a text" }
    $.:
    $/:

My problem我的问题

Looking on the resulting rsyslog, I miss a majority, if not all, of items originating from the journal entry.查看生成的 rsyslog,我错过了大部分(如果不是全部)源自日记条目的项目。 There is really no property (key) matching.确实没有属性(键)匹配。 Shouldn't be there all properties matched as it is a debug output?不应该所有属性都匹配,因为它是调试 output?

Specifically I am concentrating on my custom property, MEAS_VAL , it is not there.具体来说,我专注于我的自定义属性MEAS_VAL ,它不存在。 The only property which occurs is "msg", which by the way is questionable whether it is a match of the journal, since the originating property name attached to the resulting content "there shoud be a text" is MESSAGE出现的唯一属性是“msg”,顺便说一句,它是否与日志匹配值得怀疑,因为附加到结果内容"there shoud be a text"的原始属性名称是MESSAGE

So it feels that I don't hit the whole journal capturing mechanism at all, why?所以感觉完全没有打到整个journal捕获机制,为什么呢?

Can we be sure that imjournal gets loaded properly?我们能确定imjournal被正确加载了吗?

I would say yes because of systemd's startup messages:我会说是因为systemd's启动消息:

    Nov 28 16:27:38 f1aad951c039 rsyslogd[144703]: imjournal: Journal indicates no msgs when positioned at head.  [v8.2212.0.master try https://www.rsyslog.com/e/0 ]
    Nov 28 16:27:38 f1aad951c039 rsyslogd[144703]: imjournal: journal files changed, reloading...  [v8.2212.0.master try https://www.rsyslog.com/e/0 ]
    Nov 28 16:27:38 f1aad951c039 rsyslogd[144703]: imjournal: Journal indicates no msgs when positioned at head.  [v8.2212.0.master try https://www.rsyslog.com/e/0 ]

Edit 2022-11-29编辑 2022-11-29

Meanwhile I've compiled my own version 8.2212.0.master.同时我编译了我自己的版本 8.2212.0.master。 But the phenomenon persists.但这种现象仍然存在。

To capture journal logs with rsyslog, the imjournal module (as used in the question), can be used.要使用 rsyslog 捕获日志日志,可以使用imjournal模块(如问题中所用)。

Journal logs are stored in key-value pairs.日志日志存储在键值对中。 The imjournal module is able to parse these key-value pairs and generate the jsonf property, which then can be used to access fields of the log message as if they were fields in a JSON object. imjournal模块能够解析这些键值对并生成jsonf属性,然后可以使用该属性访问日志消息的字段,就好像它们是 JSON object 中的字段一样。

# load imjournal module
module(load="imjournal")

# specify journal as input source
input(type="imjournal")

template(name="journalTemplate" type="list") {
    property(name="timestamp" dateFormat="rfc3339")
    constant(value=" ")
    property(name="hostname")
    constant(value=" ")
    property(name="syslogtag")
    constant(value=": {")
    property(name="jsonf")
    constant(value="}")
}

if $programname == 'journal' then {
  action(type="omfile" file="/var/log/jt_err.log" template="journalTemplate")
  stop
}

The output of the provided log would then look something like the following:所提供日志的 output 将如下所示:

YYYY-MM-DDTHH:mm:ss myHostname syslogtag: {"_GID" : "0", "MESSAGE" : "there shoud be a text", ... }

As seen in the log above, the output of the provided properties will be in JSON. By using the json property parser this can be prevented, as the output can be tailored as desired.如上面的日志所示,所提供属性的 output 将在 JSON 中。通过使用json属性解析器可以避免这种情况,因为可以根据需要定制 output。 If this is used, however, each property must be defined specifically.但是,如果使用它,则必须专门定义每个属性。

template(name="journalTemplate" type="list") {
    property(name="timestamp" dateFormat="rfc3339")
    constant(value=" ")
    property(name="hostname")
    constant(value=" ")
    property(name="syslogtag")
    constant(value=": _GID=")
    property(name="$._GID" format="json")
    constant(value=" MESSAGE=")
    property(name="$.MESSAGE" format="json")
    constant(value=" _HOSTNAME=")
    property(name="$._HOSTNAME" format="json")
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM