2010-11-23 14 views
5

Tengo el registro configurado usando logging.fileConfig(). Tengo un registrador de raíz que va a un manejador que usa SysLogHandler ('/ dev/log', handlers.SysLogHandler.LOG_USER)¿Cómo configuro la cadena de identificación cuando uso logging.SysLogHandler en Python 2.6?

Todo esto funciona perfectamente bien, y veo mis entradas de registro en/var/log/user .log

La pregunta es ¿cómo puedo configurar la cadena de identificador syslog a algo que no sea python? Parece que el módulo syslog en la lib estándar permite configurar esto al abrir un registro, pero el controlador de registro no ofrece esta característica.

¿La solución debería ser la subclase SysLogHandler y usar la biblioteca syslog dentro de su método de emisión? Este es un programa único de Unix, por lo que usar syslog directamente no plantea un problema de portabilidad.

Respuesta

3

AFAIK, la cadena de identificación es un artefacto de la API syslog, consulte this page. Simplemente usa C argv [0] que sería, por supuesto, "pitón".

Me sorprende que usted está recibiendo esta usando SysLogHandler con un socket de dominio, ya que el mensaje enviado a los demonios de registro del sistema a través de sockets de dominio o TCP es sólo una cadena con la prioridad en < paréntesis angulares > seguido por el mensaje formateado y un byte NUL. No hay una cadena de identificación especificada en SysLogHandler, ya que no utiliza la API syslog (que tiene algunos problemas de seguridad de subprocesos en algunas versiones, IIRC).

+0

Vinay gracias por la respuesta completa. Resulta que tenía razón, y esto fue principalmente una falta de comunicación con mi equipo de operaciones. Estamos utilizando un nuevo formateador para poner una bandera falsa "ident" como primer argumento y rsyslog no podría ser más feliz. –

+0

Esta es información obsoleta, marcaría la respuesta de FirefighterBlu3 como la correcta. –

+1

No hay motivo para rechazar votos porque la información no está actualizada. Fue la respuesta correcta en ese momento, y gracias a 'FirefighterBlu3' por proporcionar la actualización. –

4

Esto es un poco viejo, pero la información nueva debe registrarse aquí para que las personas no sientan la necesidad de escribir su propio controlador syslog.

Desde Python 3.3, el SysLogHandler tiene un atributo de clase de .ident precisamente para este propósito; el valor por defecto es ''.

Ejemplo:

import logging 
from logging.handlers import SysLogHandler 

h = SysLogHandler(address=('some.destination.com',514), facility=SysLogHandler.LOG_LOCAL6) 
h.setFormatter(
    logging.Formatter('%(name)s %(levelname)s %(message)s') 
) 
h.ident = 'conmon' 

syslog = logging.getLogger('syslog') 
syslog.setLevel(logging.DEBUG) 
syslog.addHandler(h) 

syslog.debug('foo syslog message') 
+4

Esto es Python 3.3+ sin embargo. – malthe

2

Para Python 2.7, se podría hacer algo como esto:

class MySysLogHandler(logging.handlers.SysLogHandler): 
    def __init__(self): 
     super(MySysLogHandler, self).__init__(address='/dev/log') 
    def emit(self, record): 
     priority = self.encodePriority(self.facility, self.mapPriority(record.levelname)) 
     record.ident = "My[" + str(priority) + "]:" 
     super(MySysLogHandler, self).emit(record) 

handler = MySysLogHandler() 
handler.formatter = logging.Formatter(fmt="%(ident)s %(levelname)s: %(message)s") 
logging.root.addHandler(handler) 
logging.info("hello world") 

Esto producirá en el registro del sistema:

Sep 3 16:28:53 hostname My[14]: INFO: hello world

3

implementaciones Syslog aceptar RFC3164 mensajes deberían reconocer primero parte del mensaje ("foo:" en el ejemplo) como TAG.

La parte MSG tiene dos campos conocidos como campo TAG y el campo CONTENIDO . El valor en el campo TAG será el nombre del programa o el proceso que generó el mensaje.

código Python ..

import logging 
from logging.handlers import SysLogHandler 

h = SysLogHandler(address='/dev/log') 
h.setFormatter(logging.Formatter('foo: %(message)s')) 
logging.getLogger().addHandler(h) 

logging.error('bar') 

..will enviar esta en el zócalo syslog

connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 10) = 0 
sendto(3, "<11>foo: bar\0", 13, 0, NULL, 0) = 13 
close(3) 

Que a su vez, produce esto en el diario de systemd.

Dec 13 14:48:20 laptop foo[1928]: bar 

Journal detalles del mensaje:

{ 
    .. 
    "PRIORITY" : "3", 
    "SYSLOG_FACILITY" : "1", 
    "SYSLOG_IDENTIFIER" : "foo", 
    "MESSAGE" : "bar", 
    "_PID" : "1928", 
} 

Funciona con Py2.6, 2.7, 3.4, 3.5 y servidor syslog de Systemd. También puede funcionar con otras implementaciones de syslog (si aceptan RFC3164). Esta solución probablemente se rompa cuando el SysLogHandler de python cambie de forma predeterminada a RFC5424 más nuevo.

Cuestiones relacionadas