将标准输出redirect到syslog

我打算为Debian打包OpenTibia服务器 。 我想要做的事情之一是通过/etc/init.dotserv进程otserv进程添加启动。

事情是,我们可能应该redirect输出到系统日志。 这通常通过syslog()函数完成。 目前,这些代码已经成为:

 std::cout << "Stuff to printout" << std::endl; 

有没有一个适当的,容易添加的方式来redirect标准输出和标准错误输出到系统日志,而不会取代每一个“调用”到std :: cout和朋友?

不确定一个直的“C”答案是否足够; 但是在“C”中,您可以使用底层的stdio功能将(FILE *)直接插入到syslog调用中,而不需要中间的“记录器”过程。 查看http://mischasan.wordpress.com/2011/05/25/redirecting-stderr-to-syslog/

您可以使用logger命令将您的stdout传输到syslog

名称

  logger - a shell command interface to the syslog(3) system log module 

概要

  logger [-isd] [-f file] [-p pri] [-t tag] [-u socket] [message ...] 

描述

  Logger makes entries in the system log. It provides a shell command interface to the syslog(3) system log module. 

如果你不在命令行上提供消息,它会读取stdin

您可以通过rdbuf()命令在C ++中重定向任何流。 这实施起来有点复杂,但并不难。

你需要写一个streambuf,输出到syslog的overflow(),并用你的streambuf代替std :: cout rdbuf。

一个例子,这将输出到一个文件(没有错误处理,未经测试的代码)

 #include <iostream> #include <fstream> using namespace std; int main (int argc, char** argv) { streambuf * yourStreamBuffer = NULL; ofstream outputFileStream; outputFileStream.open ("theOutputFile.txt"); yourStreamBuffer = outputFileStream.rdbuf(); cout.rdbuf(yourStreamBuffer); cout << "Ends up in the file, not std::cout!"; outputFileStream.close(); return 0; } 

尝试用合适的脚本包装二进制文件的执行,只读取stdout和stderr,并使用syslog()发送从它们读取的任何数据。 这应该没有任何代码更改包装的应用程序,并且很容易。

不知道是否有现有的脚本,但写一个不应该很难。

我只是写了一些代码,将这样做。 它使用的是ASL而不是syslog,它使用kevents,因此您可能需要将其移植到系统的不同API(syslog而不是ASL,poll / select而不是kevent)

http://cgit.freedesktop.org/xorg/app/xinit/tree/launchd/console_redirect.c

而且,我基本上把它添加到了Mountain Lion上的libsystem_asl。 查看asl_log_descriptor的手册页。

例:

 #include <asl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { asl_log_descriptor(NULL, NULL, ASL_LEVEL_INFO, STDOUT_FILENO, ASL_LOG_DESCRIPTOR_WRITE); asl_log_descriptor(NULL, NULL, ASL_LEVEL_NOTICE, STDERR_FILENO, ASL_LOG_DESCRIPTOR_WRITE); fprintf(stdout, "This is written to stdout which will be at log level info."); fprintf(stderr, "This is written to stderr which will be at log level notice."); return 0; }