Syslog API:如何在 C 中获取亚秒级时间戳(适用于 Python3)

Syslog API: How to get subsecond timestamps in C (works in Python3)

我有两个写入系统日志的测试程序,一个用 C 语言,一个用 Python3。这是一些示例输出(来自 /var/log/messages):

Dec  9 11:27:55.000 0c6e58933c36 c-logtest[206]: hello
Dec  9 11:27:55.000 0c6e58933c36 c-logtest[206]: world
Dec  9 11:27:59.584 0c6e58933c36 py-logtest[208]: hello
Dec  9 11:27:59.590 0c6e58933c36 py-logtest[208]: world

对于 c-logtest 程序,毫秒数 始终为 000,而显然适用于 py-logtest。我做错了什么?


c-logtest.c:

#include <syslog.h>
#include <unistd.h> //usleep

int main() {
    openlog("c-logtest", LOG_CONS | LOG_NDELAY, LOG_USER);

    syslog(LOG_INFO, "hello");
    usleep(5000);
    syslog(LOG_INFO, "world");

    closelog();
    return 0;
}

py-logtest.py

#!/usr/bin/env python3

import time
import logging
import logging.handlers

logger = logging.getLogger('')
handler = logging.handlers.SysLogHandler(address = '/dev/log')
handler.setFormatter(logging.Formatter('py-logtest %(message)s'))
logger.addHandler(handler)
logger.setLevel(logging.INFO)

logger.info("hello")
time.sleep(0.005)
logger.info("world")

我正在使用 syslog-ng,我已将其配置为生成毫秒分辨率时间戳,方法是将其添加到 syslog-ng.conf:

options{ frac-digits(3); };

提示:可以使用 docker run --rm -it fedora bash 以独立的方式重现此内容,然后从那里安装和配置 syslog-ng,运行 这两个程序,以及 tail -F /var/log/messages.

根据 this thread 系统日志的 glibc 实现 API 不会生成亚秒级时间戳精度。

你可以做的可能是使用 keep-timestamp(no) syslog-ng 选项。这将使 syslog-ng 忽略与消息一起发送的时间戳,而是使用消息接收时间。这是否可以接受取决于您的用例。在大多数情况下,当 syslog 在本地运行时,这应该不是问题。但是 documentation 中有以下警告:

To use the S_ macros, the keep-timestamp() option must be enabled (this is the default behavior of syslog-ng PE).

我做了我自己的日志实现,它是这样做的:

(C++)

static void writeTimestamp(std::ofstream& out)
{
    struct timeval now;
    gettimeofday(&now, nullptr);
    out << std::put_time(std::localtime(&now.tv_sec), "%F %T.");

    char usecbuf[6+1];
    snprintf(usecbuf, sizeof(usecbuf), "%06lu", now.tv_usec);
    out << usecbuf;
}

要获得完整的解决方案,我需要重新实现系统日志库,但我没有。