Comprender el registro en Linux

62

Según tengo entendido, ¿el kernel de Linux registra en el /proc/kmsgarchivo (principalmente mensajes relacionados con el hardware) y el /dev/logsocket? ¿En cualquier otro lugar? ¿Otras aplicaciones también pueden enviar mensajes /proc/kmsgao /dev/log? Por último, pero no menos importante, estoy en lo correcto que es el demonio syslog ( rsyslog , syslog-ng ) que comprueba los mensajes de esos dos lugares y luego distribuye los diversos archivos como /var/log/messageso /var/log/kern.logo servidor syslog incluso central?

Martín
fuente

Respuestas:

81

Simplificado, es más o menos así:

El kernel registra los mensajes (usando la printk()función) en un buffer de anillo en el espacio del kernel. Estos mensajes están disponibles para las aplicaciones de espacio de usuario de dos maneras: a través del /proc/kmsgarchivo (siempre que /procesté montado) y a través de sys_syslogsyscall.

Hay dos aplicaciones principales que leen (y, hasta cierto punto, pueden controlar) el búfer en anillo del núcleo: dmesg(1)y klogd(8). El primero está destinado a ser ejecutado a pedido por los usuarios, para imprimir el contenido del búfer en anillo. Este último es un demonio que lee los mensajes /proc/kmsg(o llamadas sys_syslog, si /procno está montado) y los envía a syslogd(8), o a la consola. Eso cubre el lado del núcleo.

En el espacio del usuario, hay syslogd(8). Este es un demonio que escucha en varios zócalos de dominio UNIX (principalmente /dev/log, pero también se pueden configurar otros), y opcionalmente en el puerto UDP 514 para mensajes. También recibe mensajes de klogd(8)( syslogd(8)no le importa /proc/kmsg). Luego escribe estos mensajes en algunos archivos /log, o en canalizaciones con nombre, o los envía a algunos hosts remotos (a través del syslogprotocolo, en el puerto UDP 514), como está configurado en /etc/syslog.conf.

Las aplicaciones de espacio de usuario normalmente usan la libcfunción syslog(3)para registrar mensajes. libcenvía estos mensajes al socket de dominio UNIX /dev/log(donde son leídos syslogd(8)), pero si una aplicación es chroot(2)-ed, los mensajes podrían terminar siendo escritos en otros sockets, fi /var/named/dev/log. Por supuesto, es esencial para las aplicaciones que envían estos registros y syslogd(8)acordar la ubicación de estos sockets. Por esta razón, syslogd(8)se puede configurar para escuchar tomas adicionales aparte del estándar /dev/log.

Finalmente, el syslogprotocolo es solo un protocolo de datagrama. Nada impide que una aplicación envíe datagramas de syslog a cualquier socket de dominio UNIX (siempre que sus credenciales le permitan abrir el socket), omitiendo la syslog(3)función por libccompleto. Si los datagramas están formateados correctamente, syslogd(8)puede usarlos como si los mensajes se hubieran enviado syslog(3).

Por supuesto, lo anterior cubre solo la teoría de tala "clásica". Otros demonios (como rsyslogy syslog-ng, como usted menciona) pueden reemplazar el plano syslogd(8)y hacer todo tipo de cosas ingeniosas, como enviar mensajes a hosts remotos a través de conexiones TCP encriptadas, proporcionar marcas de tiempo de alta resolución, etc. Y también hay systemd, que está fagocitando lentamente la parte UNIX de Linux. systemdtiene sus propios mecanismos de registro, pero esa historia tendría que ser contada por otra persona. :)

Diferencias con el mundo * BSD:

En * BSD no existe klogd(8), y /procno existe (en OpenBSD) o es en su mayoría obsoleto (en FreeBSD y NetBSD). syslogd(8)lee los mensajes del núcleo del dispositivo de caracteres /dev/klogy los dmesg(1)utiliza /dev/kmempara decodificar los nombres del núcleo. Solo OpenBSD tiene un /dev/log. FreeBSD usa dos sockets de dominio UNIX /var/run/logy var/rub/logpriv, en cambio, NetBSD tiene un /var/run/log.

