2009-03-20 22 views
14

tengo la intención de empaquetar OpenTibia Server para Debian. Una de las cosas que quiero hacer es agregar inicio a través de /etc/init.d y daemonización del proceso otserv.redirigir la salida estándar a syslog

cosa es, probablemente deberíamos redirigir la salida a syslog. Esto generalmente se hace a través de la función syslog(). Actualmente, el código es rodeado con:

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

¿Existe una manera adecuada, fácil de añadir, para redirigir la salida estándar y la salida estándar de error en el syslog sin tener que reemplazar cada "llamada" a std :: cout y amigos?

Respuesta

4

No estoy seguro de si una recta respuesta "C" es suficiente; pero en "C" puede usar las características de stdio subyacentes para conectar el (ARCHIVO *) directamente a las llamadas de registro del sistema, sin un proceso intermedio de "registrador". Echa un vistazo a http://mischasan.wordpress.com/2011/05/25/redirecting-stderr-to-syslog/

+1

Esto es todo. Sería genial si también pegaría partes de su publicación aquí;) –

+1

no es portátil, y no es estándar POSIX – Alnitak

+0

@Ivan: pegar un enlace es más rápido que pegar un artículo. No obtengo ingresos de usted al hacer clic en el enlace de mi blog :-) – Mischa

2

Pruebe envolviendo la ejecución del binario con una secuencia de comandos adecuada, que solo lea stdout y stderr, y envíe cualquier dato leído de ellos usando syslog(). Eso debería funcionar sin ningún cambio de código en la aplicación empaquetada, y sería bastante fácil.

No

seguro de si hay secuencias de comandos existentes a la tubería en, pero la escritura no hay que ser difícil si no.

+0

que parece una solución muy portátil, por lo tanto, esto solo nos permitirá tener dos niveles de registro error e información, el syslog de Linux tiene más niveles de registro a la mano. Pero si podemos soportar este pequeño inconveniente, aquí hay una publicación que muestra cómo lograr eso: http://unix.stackexchange.com/questions/124455/linux-how-to-redirect-stdout-stderr-to-logger –

21

Puede canalizar su stdout-syslog con el comando logger:

NOMBRE

logger - a shell command interface to the syslog(3) system log module 

SINOPSIS

logger [-isd] [-f file] [-p pri] [-t tag] [-u socket] [message ...] 

DESCRIPCIÓN

Logger makes entries in the system log. It provides a shell command 
interface to the syslog(3) system log module. 

Si no se proporciona un mensaje en la línea de comandos lee stdin

5

Puede redirigir cualquier corriente en C++ a través del comando rdbuf(). Esto es un poco complicado de implementar, pero no tan difícil.

tiene que escribir un streambuf que sería la salida a syslog en caso de desbordamiento(), y sustituir el rdbuf std :: cout con su streambuf.

Un ejemplo, que haría salida a un archivo (sin control de errores, el código no probado)

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

Casi lo que estaba buscando, sin embargo, "registrador" me proporciona información adicional, especialmente si simplemente produzco un guión bash de envoltura. Sin embargo, gracias por la información, y lo siento mucho, no puedo marcar ambas respuestas como The Answers (tm). –

1

que acabo de escribir un código que va a hacer esto. Es el uso de ASL en lugar de syslog, y es usando kevents, de manera que deberá portarlo a diferentes APIs para su sistema (syslog en lugar de ASL y sondeo/seleccione en lugar de kevent)

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

Por otra parte, yo Básicamente, agregó esto a libsystem_asl en Mountain Lion. Consulte la página man para asl_log_descriptor.

Ejemplo:

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