我们在 Linux 上有一个使用syslog机制的应用程序。在花了一周的时间试图弄清楚为什么这个应用程序运行得比预期慢后,我们发现如果我们消除 syslog,直接写入日志文件,性能会显着提高。
我理解为什么 syslog 比直接文件写入慢。但我想知道:有没有办法配置 syslog 来优化其性能?
您可以通过在配置文件中的日志文件路径前添加“-”来配置 syslogd(和至少 rsyslog)在日志消息之后不同步日志文件。这以牺牲日志消息可能在崩溃中丢失的危险为代价来提高性能。
有几个选项可以提高 syslog 性能:
使用宏优化呼叫
int LogMask = LOG_UPTO(LOG_WARNING);
#define syslog(a, ...) if ((a) & LogMask ) syslog((a), __VA_ARGS__)
int main(int argc, char **argv)
{
LogMask = setlogmask(LOG_UPTO(LOG_WARNING));
...
}
使用宏过滤 syslog 调用的一个优点是,整个调用被简化为对全局变量的条件跳转,如果您碰巧有通过其他函数转换大型数据集的 DEBUG 调用,这将非常有用。
设置日志掩码()
setlogmask(LOG_UPTO(LOG_LEVEL))
setlogmask() 将通过不记录到 /dev/log 来优化调用,但程序仍将调用用作参数的函数。
使用 syslog.conf 过滤
*.err /var/log/messages
“有关详细信息,请查看 syslog.conf 的手册页。”
配置 syslog 以执行异步或缓冲日志记录
metalog 用于缓冲日志输出并将其刷新为块。据我所知,stock syslog 和 syslog-ng 不这样做。
在开始编写新的守护进程之前,您可以检查syslog-ng是否比普通的旧 syslog 更快(或可以配置为更快)。
如果您控制日志记录应用程序的源,您可以使用的一个技巧是在应用程序本身而不是在 syslog.conf 中屏蔽您想要的日志级别。几年前,我使用了一个生成大量调试日志的应用程序。我们没有从生产代码中删除调用,而是屏蔽了调试级别的调用,这样调试级别的调用就不会被发送到守护进程。我实际上找到了代码,它是 Perl,但它只是 setlogmask(3) 调用的前面。
use Sys::Syslog;
# Start system logging
# setlogmask controls what levels we're going to let get through. If we mask
# them off here, then the syslog daemon doesn't need to be concerned by them
# 1 = emerg
# 2 = alert
# 4 = crit
# 8 = err
# 16 = warning
# 32 = notice
# 64 = info
# 128 = debug
Sys::Syslog::setlogsock('unix');
openlog($myname,'pid,cons,nowait','mail');
setlogmask(127); # allow everything but debug
#setlogmask(255); # everything
syslog('debug',"syslog opened");
不知道为什么我使用十进制而不是位掩码...... 耸了耸肩
编写您自己的 syslog 实现。:-P
这可以通过两种方式实现。
LD_PRELOAD
钩子来覆盖 syslog 函数,并将它们输出到stderr
。实际上,我多年前写过一篇关于此的文章:http: //marc.info/ ?m= 97175526803720 :-P/dev/log
!:-P好的,好的,所以这些都是滑稽的答案。你有没有分析syslogd
过它最令人窒息的地方?
您可以将 syslogd 的级别(或设施)配置为异步记录,方法是在日志文件的路径前加上减号(即:user.* [tab] -/var/log/user.log)。
干杯。
syslog-async() 实现可能会有所帮助,但有可能在其他时间丢失日志行/有界延迟。 http://thekelleys.org.uk/syslog-async/
注意:这里的“异步”是指在您的应用程序中排队日志事件,而不是其他答案所指的异步 syslogd 输出文件配置选项。