lcd047
fuente
3
nit: rsyslog es más popular ahora (predeterminado para Fedora, Debian), y no utiliza un klogd separado. Parece que syslog-ng tampoco lo hace (por preferencia).
sourcejedi
@sourcejedi No he seguido a Linux tan de cerca en más de unos años, pero el IIRC rsyslogno lo usa klogd(8)porque sus raíces se remontan, no porque recientemente haya tomado una decisión explícita de eliminarlo. Sin embargo, mi memoria puede estar fallando. De todos modos, como dije, solo estaba tratando de cubrir el registro "clásico".
lcd047
1
@ lcd047, @sourcejedi, ¡Gracias por las respuestas! Tenía un sistema Debian 7 con rsyslogdejecución y un Ubuntu 12.04 con syslog-ngejecución y ambos tenían el archivo /proc/kmsgabierto de acuerdo lsof, es decir, klogdno se usaba. Otra cosa interesante que noté es que los mensajes de registro se almacenan en un /proc/kmsgarchivo si no se está ejecutando un demonio syslog y uno puede verlos con, por ejemplo, cato editor de texto. Sin embargo, solo es posible ver esos mensajes una vez porque desaparecen después de verlos. Por último, pero no menos importante, la ejecución dmesgno borra el contenido del /proc/kmsgarchivo.
Martin
1
@ Martin /proc/kmsgno es un archivo normal, no hay nada "almacenado" allí, sino que es solo una vista del búfer de anillo del núcleo. Puede leerlo catprecisamente porque no tiene klogd(8)ejecución (si ejecuta klogd(8), cat /proc/kmsgbloquearía). dmesg(1)lee mensajes de en /dev/kmsglugar de /proc/kmsg; y también puede borrar el búfer si se lo indica.
lcd047
1
systemd has its own logging mechanisms, but that story would have to be told by somebody else. :)- Por favor, dices, tienes talento :-)
Flavius
51

La otra respuesta explica, como dice su autor, "registro clásico" en Linux. Así no es como funcionan las cosas en muchos sistemas hoy en día.

El núcleo

Los mecanismos del kernel han cambiado.

El kernel genera salida a un búfer en memoria. Los softwares de aplicación pueden acceder a esto de dos maneras. El subsistema de registro generalmente accede a él como un pseudo-FIFO llamado /proc/kmsg. Esta fuente de información de registro no se puede compartir útilmente entre los lectores de registro, ya que es de lectura única. Si varios procesos lo comparten, cada uno obtiene solo una parte de la secuencia de datos de registro del kernel. También es de solo lectura.

La otra forma de acceder es el /dev/kmsgdispositivo de caracteres más nuevo . Esta es una interfaz de lectura y escritura que se puede compartir entre múltiples procesos de clientes. Si varios procesos lo comparten, todos leen el mismo flujo de datos completo, sin verse afectados entre sí. Si lo abren para acceso de escritura, también pueden inyectar mensajes en la secuencia de registro del núcleo, como si fueran generados por el núcleo.

/proc/kmsgy /dev/kmsgproporcionar datos de registro en un formulario que no sea RFC-5424.

Aplicaciones

Las aplicaciones han cambiado.

La syslog()función de la biblioteca GNU C en los intentos principales de conectarse a un AF_LOCALsocket de datagrama llamado /dev/logy escribir entradas de registro en él. (La syslog()función de la biblioteca BSD C hoy en día se usa /var/run/logcomo el nombre del socket, e intenta /var/run/logprivprimero). Las aplicaciones pueden, por supuesto, tener su propio código para hacerlo directamente. La función de biblioteca es solo código (para abrir, conectar, escribir y cerrar un socket) ejecutándose en el contexto del proceso de la aplicación, después de todo.

Las aplicaciones también pueden enviar mensajes RFC 5424 a través de UDP a un servidor RFC 5426 local, si uno está escuchando en un zócalo AF_INET/ AF_INET6datagrama en la máquina.

Gracias a la presión del mundo de daemontools en las últimas dos décadas, muchos demonios admiten la ejecución en un modo en el que no utilizan la syslog()función de biblioteca GNU C o los sockets UDP, sino que simplemente escupen sus datos de registro al error estándar en el La moda ordinaria de Unix.

gestión de registros con nosh y la familia daemontools en general

Con la familia de conjuntos de herramientas daemontools, hay mucha flexibilidad en el registro. Pero, en general, en toda la familia, la idea es que cada demonio "principal" tiene un demonio "de registro" asociado. los dæmons "principales" funcionan igual que los procesos que no son dæmon y escriben sus mensajes de registro en un error estándar (o salida estándar), que el subsistema de administración de servicios se encarga de conectar a través de una tubería (que se mantiene abierta para que los datos de registro no se pierdan un reinicio del servicio) a la entrada estándar del demonio "logging".

Todos los demonios de "registro" ejecutan un programa que registra en alguna parte . En general, este programa es algo así multilogo cyclogque lee de la entrada estándar y escribe (sellos de tiempo de nanosegundos) archivos en una, exclusiva-escritura, directorio estrictamente tamaño límite máximo, giran automáticamente de registro. En general, también, todos estos demonios se ejecutan bajo los auspicios de cuentas de usuario dedicadas individuales sin privilegios.

Entonces uno termina con un sistema de registro ampliamente distribuido, con los datos de registro de cada servicio procesados ​​por separado.

Uno puede ejecutar algo como klogdo syslogdo rsyslogdbajo una gestión de servicios daemontools familiar. Pero el mundo de daemontools se dio cuenta hace muchos años de que la estructura de gestión de servicios con demonios "logging" se presta claramente para hacer las cosas de una manera más simple. No es necesario desplegar todas las secuencias de registro en una mezcla gigante, analizar los datos de registro y luego volver a desplegar las secuencias para separar los archivos de registro; y luego (en algunos casos) atornille un mecanismo de rotación de registro externo poco confiable en el lateral. La estructura de la familia daemontools como parte de su gestión de registros estándar ya realiza la rotación de registros, la escritura del archivo de registro y la separación de la secuencia.

