Por Helder Guerreiro.
Existem muitas situações onde a visualização da informação sob a forma de um gráfico facilita a compreensão do que se está a passar. Por exemplo poderá ser normal termos a carga do sistema a 7.0 ou 8.0 durante breves períodos de tempo num servidor de base de dados, podemos estar a fazer a consolidação de dados diária, ou a extrair um dump da base de dados para backup. No entanto já não será normal termos valores de carga do sistema permanentemente neste valores. Se tivermos um gráfico com as variações nas últimas 24H da carga do sistema, facilmente se encontram estes tipos de problemas.
Neste artigo vou apresentar a ferramenta RRDtool que nos permite de uma forma rápida e prática fazer gráficos e não só de dados que variem no tempo.
O RRDtool desempenha as seguintes funções:
Para fazer os gráficos podemos utilizar as ferramentas de linha de comandos incluídas na distribuição da ferramenta, ou então usar uma das ligações disponíveis para linguagens de programação como o Perl ou o Python.
O RRDtool está disponível em todas as distribuições de Linux. Por exemplo para o Debian, ou Kubunto basta fazer o seguinte para instalar o pacote:
# apt-get install rrdtool
A documentação disponibilizada na distribuição do RRDtool é de muito boa qualidade e está disponível através do comando 'man', em texto simples, em html, etc. Como o RRDtool tem muitas opções o comando principal 'rrdtool' admite uma série de sub-comandos. Para saber quais os comandos disponíveis basta fazer:
$ rrdtool help RRDtool 1.2.19 Copyright 1997-2007 by Tobias OetikerCompiled May 22 2007 13:48:39 Usage: rrdtool [options] command command_options Valid commands: create, update, updatev, graph, dump, restore, last, lastupdate, first, info, fetch, tune, resize, xport RRDtool is distributed under the Terms of the GNU General Public License Version 2. (www.gnu.org/copyleft/gpl.html) For more information read the RRD manpages
(Assinalei os sub-comandos a azul.)
Para obter ajuda sobre o sub-comando específico fazer 'man rdd<sub-comando>'. Para ler um guia do programa fazer 'man rrdtutorial'. É claro que se pode também consultar a home page do programa onde toda a informação também está disponível.
Vamos imaginar que queremos fazer um gráfico com a carga do sistema, onde seja possível mostrar as variações das últimas 24 horas. Esta carga pode-se obter de várias formas diferentes. Tradicionalmente o valor da carga do sistema é apresentado em média para o último minuto, para os últimos 5 minutos e para os últimos 15 minutos.
O comando para criar base de dados pode ser:
( i)$ rrdtool create \ ( ii) /arquivo/rrd/carga_sistema.rrd \ (iii) --start 1235667600 \ ( iv) --step=300 \ ( v) DS:carga:GAUGE:600:U:U \ ( vi) RRA:AVERAGE:0.33:1:288 \ (vii) RRA:AVERAGE:0.5:4:504
Como se pode ver o comando é mais parecido a uma pequena linguagem de programação do que a um comando normal. Por esta razão e para registo futuro, convém guardar o comando de criação das bases de dados num ficheiro, como um shell script.
O que este comando faz, passo a passo é:
$ date +"%s"
Para cada base de dados podemos ter múltiplas fontes de informação, basta acrescentar linhas como estas tendo o cuidado de ir escolhendo nomes diferentes para cada fonte. O tipo de informação não tem de ser idêntico para cada fonte. De facto cada fonte não necessita de ter nada a ver com a anterior.
Consultar a 'man page' rrdcreate para uma descrição completa de todas as opções possíveis nesta linha;
Atenção que na função para desenho dos gráficos podemos especificar fontes de informação de bases de dados diferentes, pelo que será essa a forma ideal de termos especificações diferentes dos arquivos para fontes de informação diferentes.
Esta linha decifra-se da seguinte forma:
Continuando o exemplo, o primeiro problema a resolver vai ser a recolha dos dados. Isso pode-se fazer de várias formas, usando as ferramentas tradicionais do unix (awk, cut, etc), ou usando qualquer outra ferramenta. Por exemplo com usando um shell script com um bocadinho de python à mistura, ficamos com:
#!/bin/sh CARGA=`uptime | python -c "import sys; print sys.stdin.read().split()[-2][:-1]"` HORA=`date +"%s"` rrdtool update /arquivo/rrd/carga_sistema.rrd $HORA:$CARGA
O sub-comando 'update' é muito mais simples que o 'create'. Mesmo assim, podemos complicar um bocadinho mais se tivermos várias fontes de informação (DS). Se tivermos, por exemplo várias fontes de informação o comando ficaria:
rrdtool update <base de dados> <tempo>:<valor fonte 1>:<valor fonte 2>:etc...
A ordem das fontes de informação será a mesma ordem pela qual foi criada a base de dados. Se não quisermos usar esta ordem, podemos especificar directamente a ordem usando a opção '--template'.
Finalmente, podemos introduzir várias leituras de uma vez, na mesma linha de comando:
rrdtool update <base de dados> \
<tempo 1>:<valor fonte 1>:<valor fonte 2>:etc... \
<tempo 2>:<valor fonte 1>:<valor fonte 2>:etc... \
etc...
Resta-nos automatizar a invocação deste script a cada 5 minutos, para tal basta editar o crontab:
$ crontab -e
E acrescentar a linha:
*/5 * * * * /arquivo/scripts/update_rdd
(Assumindo que o script acima foi gravado em '/arquivo/scripts/update_rdd' e tornado executável.)
Tal como o comando para criar a base de dados, o comando para criar gráficos é também ele muito complicado. A documentação completa deste comando compreende:
Para o exemplo da carga do sistema, qualquer coisa como o seguinte bastaria:
( i)rrdtool graph \ ( ii) /arquivo/rrd/carga_sistema.png \ (iii) --title "Carga do sistema nas ultimas 24 Horas" \ ( iv) DEF:carga=/arquivo/rrd/carga_sistema.rrd:carga:AVERAGE \ ( v) AREA:carga#e4a25e LINE2:carga#5e0710:"Carga"
Este comando gera o gráfico seguinte:

