我计划将OpenTibia Server打包为Debian。我想做的其中一件事是通过/etc/init.d
启动并将otserv
进程作为守护进程。
问题是,我们应该将输出重定向到syslog。这通常是通过syslog()
函数完成的。目前,代码中充斥着:
std::cout << "Stuff to printout" << std::endl;
有没有一种适当且易于使用的方法,可以将标准输出和标准错误输出重定向到syslog,而不必替换每个对std::cout等的调用?
logger
命令将stdout
导入syslog
:
NAME
logger - a shell command interface to the syslog(3) system log module
SYNOPSIS
logger [-isd] [-f file] [-p pri] [-t tag] [-u socket] [message ...]
DESCRIPTION
Logger makes entries in the system log. It provides a shell command interface to the syslog(3) system log module.
如果你在命令行中没有提供消息,它会读取stdin
(标准输入)
#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;
}
不确定直接给出"C"语言的答案是否足够;但是在"C"中,您可以使用底层stdio功能将(FILE*)直接插入syslog调用中,而无需介入“logger”进程。请查看http://mischasan.wordpress.com/2011/05/25/redirecting-stderr-to-syslog/
fopencookie
函数只存在于 glibc
(即 Linux 系统)中。 - Alnitakfwopen()
的文章,该函数存在于包括OS X在内的BSD系统中。这几乎涵盖了所有值得讨论的具有syslog实现的主要平台。对于大多数开发者的需求来说,这已经足够了。当存在这种优雅的解决方案时,我不会疯狂地使用套接字和第二个线程来调用syslog()
以符合POSIX标准。 - Ivan Vučicasyslog()
发送从它们读取的任何数据。这样做不需要对被包装应用程序进行任何代码更改,而且相当容易实现。我刚刚写了一些代码来实现这个功能。它使用的是 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;
}