Da quanto ho capito, il kernel Linux si registra su /proc/kmsg
file (per lo più messaggi relativi all'hardware) e /dev/log
PRESA? Da qualsiasi altra parte? Anche altre applicazioni sono in grado di inviare messaggi a /proc/kmsg
o /dev/log
? Ultimo ma non meno importante, ho ragione sul fatto che è il demone syslog(rsyslog , syslog-ng ) che controlla i messaggi da queste due posizioni e poi li distribuisce a vari file come /var/log/messages
o /var/log/kern.log
o anche server syslog centrale?
Risposta accettata:
Semplificato, funziona più o meno così:
Il kernel registra i messaggi (usando printk()
funzione) in un buffer ad anello nello spazio del kernel. Questi messaggi sono resi disponibili alle applicazioni dello spazio utente in due modi:tramite il /proc/kmsg
file (a condizione che /proc
è montato) e tramite sys_syslog
syscall.
Esistono due applicazioni principali che leggono (e, in una certa misura, possono controllare) il buffer circolare del kernel:dmesg(1)
e klogd(8)
. Il primo è concepito per essere eseguito su richiesta dagli utenti, per stampare il contenuto del buffer dell'anello. Quest'ultimo è un demone che legge i messaggi da /proc/kmsg
(o chiama sys_syslog
, se /proc
non è montato) e li invia a syslogd(8)
o alla console. Questo copre il lato del kernel.
Nello spazio utente c'è syslogd(8)
. Questo è un demone che ascolta su un certo numero di socket di dominio UNIX (principalmente /dev/log
, ma possono essere configurati anche altri) e facoltativamente alla porta UDP 514 per i messaggi. Riceve anche messaggi da klogd(8)
(syslogd(8)
non si preoccupa di /proc/kmsg
). Quindi scrive questi messaggi in alcuni file in /log
, o a named pipe, o li invia ad alcuni host remoti (tramite il syslog
protocollo, sulla porta UDP 514), come configurato in /etc/syslog.conf
.
Le applicazioni dello spazio utente normalmente usano libc
funzione syslog(3)
per registrare i messaggi. libc
invia questi messaggi al socket di dominio UNIX /dev/log
(dove vengono letti da syslogd(8)
), ma se un'applicazione è chroot(2)
-ed i messaggi potrebbero finire per essere scritti su altri socket, f.i. a /var/named/dev/log
. Ovviamente è essenziale per le applicazioni che inviano questi log e syslogd(8)
concordare la posizione di queste prese. Per questi motivi syslogd(8)
può essere configurato per ascoltare socket aggiuntivi oltre allo standard /dev/log
.
Infine, il syslog
protocollo è solo un protocollo datagramma. Niente impedisce a un'applicazione di inviare datagrammi syslog a qualsiasi socket di dominio UNIX (a condizione che le sue credenziali gli consentano di aprire il socket), bypassando il syslog(3)
funzione in libc
completamente. Se i datagrammi sono formattati correttamente syslogd(8)
può usarli come se i messaggi fossero stati inviati tramite syslog(3)
.
Naturalmente, quanto sopra copre solo la teoria della registrazione "classica". Altri demoni (come rsyslog
e syslog-ng
, come dici tu) può sostituire il semplice syslogd(8)
e fare ogni sorta di cose eleganti, come inviare messaggi a host remoti tramite connessioni TCP crittografate, fornire timestamp ad alta risoluzione e così via. E c'è anche systemd
, che sta lentamente fagocitando la parte UNIX di Linux. systemd
ha i suoi meccanismi di registrazione, ma quella storia dovrebbe essere raccontata da qualcun altro. 🙂
Differenze con il *mondo BSD:
Su *BSD non c'è klogd(8)
e /proc
o non esiste (su OpenBSD) o è per lo più obsoleto (su FreeBSD e NetBSD). syslogd(8)
legge i messaggi del kernel dal dispositivo di caratteri /dev/klog
e dmesg(1)
utilizza /dev/kmem
per decodificare i nomi del kernel. Solo OpenBSD ha un /dev/log
. FreeBSD usa due socket di dominio UNIX /var/run/log
e var/rub/logpriv
invece, e NetBSD ha un /var/run/log
.