Entender o log no Linux

62

Pelo que entendi, o kernel do Linux registra em /proc/kmsgarquivo (principalmente mensagens relacionadas a hardware) e /dev/logsoquete? Em outro lugar? Outros aplicativos também podem enviar mensagens para /proc/kmsgou /dev/log? Por último, mas não menos importante, estou correto que é o daemon syslog ( rsyslog , syslog-ng ), que verifica as mensagens a partir desses dois lugares e, em seguida, distribui os a vários arquivos como /var/log/messagesou /var/log/kern.logou mesmo servidor syslog central?

Martin
fonte

Respostas:

81

Simplificado, é mais ou menos assim:

O kernel registra mensagens (usando a printk()função) em um buffer de anel no espaço do kernel. Essas mensagens são disponibilizadas para aplicativos de espaço do usuário de duas maneiras: via /proc/kmsgarquivo (fornecido /procmontado) e via sys_syslogsyscall.

Existem dois aplicativos principais que lêem (e, até certo ponto, podem controlar) o buffer de anel do kernel: dmesg(1)e klogd(8). O primeiro destina-se a ser executado sob demanda pelos usuários, para imprimir o conteúdo do buffer de anel. O último é um daemon que lê as mensagens /proc/kmsg(ou chama sys_syslog, se /procnão estiver montado) e as envia para syslogd(8)ou para o console. Isso cobre o lado do kernel.

No espaço do usuário, existe syslogd(8). Este é um daemon que escuta em vários soquetes de domínio UNIX (principalmente /dev/log, mas outros também podem ser configurados) e, opcionalmente, na porta UDP 514 para mensagens. Ele também recebe mensagens de klogd(8)( syslogd(8)não se importa /proc/kmsg). Em seguida, ele escreve essas mensagens para alguns arquivos em /log, ou para pipes nomeados, ou envia-los para alguns hosts remotos (através do syslogprotocolo, na porta UDP 514), conforme configurado no /etc/syslog.conf.

Aplicativos de espaço do usuário normalmente usam a libcfunção syslog(3)para registrar mensagens. libcenvia essas mensagens para o soquete do domínio UNIX /dev/log(onde são lidas syslogd(8)), mas se um aplicativo for chroot(2)ed, as mensagens poderão acabar sendo gravadas em outros soquetes, fi /var/named/dev/log. Obviamente, é essencial para os aplicativos que enviam esses logs e syslogd(8)concordar com a localização desses soquetes. Por esse motivo, syslogd(8)pode ser configurado para escutar soquetes adicionais além do padrão /dev/log.

Finalmente, o syslogprotocolo é apenas um protocolo de datagrama. Nada impede que um aplicativo envie datagramas syslog para qualquer soquete de domínio UNIX (desde que suas credenciais permitam a abertura do soquete), ignorando completamente a syslog(3)função libc. Se os datagramas estiverem formatados corretamente, syslogd(8)use-os como se as mensagens fossem enviadas syslog(3).

Obviamente, o exposto acima cobre apenas a teoria "clássica" da exploração madeireira. Outros daemons (como rsysloge syslog-ng, como você mencionou) podem substituir a planície syslogd(8)e fazer todo tipo de coisa bacana, como enviar mensagens para hosts remotos por meio de conexões TCP criptografadas, fornecer registros de data e hora de alta resolução e assim por diante. E há também systemdque está lentamente fagocitando a parte UNIX do Linux. systemdpossui seus próprios mecanismos de registro, mas essa história teria que ser contada por outra pessoa. :)

Diferenças com o mundo * BSD:

No * BSD não existe klogd(8)e /procnem existe (no OpenBSD) ou é mais obsoleto (no FreeBSD e NetBSD). syslogd(8)lê mensagens do kernel do dispositivo de caractere /dev/kloge dmesg(1)usa /dev/kmempara decodificar nomes do kernel. Somente o OpenBSD possui um /dev/log. O FreeBSD usa dois soquetes de domínio UNIX /var/run/loge var/rub/logpriv, em vez disso, o NetBSD possui um /var/run/log.

