systemd stdout 记录长行

systemd stdout 记录长行

systemd 似乎将很长的日志行分割成多个日志消息:

$ journalctl -u myunit
Nov 12 08:00:18 ovh7 uwsgi[32441]: SHORT LINE
Nov 12 08:00:18 ovh7 uwsgi[32441]: START of VERY VERY LONG LINE ON STDOUT
Nov 12 08:00:18 ovh7 uwsgi[32441]: CONTINUE VERY VERY LONG LINE
Nov 12 08:00:18 ovh7 uwsgi[32441]: SHORT LINE

现在,我并不介意,但我需要加入单独的日志消息以从我的进程中获取原始的标准输出。我想我可以简单地梳理 pid 的日志并使用journalctl json 输出连接 MESSAGE 字符串:

def main():
    import optparse, json, sys
    parser = optparse.OptionParser()
    parser.add_option('--pid')
    parser.add_option('-f', '--file')
    options, args = parser.parse_args()

    with open(options.file, 'r') as f:
        for line in f:
            d = json.loads(line)
            if d['_PID'] == options.pid:
                sys.stdout.write(d['MESSAGE'].encode("utf-8"))

遗憾的是,上面的方法不起作用,因为 systemd 似乎也从 stdout 中删除了尾随的 \n 。它生成这个:

SHORT LINE START of VERY VERY LONG LINE ON STDOUT CONTINUE VERY VERY LONG LINE SHORT LINE

现在,我可以尝试为每个 MESSAGE 添加额外的 \n ,但这会生成以下内容:

SHORT LINE
START of VERY VERY LONG LINE ON STDOUT
CONTINUE VERY VERY LONG LINE
SHORT LINE

上述两个结果都没有太大帮助。我需要这个:

SHORT LINE
START of VERY VERY LONG LINE ON STDOUT CONTINUE VERY VERY LONG LINE
SHORT LINE

我在 Journalctl 的输出中没有看到任何内容可以让我推断出两个连续的消息来自原始 stdout 输出中的同一行。有什么想法可以让我正确地重建这些数据,而不必为我的程序的 stdout 生成单独的日志文件?

答案1

从 systemd v235 开始,systemd 有一个LineMax=指令 for journald.conf,默认设置为 48k。因此,如果您想在日志中支持很长的行,您的第一个选择是将其设置为更大的值。

json其次,如果您使用像( )这样的输出格式journalctl -o json,您可以查看是否插入了换行符。它会出现在 JSON 中,如下所示:

  _LINE_BREAK: "line-max"

如果您遇到这种情况,您就知道下一条记录是该行的延续。有关此功能的更多信息,您可以查看此 git commit:

https://github.com/systemd/systemd/commit/ec20fe5ffb8a00469bab209fff6c069bb93c6db2

相关内容