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

时间:2016-12-09 11:57:13

标签: c syslog

我有两个写入syslog的测试程序,一个用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。 / p>

2 个答案:

答案 0 :(得分:1)

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

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

  

要使用S_宏,必须启用keep-timestamp()选项(这是syslog-ng PE的默认行为)。

答案 1 :(得分:0)

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

(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;
}

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