lcd047
fonte
3
nit: rsyslog é mais popular agora (padrão para o Fedora, Debian) e não usa um klogd separado. Parece que o syslog-ng também não (por preferência).
sourcejedi
@sourcejedi Não acompanho o Linux tão de perto há mais de alguns anos, mas o IIRC rsyslognão usa klogd(8)porque suas raízes remontam, não porque recentemente tomou uma decisão explícita de acabar com ele. Minha memória pode estar falhando. De qualquer forma, como eu disse, só estava tentando cobrir o registro "clássico".
Lcd047 30/05
1
@ lcd047, @sourcejedi, Obrigado pelas respostas! Eu tinha um sistema Debian 7 em rsyslogdexecução e um Ubuntu 12.04 em syslog-ngexecução e ambos tinham arquivos /proc/kmsgabertos de acordo com lsof, ou seja, klogdnão foram usados. Outra coisa interessante que notei é que as mensagens de log são armazenadas em /proc/kmsgarquivo se nenhum daemon syslog estiver em execução e é possível visualizá-las com, por exemplo, catou editor de texto. No entanto, só é possível visualizar essas mensagens uma vez porque elas desaparecem após a visualização. Por último, mas não menos importante, a execução dmesgnão limpa o conteúdo do /proc/kmsgarquivo.
Martin
1
@ Martin /proc/kmsgnão é um arquivo regular, não há nada "armazenado" lá, é apenas uma visão do buffer de anel do kernel. Você pode lê-lo catprecisamente porque não tem klogd(8)corrida (se você correr klogd(8), cat /proc/kmsgbloquearia). dmesg(1)lê mensagens de /dev/kmsge não /proc/kmsg; e também pode limpar o buffer, se você pedir.
Lcd047 /
1
systemd has its own logging mechanisms, but that story would have to be told by somebody else. :)- Por favor, diga que você tem talento :-)
Flavius
51

A outra resposta explica, como diz o autor, "log clássico" no Linux. Não é assim que as coisas funcionam em muitos sistemas hoje em dia.

O kernel

Os mecanismos do kernel foram alterados.

O kernel gera saída para um buffer na memória. Os softwares de aplicativos podem acessar isso de duas maneiras. O subsistema de registro geralmente o acessa como um pseudo-FIFO chamado /proc/kmsg. Essa fonte de informações de log não pode ser utilmente compartilhada entre os leitores de log, porque é de leitura única. Se vários processos o compartilharem, cada um receberá apenas uma parte do fluxo de dados do log do kernel. Também é somente leitura.

A outra maneira de acessá-lo é o /dev/kmsgdispositivo de caracteres mais recente . Essa é uma interface de leitura e gravação compartilhável entre vários processos do cliente. Se vários processos o compartilharem, todos lerão o mesmo fluxo de dados completo, não afetados um pelo outro. Se o abrirem para acesso de gravação, eles também poderão injetar mensagens no fluxo de logs do kernel, como se tivessem sido gerados pelo kernel.

/proc/kmsge /dev/kmsgforneça dados de log em um formato não RFC-5424.

Formulários

Os aplicativos foram alterados.

A syslog()função da biblioteca GNU C nas principais tentativas de se conectar a um AF_LOCALsoquete de datagrama chamado /dev/loge gravar entradas de log nele. (Atualmente, a syslog()função da biblioteca BSD C usa /var/run/logcomo o nome do soquete e tenta /var/run/logprivprimeiro.) É claro que os aplicativos podem ter seu próprio código para fazer isso diretamente. A função de biblioteca é apenas código (para abrir, conectar, gravar e fechar um soquete) executando no próprio contexto de processo do aplicativo, afinal.

Os aplicativos também podem enviar mensagens RFC 5424 via UDP para um servidor RFC 5426 local, se alguém estiver escutando em um soquete AF_INET/ AF_INET6datagrama na máquina.

Graças à pressão do mundo daemontools nas últimas duas décadas, muitos daemons suportam a execução em um modo em que não usam a syslog()função de biblioteca GNU C ou soquetes UDP, mas apenas enviam seus dados de log para erros padrão no moda Unix comum.

gerenciamento de logs com nosh e a família daemontools em geral

Com a família de conjuntos de ferramentas daemontools, há muita flexibilidade no registro. Mas, em geral, em toda a família, a idéia é que cada daemon "principal" tenha um daemon de "registro" associado. os daemon "main" funcionam como processos não daemon e gravam suas mensagens de log em erro padrão (ou saída padrão), que o subsistema de gerenciamento de serviços organiza para se conectar por meio de um pipe (que é aberto para que os dados do log não sejam perdidos) uma reinicialização do serviço) na entrada padrão do daemon "logging".

Todos os daemons de "registro" executam um programa que registra em algum lugar . Geralmente, esse programa é algo parecido multilogou cyclogque lê sua entrada padrão e grava arquivos de log (nanossegundos com carimbo de data e hora) em um diretório com tamanho estrito, rotação automática e gravação exclusiva. Geralmente, também, todos esses daemons são executados sob a égide de contas de usuários individuais não privilegiadas.

Portanto, acaba-se com um sistema de log amplamente distribuído, com os dados de log de cada serviço processados ​​separadamente.

Um pode executar algo parecido klogdou syslogdou rsyslogdsob um gerenciamento de serviços daemontools familiar. Mas o mundo daemontools percebeu há muitos anos que a estrutura de gerenciamento de serviços com "logging" daæmons se presta muito bem a fazer as coisas de uma maneira mais simples. Não há necessidade de ventilar todos os fluxos de logs em um mish-mash gigante, analisar os dados do registro e depois ventilar os fluxos de volta para separar os arquivos de log; e depois (em alguns casos) parafuse um mecanismo externo de rotação de logs não confiável ao lado. A estrutura daemontools-family como parte de seu gerenciamento de log padrão já faz a rotação do log, a gravação do arquivo de log e a separação do fluxo.