Además: el modelo de carga en cadena de la eliminación de privilegios con herramientas comunes en todos los servicios significa que los programas de registro no necesitan privilegios de superusuario; y el modelo UCSPI significa que solo necesitan preocuparse por las diferencias, como el transporte de flujo versus el de datagrama.

El conjunto de herramientas nosh ejemplifica esto. Si bien se puede ejecutar rsyslogddebajo de él, listo para usar , y simplemente administrar el kernel /run/logy la entrada de registro UDP de la manera anterior; que también ofrece más formas "nativos" daemontools de registro de estas cosas:

  • un klogdservicio que lee /proc/kmsgy simplemente escribe esa secuencia de registro en su error estándar. Esto se hace mediante un programa simple llamado klog-read. El demonio de registro asociado alimenta la secuencia de registro en su entrada estándar en un /var/log/sv/klogddirectorio de registro.
  • un local-syslog-readservicio que lee datagramas de /dev/log( /run/logen los BSD) y simplemente escribe esa secuencia de registro en su error estándar. Esto lo hace un programa llamado syslog-read. El demonio de registro asociado alimenta la secuencia de registro en su entrada estándar en un /var/log/sv/local-syslog-readdirectorio de registro.
  • un udp-syslog-readservicio que escucha en el puerto UDP syslog, lee lo que se le envía y simplemente escribe esa secuencia de registro en su error estándar. De nuevo, el programa es syslog-read. El demonio de registro asociado alimenta la secuencia de registro en su entrada estándar en un /var/log/sv/udp-syslog-readdirectorio de registro.
  • (en los BSD) un local-priv-syslog-readservicio que lee datagramas /run/logprivy simplemente escribe esa secuencia de registro en su error estándar. De nuevo, el programa es syslog-read. El demonio de registro asociado alimenta la secuencia de registro en su entrada estándar en un /var/log/sv/local-priv-syslog-readdirectorio de registro.

El conjunto de herramientas también viene con una export-to-rsyslogherramienta que puede monitorear uno o varios directorios de registro (usando un sistema de cursores de registro no intrusivos ) y enviar nuevas entradas en forma RFC 5424 a través de la red a un servidor RFC 5426 designado.

gestión de registros con systemd

systemd tiene un solo programa de gestión de registros monolítico, systemd-journald. Esto se ejecuta como un servicio administrado por systemd.

  • Se lee /dev/kmsgpara los datos de registro del kernel.
  • Lee /dev/log(un enlace simbólico /run/systemd/journal/dev-log) para los datos de registro de la aplicación de la syslog()función de la biblioteca GNU C.
  • Escucha en el AF_LOCALsocket del flujo en /run/systemd/journal/stdoutbusca de datos de registro provenientes de servicios administrados por systemd.
  • Escucha en el AF_LOCALzócalo del datagrama en /run/systemd/journal/socketbusca de datos de registro procedentes de programas que hablan el protocolo de diario específico del sistema (es decir, sd_journal_sendv()et al.).
  • Los mezcla todos juntos.
  • Escribe en un conjunto de archivos de diario de todo el sistema y por usuario, en /run/log/journal/o /var/log/journal/.
  • Si puede conectarse (como cliente) a un AF_LOCALzócalo de datagrama en el /run/systemd/journal/syslogque escribe datos del diario allí, si está configurado el reenvío a syslog.
  • Si está configurado, escribe datos del diario en el búfer del núcleo utilizando el /dev/kmsgmecanismo de escritura .
  • Si está configurado, escribe datos de diario en terminales y también en el dispositivo de consola.

Las cosas malas suceden en todo el sistema si este programa falla o si se detiene el servicio.

systemd mismo organiza las salidas estándar y los errores de (algunos) servicios para que se conecten al /run/systemd/journal/stdoutsocket. Entonces, los demonios que inician sesión en el error estándar de la manera normal tienen su salida enviada al diario.

Esto reemplaza completamente a klogd, syslogd, syslog-ng y rsyslogd.

Ahora se requiere que sean específicos del sistema. En un sistema systemd no llegan a ser el servidor final /dev/log. En cambio, toman uno de dos enfoques:

  • Llegan a ser el extremo del servidor /run/systemd/journal/syslog, que (si recuerdas) systemd-journaldintenta conectarse y escribir datos del diario. Hace un par de años, uno habría configurado el imuxsockmétodo de entrada de rsyslogd para hacer esto.
  • Leen directamente del diario de systemd, usando una biblioteca específica de systemd que comprende el formato de diario binario y que puede monitorear los archivos de diario y el directorio para nuevas entradas que se agregan. Hoy en día, uno configura el imjournalmétodo de entrada de rsyslogd para hacer esto.
JdeBP
fuente