Exibindo a hora do log do Squid de forma legível

Introdução
Quando está utilizando o seu formato padrão, o log do squid armazena a data e hora do acesso no formato de timestamp chamado Unix Time, que é a quantidade de segundos passados após a data 01/01/1970. Esse formato é útil, pois facilita cálculos com datas. Por exemplo: para calcular a distancia entre duas datas, basta converter ambas para o timestamp, subtrair a menor da maior e reconverter o resultado para minutos/horas/dias/etc. O problema é que o formato não facilita a visualização de dados no dia-a-dia. Existem vários comandos possíveis para realizar a conversão para um formato de leitura mais agradável. Vou colocar aqui a minha preferida, que envolve o poderosíssimo AWK.

Criando o script
Crie um arquivo com um nome sugestivo (por exemplo timestamp.sh) com o conteúdo abaixo e o salve em algum diretório que conste na variável de ambiente PATH (/usr/local/bin, por exemplo):

#!/bin/bash
awk '{$1=strftime("%F %T",$1);print $0}' $1



As letras entre aspas dentro dos parênteses controlam o formato de saída. Consulte a página de manual do comando date para checar outras opções de formatos. Por exemplo, %F exibe a data no formatoYYYY-MM-DD, e %T exibe a hora no formato 24 horas hh:mm:ss.

Utilização
Existem duas formas de se utilizar o script: chamando o arquivo de log diretamente (timestamp.sh access.log) ou através de um pipe (cat access.log | timestamp.sh).

Observação
As alterações são realizadas apenas "na tela", ou seja, o conteúdo do arquivo continua inalterado, com a data armazenada no formato timestamp. na verdade, isso é desejável, pois caso não impede o processamento do log do squid por programas de relatórios (como o sarg e o sawmill). Caso você necessite de um arquivo com as datas em formato "legível", basta redirecionar a saída da tela com os redirecionadores > (sobrescrever) ou >> (concatenar), conforme a necessidade.

Problemas relacionados a servidores NTP

Estes são alguns problemas que encontrei em servidores NTP que administro e que resolvi (após bater cabeça por um tempinho ...). Ficam aqui as soluções para quem precisar:

Erro:
sendto(200.160.0.8): Bad file descriptor

Sintomas:
Aparecem linhas como as abaixo no seu log de sistema (geralmente no arquivo /var/log/messages ou /var/log/syslog):

Jul 14 10:21:39 server ntpd[29169]: bind() fd 4, family 2, port 123, addr 0.0.0.0, in_classd=0 flags=8 fails: Address already in use
Jul 14 10:21:39 server ntpd[29169]: bind() fd 4, family 10, port 123, addr ::, in6_is_addr_multicast=0 flags=0 fails: Address already in use
Jul 14 10:21:39 server ntpd[29169]: bind() fd 4, family 2, port 123, addr 127.0.0.1, in_classd=0 flags=0 fails: Address already in use
Jul 14 10:21:39 server ntpd[29169]: bind() fd 4, family 2, port 123, addr 172.20.32.6, in_classd=0 flags=8 fails: Address already in use
Jul 14 10:21:40 server ntpd[29169]: sendto(200.160.0.8): Bad file descriptor
Jul 14 10:21:41 server ntpd[29169]: sendto(200.189.40.8): Bad file descriptor
Jul 14 10:32:55 server ntpd[29368]: sendto(200.160.0.8): Bad file descriptor
Jul 14 10:32:57 server ntpd[29368]: sendto(200.192.232.8): Bad file descriptor
Jul 14 10:32:57 server ntpd[29368]: sendto(200.160.0.8): Bad file descriptor
Jul 14 10:32:59 server ntpd[29368]: sendto(200.192.232.8): Bad file descriptor
Jul 14 10:32:59 server ntpd[29368]: sendto(200.189.40.8): Bad file descriptor


