将标准输出重定向到syslog

时间:2009-03-20 09:46:12

标签: c++ unix redirect daemon syslog

我打算为Debian打包OpenTibia Server。我想要做的其中一件事是通过/etc/init.d添加启动和otserv进程的守护进程。

事情是,我们应该将输出重定向到syslog。这通常通过syslog()函数完成。目前,代码集中在:

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

是否有一种正确的,易于添加的方法将标准输出和标准错误输出重定向到syslog中,而无需将每一个“调用”替换为std :: cout和朋友?

5 个答案:

答案 0 :(得分:21)

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

  

命名

 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

答案 1 :(得分:5)

您可以通过rdbuf()命令在C ++中重定向任何流。这有点令人费解,但并不那么难。

你需要写一个streambuf,它会在overflow()上输出到syslog,并用你的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;
 }

答案 2 :(得分:4)

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

答案 3 :(得分:2)

尝试使用合适的脚本包装二进制文件的执行,该脚本只读取stdout和stderr,并使用syslog()发送从中读取的任何数据。这应该在包装的应用程序中没有任何代码更改的情况下工作,并且非常简单。

不确定是否存在要插入的现有脚本,但是如果没有,那么写一个脚本应该不会很难。

答案 4 :(得分:1)

我刚刚编写了一些可以执行此操作的代码。它使用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;
}