将标准输出重定向到系统日志

发布于 2024-07-15 13:09:08 字数 432 浏览 6 评论 0原文

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

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

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

眼藏柔 2024-07-22 13:09:08

您可以使用 logger 命令将 stdout 通过管道传输到 syslog

姓名

 logger - syslog(3) 系统日志模块的 shell 命令接口 
  

概要

 记录器 [-isd] [-f 文件] [-p pri] [-t 标记] [-u 套接字] [消息 ...] 
  

描述

 记录器在系统日志中生成条目。   它提供了一个shell命令 
   syslog(3) 系统日志模块的接口。 
  

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

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

枫以 2024-07-22 13:09:08

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

您需要编写一个在溢出()时输出到系统日志的streambuf,并将std::cout rdbuf替换为您的streambuf。

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

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

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;
 }
遇到 2024-07-22 13:09:08

不确定直接回答“C”是否足够; 但在“C”中,您可以使用底层 stdio 功能将 (FILE*) 直接插入系统日志调用中,而无需介入“记录器”进程。 查看
http://mischasan.wordpress.com/2011/05/ 25/重定向标准错误到系统日志/

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/

酒绊 2024-07-22 13:09:08

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

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

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.

月棠 2024-07-22 13:09:08

我刚刚编写了一些代码来执行此操作。 它使用 ASL 而不是 syslog,并且使用 kevent,因此您可能需要将其移植到系统的不同 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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文