DEF:nome_var=fich_rrd:fonte_informação:função consolidação[:step=step][:start=tempo][:end=tempo]
Notar que esta linha apenas torna disponível a fonte de informação às funções que vão desenhar o gráfico.
O formato para criar o gráfico é:
<Tipo de gráfico>:<nome da variável>[#cor][:[legenda][:STACK]]
Não especificámos o tempo inicial e final para construir este gráfico, isto porque, por omissão, são desenhadas as últimas 24Horas. Se quisermos especificar o inicio do gráfico, basta usar a opção '--start=<tempo inicial>' e para especificar o fim a opção '--end=<tempo final>'. Em ambos os casos os tempos devem ser dados em segundos desde 1970-01-01 00:00:00 UTC. Por exemplo para calcularmos a última semana, podemos usar:
AGORA=`date +"%s"` ULTIMASEMANA=$(($AGORA - 3600*24*7))
Podemos criar fontes de dados a partir de variáveis já existentes. Imaginemos que tínhamos um serviço de transferência de ficheiros (que é útil ter para transferir documentos volumosos entre filiais de uma empresa). No nosso site interno vamos armazenando as estatísticas numa base de dados 'round robin'. Um gráfico para apresentar o tráfego poderá ser qualquer coisa como:
rrdtool graph \
/arquivo/rrd/teste.png \
--title "Tipo de uploads" \
DEF:nfotos=/arquivo/rrd/estatistica_site.rrd:nfotos:AVERAGE \
DEF:npdf=/arquivo/rrd/estatistica_site.rrd:npdf:AVERAGE \
LINE2:nfotos:"Fotos recebidas" \
LINE2:npdf:"Arquivos PDF"
Se quisermos mostrar o total de ficheiros transferidos, podemos usar criar uma fonte de dados, por exemplo com:
CDEF:total=nfotos,npdf,+
Notar que se utiliza a notação polaca reversa para fazer esta operação. A explicação desta notação sai fora do âmbito deste artigo. Esta notação é bastante familiar para quem utiliza máquinas de calcular cientificas da HP. Em geral começa-se por indicar os argumentos da função e no fim a função a calcular (neste caso uma adição simples). Por exemplo:
A seguir podemos traçar em gráfico esta variável:
rrdtool graph \
/arquivo/rrd/teste.png \
--title "Tipo de uploads" \
DEF:nfotos=/arquivo/rrd/estatistica_site.rrd:nfotos:AVERAGE \
DEF:npdf=/arquivo/rrd/estatistica_site.rrd:npdf:AVERAGE \
LINE2:nfotos:"Fotos recebidas" \
LINE2:npdf:"Arquivos PDF" \
CDEF:total=nfotos,npdf,+ \
AREA:total#accff5:"Total Geral"
O RRDtool é uma ferramenta valiosíssima na interpretação dos dados produzidos num sistema. Permite-nos identificar tendências imediatamente e actuar de forma preventiva. Se tivermos sensores externos podemos usar o RRDtool para representar uma gama enorme de fenómenos.