Redirecting standard output to syslog

让人想犯罪 __ 提交于 2019-11-29 17:18:41

问题


I'm planning to package OpenTibia Server for Debian. One of the things I want to do is add startup via /etc/init.d and daemonization of the otserv process.

Thing is, we should probably redirect output to syslog. This is usually done via the syslog() function. Currently, the code is swarmed with:

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

Is there a proper, easy to add, way to redirect standard output and standard error output into syslog without replacing every single "call" to std::cout and friends?


回答1:


Not sure whether a straight "C" answer suffices; but in "C" you can use underlying stdio features to plug the (FILE*) directly into syslog calls, without an intervening "logger" process. Check out http://mischasan.wordpress.com/2011/05/25/redirecting-stderr-to-syslog/




回答2:


You can pipe your stdout to syslog with the logger command:

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.

If you don't supply a message on the command line it reads stdin




回答3:


You can redirect any stream in C++ via the rdbuf() command. This is a bit convoluted to implement but not that hard.

You need to write a streambuf that would output to syslog on overflow(), and replace the std::cout rdbuf with your streambuf.

An example, that would output to a file (no error handling, untested code)

#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;
 }



回答4:


Try wrapping the execution of the binary with a suitable script, that just reads stdout and stderr, and send any data read from them on using syslog(). That should work without any code changes in the wrapped application, and be pretty easy.

Not sure if there are existing scripts to pipe into, but writing one shouldn't be hard if not.




回答5:


I just wrote some code that will do this. It's using ASL instead of syslog, and it's using kevents, so you may need to port it to different APIs for your system (syslog instead of ASL and poll/select instead of kevent)

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

Furthermore, I basically added this to libsystem_asl on Mountain Lion. Check out the man page for asl_log_descriptor.

Example:

#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;
}


来源:https://stackoverflow.com/questions/665509/redirecting-standard-output-to-syslog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!