Перенаправление стандартного вывода в системный журнал - PullRequest
14 голосов
/ 20 марта 2009

Я планирую упаковать OpenTibia Server для Debian. Я хочу добавить запуск через /etc/init.d и демонизацию процесса otserv.

Дело в том, что нам, вероятно, следует перенаправить вывод в системный журнал. Обычно это делается с помощью функции syslog(). В настоящее время код кишит:

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

Существует ли правильный, простой в добавлении способ перенаправления стандартного вывода и вывода стандартной ошибки в системный журнал без замены каждого отдельного "вызова" на std :: cout и friends?

Ответы [ 5 ]

21 голосов
/ 20 марта 2009

Вы можете передать свой 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

5 голосов
/ 20 марта 2009

Вы можете перенаправить любой поток в C ++ с помощью команды rdbuf (). Это немного запутанно для реализации, но не так сложно.

Вам нужно написать streambuf, который выводил бы в syslog при переполнении (), и заменить 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;
 }
4 голосов
/ 22 октября 2011

Не уверен, достаточно ли прямого ответа "С"; но в «C» вы можете использовать базовые функции stdio, чтобы подключить (FILE *) непосредственно к вызовам системного журнала, без вмешательства процесса «logger». Проверять, выписываться http://mischasan.wordpress.com/2011/05/25/redirecting-stderr-to-syslog/

2 голосов
/ 20 марта 2009

Попробуйте обернуть выполнение двоичного файла подходящим скриптом, который просто читает stdout и stderr, и отправьте любые данные, прочитанные с них, используя syslog(). Это должно работать без каких-либо изменений кода в упакованном приложении и быть довольно простым.

Не уверен, существуют ли существующие сценарии для передачи, но написание их не должно быть трудным, если нет.

1 голос
/ 27 апреля 2011

Я только что написал код, который сделает это. Он использует ASL ​​вместо syslog и использует kevents, поэтому вам может потребоваться перенести его на разные API для вашей системы (syslog вместо ASL и poll / select вместо kevent)

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

Более того, я добавил это в libsystem_asl на Mountain Lion. Посетите справочную страницу 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;
}
...