我有两个写入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>
答案 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库,但我没有。