Onde server é o nome do seu servidor e os IPs entre parênteses são os IPs dos servidores públicos configurados nos arquivos de configuração (os IPs acima são do projeto brasileiro NTP.br, que disponibiliza servidores atualizados pelo Relógio Atômico do Observatório Nacional - http://www.on.br - , que por sua vez é o responsável pela Hora Legal Brasileira).

Causa:
Existe mais de um processo do servidor NTP (ntpd) rodando na máquina.

Solução:
Pare o serviço do NTP. Em distribuições da família Debian (Ubuntu, Kurumin, Knoppix, etc) e da família Red Hat (Fedora, Mandriva, CentOS, etc) normalmente isso é realizado com /etc/init.d/ntp stop. Em outras distribuições (SlackWare, Gentoo, ?) o processo pode ser diferente, mas não muito. Após parar o serviço, execute um killall ntpd para matar quaisquer processos que possam ter restado e inicie novamente o serviço NTP com /etc/init.d/ntp start (ou comando equivalente em sua distribuição) e o problema deve estar resolvido. Obs: todos os comandos acima necessitam de permissões de root para serem executados.

Dica:
Observe a seguinte linha, retirada do trecho de log acima:

Jul 14 10:21:39 server ntpd[29169]: bind() fd 4, family 2, port 123, addr 0.0.0.0, in_classd=0 flags=8 fails: Address already in use

Em programas com suporte a rede (geralmente programas servidores), bind() é o ato de associar um programa ou processo a uma determinada porta de rede. Observe que o próprio programa já mostra o erro que está ocorrendo: Address already in use, ou seja, o endereço já está em uso por outro processo. Esse tipo de erro é um tanto comum e a mensagem costuma vir parecida com essas, facilitando assim encontrar a solução.


Erro:
O serviço exibe uma mensagem de erro ao iniciar, sobe mas não sincroniza a hora com os servidores externos.

Sintomas:

Aparecem linhas como as abaixo no seu log de sistema (geralmente no arquivo /var/log/messages ou /var/log/syslog):
Jul 14 10:38:11 server ntpdate[30521]: no server suitable for synchronization found
Jul 14 10:38:11 server ntpd:  failed
Jul 14 10:38:11 server ntpd[30525]: ntpd 4.2.0a@1.1190-r Sat May  5 12:55:34 EDT 2007 (1)
Jul 14 10:38:11 server ntpd: ntpd startup succeeded
Jul 14 10:38:18 server ntpd[30525]: kernel time sync disabled 0041
Jul 14 10:38:28 server ntpd[30525]: kernel time sync enabled 0001

Causa:
Servidores inválidos ou inexistentes referenciados nos arquivos de configuração /etc/ntp/ntpservers e /etc/ntp/step-tickers).

Solução:
Haviam servidores NTP internos que já haviam sido removidos da rede, mas continuavam configurados nos arquivos citados acima. Com isso, mesmo com os servidores do projeto NTP.br no arquivo de configuração principal, o serviço falhava e não se recuperava. Após remover os IPs dos servidores, o serviço passou a funcionar como um relógio ;-)

Debian Reference Card - Para imprimir e deixar à mão

Navegando na Web, encontrei essa ficha de referência sobre o Debian. Vem em Português Brasileiro (e outras dezenas de idiomas), em formato PDF para ser impresso (frente e verso) em uma única folha A4. Depois de imprimir, dobre conforme indicado na página.
O endereço para download e instruções para a dobra estão em http://tangosoft.com/refcard/. A título de curiosidade, esse tipo de ficha é bem comum e pode ser encontrado na internet com nomes como Reference Card, Cheat Sheet (algo como folha de cola, em uma tradução livre). Existem Cheat Sheets para bancos de dados, linguagens de programação e vários outros items. Conforme eu for esbarrando em outros mais, eu publico aqui.

Gerando arquivos de log com shell script