Além disso: o modelo de carregamento em cadeia de descartar privilégios com ferramentas comuns em todos os serviços significa que os programas de log não precisam de privilégios de superusuário; e o modelo UCSPI significa que eles só precisam se preocupar com diferenças como transporte de fluxo versus datagrama.

O conjunto de ferramentas nosh exemplifica isso. Enquanto alguém pode rodar rsyslogdcom ele, fora da caixa, e apenas gerenciar o kernel /run/loge a entrada de log UDP da maneira antiga; ele também fornece mais maneiras "nativas daemontools" de registrar essas coisas:

  • um klogdserviço que lê /proc/kmsge simplesmente grava esse fluxo de logs em seu erro padrão. Isso é feito por um programa simples chamado klog-read. O daemon de log associado alimenta o fluxo de log em sua entrada padrão em um /var/log/sv/klogddiretório de log.
  • um local-syslog-readserviço que lê datagramas de /dev/log( /run/lognos BSDs) e simplesmente grava esse fluxo de logs em seu erro padrão. Isso é feito por um programa chamado syslog-read. O daemon de log associado alimenta o fluxo de log em sua entrada padrão em um /var/log/sv/local-syslog-readdiretório de log.
  • um udp-syslog-readserviço que escuta na porta syslog UDP, lê o que é enviado a ele e simplesmente grava esse fluxo de log em seu erro padrão. Mais uma vez, o programa é syslog-read. O daemon de log associado alimenta o fluxo de log em sua entrada padrão em um /var/log/sv/udp-syslog-readdiretório de log.
  • (nos BSDs), um local-priv-syslog-readserviço que lê datagramas /run/logprive simplesmente grava esse fluxo de logs em seu erro padrão. Mais uma vez, o programa é syslog-read. O daemon de log associado alimenta o fluxo de log em sua entrada padrão em um /var/log/sv/local-priv-syslog-readdiretório de log.

O conjunto de ferramentas também vem com uma export-to-rsyslogferramenta que pode monitorar um ou vários diretórios de log (usando um sistema de cursores de log não intrusivos ) e enviar novas entradas no formato RFC 5424 pela rede para um servidor RFC 5426 designado.

gerenciamento de log com systemd

O systemd possui um único programa de gerenciamento de log monolítico systemd-journald,. Isso é executado como um serviço gerenciado pelo systemd.

  • Ele lê /dev/kmsgdados de log do kernel.
  • Ele lê /dev/log(um link simbólico para /run/systemd/journal/dev-log) os dados do log do aplicativo a partir da syslog()função da biblioteca GNU C.
  • Ele escuta no AF_LOCALsoquete do fluxo em /run/systemd/journal/stdoutdados de log provenientes de serviços gerenciados pelo systemd.
  • Ele escuta no AF_LOCALsoquete do datagrama em /run/systemd/journal/socketbusca de dados de log provenientes de programas que falam o protocolo de diário específico do sistema (ie sd_journal_sendv()et al.).
  • Mistura tudo isso junto.
  • Ele grava em um conjunto de arquivos de diário de todo o sistema e por usuário, em /run/log/journal/ou /var/log/journal/.
  • Se ele puder se conectar (como cliente) a um AF_LOCALsoquete de datagrama, /run/systemd/journal/syslogele gravará os dados do diário, se o encaminhamento para o syslog estiver configurado.
  • Se configurado, ele grava os dados do diário no buffer do kernel usando o /dev/kmsgmecanismo gravável .
  • Se configurado, ele grava dados do diário nos terminais e no dispositivo do console.

Coisas ruins acontecem em todo o sistema se este programa falhar ou o serviço for parado.

O próprio systemd organiza as saídas e erros padrão de (alguns) serviços a serem anexados ao /run/systemd/journal/stdoutsoquete. Portanto, daemons que registram erros padrão da maneira normal têm sua saída enviada ao diário.

Isso substitui completamente o klogd, syslogd, syslog-ng e rsyslogd.

Agora, eles precisam ser específicos do sistema. Em um sistema systemd eles não chegam ao fim do servidor /dev/log. Em vez disso, eles adotam uma das duas abordagens:

  • Eles chegam ao final do servidor /run/systemd/journal/syslog, no qual (se você se lembra) systemd-journaldtenta conectar e gravar dados do diário. Alguns anos atrás, alguém teria configurado o imuxsockmétodo de entrada do rsyslogd para fazer isso.
  • Eles lêem diretamente do diário systemd, usando uma biblioteca específica do systemd que entende o formato do diário binário e que pode monitorar os arquivos e o diretório do diário para novas entradas sendo adicionadas. Atualmente, configura-se o imjournalmétodo de entrada do rsyslogd para fazer isso.
JdeBP
fonte