14

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

问题是,我们可能应该将输出重定向到 syslog。这通常通过syslog()函数完成。目前,代码中充斥着:

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

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

4

5 回答 5

22

您可以使用以下命令通过管道stdout传输到:sysloglogger

姓名

 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

于 2009-03-20T09:50:12.493 回答
5

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

您需要编写一个将在溢出()上输出到 syslog 的 streambuf,并用您的 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;
 }
于 2009-03-20T10:50:33.377 回答
4

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

于 2011-10-22T06:02:06.230 回答
2

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

不确定是否有现有的脚本可以输入,但如果没有的话,编写一个应该不难。

于 2009-03-20T09:49:46.283 回答
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;
}
于 2011-04-26T20:40:12.727 回答