Introdução:
Shell Scripts são uma verdadeira mão na roda na administração de servidores Linux. Porém um assunto que é um tanto negligenciado neste aspecto é quanto ao registro da informação sobre o que foi feito durante a execução do script, até porque na maioria das vezes o script é executado via cron, e como você não pode ver as informações dele na tela, um arquivo ou sistema de log torna-se essencial.

Modo 1: Log via arquivo próprio
O modo mais simples de realizar o log é através de um arquivo próprio, exclusivo para sua aplicação. Existem diversas formas de se fazer isso, a que mostro a seguir é a que costumo utilizar. Considere o pequeno shell script (em bash) abaixo:



#!/bin/bash
WORKDIR="/root/my_script"
SESSION_LOG=${WORKDIR}/$$.log
LOGFILE=${WORKDIR}/my_script.log
DEST_DIR=${WORKDIR}/backups
DATE=$(date +"%Y-%m-%d_%H:%M:%S")

function LOG(){
DATA=$(date +"%Y-%m-%d %H:%M:%S")
echo ${DATA} $1 | tee -a ${SESSION_LOG}
}

LOG "Iniciando ..."
LOG "Trocando de diretorio"
cd /etc
LOG "Criando o arquivo compactado etc-${DATE}.tar.bz2 em /tmp"
tar -cvjf /tmp/etc-${DATE}.tar.bz2
LOG "Movendo o arquivo etc-${DATE}.tar.bz2 para o diretorio de destino ${DEST_DIR}"
mv /tmp/etc-${DATE}.tar.bz2 ${DEST_DIR}
LOG "Finalizado"

#Salva o log da sessão no log geral
cat  ${SESSION_LOG} >>  ${LOGFILE}

#Descomente para enviar o log da sessão para o usuário root
#mail -s "Log do backup de `date +%F`" root < ${SESSION_LOG}

#remove o log da sessão
rm -f  ${SESSION_LOG}


Nesse simples script, foi criada uma função de nome LOG que deve ser utilizada no formato LOG "Mensagem". Quando chamada, a função LOG imprime a mensagem passada na tela e também em um arquivo de log, definido na variável ${SESSION_LOG}. A vantagem de se utilizar uma função (ao invés de repetir o mesmo código por todo o script) é que, se for necessário alterar algo no código, a alteração é realizada apenas uma vez. Por exemplo, conferindo a página de manual do comando date, verifiquei que a opção %F é equivalente à %Y-%m-%d utilizada e resolvi trocá-la, para otimizar o código. Se não utilizasse uma função, teria de editar cinco linhas. Utilizando a função, basta editar apenas uma linha, independente de quantas vezes a função foi chamada. O script faz um backup do diretório /etc em um arquivo cujo nome é etc-data_hora.tar.bz2 e move esse arquivo para o diretório configurado na variável ${DEST_DIR}, sempre informando (no log de sessão e na tela) o que está sendo realizado. Por fim o script envia o log da sessão para o usuário root via email, concatena o log da sessão no log geral e apaga o arquivo de log da sessão. Esse script contém algumas coisas legais para quem está estudando shell. Um dos pontos fracos dele é que não é feito tratamento de erros. Erros devem ser sempre checados (e logados)

Modo 2: Log via syslog
existe o comando logger, que permite o envio de mensagens de log diretamente pelo protocolo SYSLOG, que gerencia os logs do sistema. Nesse caso, suas mensagens cairiam em um dos arquivos de log do sistema, como o /var/log/messages ou o /var/log/syslog. Fazendo algumas configurações no arquivo de configuração do servidor syslog (normalmente em /etc/syslog.conf). 
Desejando alterar o script acima para fazer log via syslog, basta alterar a função LOG, deixando-a desse jeito:

function LOG(){
DATA=$(date +"%Y-%m-%d %H:%M:%S")
echo ${DATA} $1 | tee -a ${SESSION_LOG}
logger $1
}

Também é necessário comentar a linha "cat  ${SESSION_LOG} >>  ${LOGFILE}", pois o arquivo de log será um dos arquivos de sistema, gerenciados pelo daemon do syslog.