2010-11-23 18 views
5

Ho configurato la registrazione utilizzando logging.fileConfig(). Ho un root logger che va a un gestore che utilizza SysLogHandler ('/ dev/log', handlers.SysLogHandler.LOG_USER)Come si imposta la stringa di identificazione quando si utilizza logging.SysLogHandler in Python 2.6?

Tutto questo funziona perfettamente, e vedo le mie voci di registro in/var/log/user .log

La domanda è: come posso impostare la stringa ident di syslog su qualcosa di diverso da python? Sembra che il modulo syslog nella lib standard permetta di impostarlo quando si apre un log, ma il gestore di logging non offre questa funzionalità.

La soluzione dovrebbe essere la sottoclasse di SysLogHandler e utilizzare la libreria syslog all'interno del suo metodo emit? Questo è un programma unix solo, quindi usare syslog direttamente non rappresenta un problema di portabilità.

risposta

3

AFAIK, la stringa di identificazione è un artefatto dell'API syslog, vedere this page. Sta usando semplicemente C argv [0] che ovviamente sarebbe "python".

Sono sorpreso che stai ricevendo questo utilizzando SysLogHandler con un socket di dominio, come il messaggio inviato ai daemon syslog attraverso socket di dominio o TCP è solo una stringa con la priorità in < parentesi angolari > seguito dal messaggio formattato e un byte NUL. Non esiste una stringa ident specificata da SysLogHandler, in quanto non utilizza l'API syslog (che ha alcuni problemi di sicurezza dei thread in alcune versioni, IIRC).

+0

Vinay, grazie per la risposta completa. Ho scoperto che avevi ragione, e questo era principalmente un errore di comunicazione con il mio team operativo. Stiamo usando un nuovo formattatore per mettere un flag "ident" falso come primo argomento e rsyslog non potrebbe essere più felice. –

+0

Questa è un'informazione obsoleta, segnerei la risposta di FirefighterBlu3 come quella corretta. –

+1

Non c'è motivo di downvote perché le informazioni non sono aggiornate. Era la risposta corretta al momento, e grazie a 'FirefighterBlu3' per aver fornito l'aggiornamento. –

4

Questo è un po 'vecchio ma le nuove informazioni dovrebbero essere registrate qui così le persone non sentono il bisogno di scrivere il proprio gestore syslog.

A partire da Python 3.3, lo SysLogHandler ha un attributo di classe .ident proprio per questo scopo; l'impostazione predefinita è "".

Esempio:

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

Questo è Python 3.3+. – malthe

2

Per Python 2.7, si potrebbe fare qualcosa di simile:

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") 

Questo produrrà nel syslog:

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

3

implementazioni Syslog accettando I messaggi RFC3164 dovrebbero prima riconoscere parte del messaggio ("foo:" nell'esempio) come TAG.

La parte MSG ha due campi noti come il campo TAG e il campo CONTENUTO . Il valore nel campo TAG sarà il nome del programma o il processo che ha generato il messaggio.

codice 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 Invia questo nella presa 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) 

Che a sua volta, produce questo nel diario di systemd.

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

Journal dettagli del messaggio:

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

Funziona con Py2.6, 2.7, 3.4, 3.5 e syslog server di Systemd. Può funzionare anche con altre implementazioni di syslog (se accettano RFC3164). Questa soluzione si interromperà probabilmente quando il SysLogHandler di Python verrà impostato su RFC5424 più recente.