Manual

do

Maker

.

com

Gerar gráficos com Grafana e Graphite, Carbon e Collectd

Gerar gráficos com Grafana e Graphite, Carbon e Collectd

Esse definitivamente não é um setup simples. E certamente gráficos com Grafana e Graphite são bem mais apreciados por administradores de sistema do que a galera de IoT. Tem muita beleza, sem dúvida. Mas o setup, não é simples.

Apesar de ter uma série de dependências entrelaçadas, dá pra usar também um broker MQTT para monitorar dispositivos, mas vou deixar essa parte para outra ocasião.

Configuração do ambiente

Para esse setup você vai precisar no mínimo de um computador x86 e uma série de serviços deverão ser configurados:

  • MySQL
  • Apache
  • Carbon
  • Grafana
  • Graphite
  • Collectd

Invés de instalar no sistema nativo, fiz o setup dentro de um container Ubuntu. Logo, o sistema nativo pode ser qualquer um, desde que suporte Docker. Para preparar um container, siga esses passos:

sudo su
apt-get install docker
docker pull ubuntu
docker run  -it --name grafana --hostname grafana -p 80:80 -v ~/my_workspace/lab:/root/workspace:rw ubuntu /bin/bash

Ao executar o último comando, nos conectamos automaticamente à instância. Se sair, ela pára sua execução. para iniciá-la em background, use o comando:

docker start grafana

E para conectar-se ao console novamente:

docker attach grafana

Como o container foi criado para iniciar o shell, os serviços que rodarão dentro dele precisarão de interação. Por essa razão, fiz um singelo script que inicia os serviços:

#!/bin/bash 
SERVICES="mysql apache2 carbon-cache grafana-server collectd" 

[ $# -eq 1 ] ||{
    echo "Use um parametro: start stop restart reload"
    exit
}
for serviceName in $SERVICES; do 
    echo "Iniciando $serviceName" 
    service  $serviceName $1 
done

Salve esse conteúdo em um arquivo. Eu criei um upServices.sh. Depois dê todas as permissões ao proprietário (que será o root):

chmod 700 upServices.sh

Instalação de pacotes

Agora que o sistema está pronto para uso, dentro dele deveremos instalar tudo o que for necessário. Comecemos por esses pacotes:

apt-get update
apt-get install graphite-web graphite-carbon mysql-server \
python-mysqldb  python-pymysql apache2 libapache2-mod-wsgi \
apt-transport-https ssl-cert

Configurando o MySQL

Como estamos instalando os pacotes agora, durante a instalação deveremos escolher uma senha para o usuário root, então nada melhor do que começar a configuração por ele mesmo.

Tão logo os pacotes tenham sido instalados, conecte-se ao MySQL (não preciso citar que é digitando mysql no console, certo?) e execute esses comandos:

CREATE USER 'graphite'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE IF NOT EXISTS `graphite` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON `graphite`.* TO 'graphite'@'localhost';

A senha utilizada para o usuário graphite não precisa ser a mesma que a do usuário root, ok? Só lembre-se de que os serviços que utilizam o usuário graphite devem usar a respectiva senha.

Configuração inicial do Graphite

E já que estamos falando de Graphite, vamos iniciar agora sua configuração. Devemos alterar 3 valores no arquivo /etc/graphite/local_settings.py. Encontre-os no arquivo e defina os seguintes valores:

SECRET_KEY = 'password'
TIME_ZONE = 'America/Sao_Paulo'
DATABASES = {
    'default': {
        'NAME': 'graphite',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'graphite',
        'PASSWORD': 'password',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'STORAGE_ENGINE':'INNODB'
    }
}

Após, devemos executar duas vezes o seguinte comando:

graphite-manage syncdb

Isso porque ocorrerá um erro na primeira execução:

django.db.utils.IntegrityError: (1215, u'Cannot add foreign key constraint')

Não se preocupe, na segunda vez não haverá mais mensagens de erro e tudo funcionará.

Cache do Carbon no boot

O Carbon é o "cara" que recebe os dados e os repassa. Para configurá-lo, edite o arquivo /etc/default/graphite-carbon e ajuste o parâmetro:

CARBON_CACHE_ENABLED=true

Configurar o tempo de armazenamento

Esses parâmetros são bastante flexíveis, mas siga esse padrão para que reduzamos o tamanho do artigo. Edite o arquivo /etc/carbon/storage-schemas.conf e ajuste-o conforme abaixo:

[statusengine]
pattern = ^statusengine\.
retentions = 60:90d

O arquivo no final deverá ficar mais ou menos assim:

[statusengine]
pattern = ^statusengine\.
retentions = 60:90d

[carbon]
pattern = ^carbon\.
retentions = 60:90d

[default_1min_for_1day]
pattern = .*
retentions = 60s:1d

E se for necessário modificar alguma coisa, não se esqueça de parar o serviço, remover os whisper files e reiniciar o serviço. Os arquivos a remover estarão localizados em /var/lib/graphite/whisper.

Feitas essas configurações, já podemos iniciar o serviço:

service start carbon-cache

Mas ainda não vale um sorriso, tem uma enormidade de coisas a configurar ainda.

Configurar o Grahpite web

Não vamos utilizá-lo, mas precisa ser configurado. Comece habilitando o site:

a2dissite 000-default
cp /usr/share/graphite-web/apache2-graphite.conf /etc/apache2/sites-available

Sempre uso uma porta específica em minhas configurações. Quem me conhece pessoalmente sabe a origem (não, não é por causa do DNS do Google). Configure a porta para 8888no arquivo /etc/apache2/sites-available/apache2-graphite.conf:

<VirtualHost *:8888>

E na configuração de portas do Apache, devemos colocá-la em Listen (/etc/apache2/ports.conf):

Listen 80
Listen 8888

<IfModule ssl_module>
        Listen 443
</IfModule>

<IfModule mod_gnutls.c>
        Listen 443
</IfModule>

Habilite a configuração e reinicie o Apache:

a2ensite apache2-graphite
systemctl restart apache2

Agora já pode dar um sorrisinho, porque se não obteve nenhum erro, será possível ver o Graphite no browser:

http://172.17.0.2:8888

graphite-web.webp

Mas calma, não é esse o nosso objetivo. Sigamos.

Instalação do Grafana

Precisaremos adicionar um repositório e baixá-lo via apt. para tal:

echo "deb https://packagecloud.io/grafana/stable/debian/ xenial main" > /etc/apt/sources.list.d/grafana.list
curl https://packagecloud.io/gpg.key | apt-key add -
apt-get update
apt-get install grafana

Supondo que a configuração não esteja sendo feita em um container, mas sim em um sistema nativo (Ubuntu Xenial ou Debian Stretch), digite esses comandos:

systemctl daemon-reload
systemctl start grafana-server
systemctl enable grafana-server

Agora, voltamos ao Apache.

Configurar o Apache como proxy reverso para o Grafana

Essa configuração fará o redirecionamento automatico de HTTP para HTTPS. Edite ou crie o arquivo /etc/apache2/sites-available/apache2-grafana.conf e adicione esse conteúdo:

<VirtualHost *:80>
    ServerName statusengine.org

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{SERVER_NAME}/$1 [R,L]
</VirtualHost>

<VirtualHost *:443>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/

    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
    SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
</VirtualHost>

Já faz um tempinho que não mexia com servidores, mas como sempre digo, o mais importante não é decorar procedimentos, mas absorver conceitos. Tendo os conceitos, as coisas são relembradas ou compreendidas rapidamente. Se quiser dar olhada em algumas coisas relacionadas ao mod_rewrite, veja esse outro artigo que escrevi a respeito.

Agora devemos habilitar uma série de módulos. Se algum módulo for esquecido, cairá diretamente nos logs, não deixe de dar uma olhada em /var/log. Para habilitá-los:

a2ensite apache2-grafana
a2enmod proxy
a2enmod proxy_http
a2enmod ssl
a2enmod xml2enc
a2enmod rewrite
systemctl restart apache2

Agora já dá pra dar um sorriso mais largo. mas ainda não acabou:

https://172.17.0.2

Primeiro login no Grafana

O usuário e senha padrão são admin. Não se esqueça de mudar isso. Mas sugiro que termine as configurações antes de fazer o login.

Depois, com mais tempo e já tendo contemplado o dashboard ao final do processo, sugiro que dê uma olhada no arquivo de configuração do Grafana, que está localizado em etc/grafana/grafana.ini.

Graphite como data source do Grafana

Acima, repare no ícone com o texto "Add data source". Clique nele e replique os parâmetros descritos.

datasource.webp

Troque Statusengine por Collectd. Ao clicar em "testar e salvar", nada além desse botão ao lado deve ficar vermelho, ok?

Collectd como backend do Graphite

Tem mil maneira de utilizar o Grafana e o Graphite. Estou descrevendo uma delas nesse tutorial. O Collectd é um daemon que ficará enviando métricas para o Carbon e daí o nível vai subindo até chegar no Grafana. Não precisa se preocupar com o background da coisa, faça funcionar e depois você poderá analisar desfrutando do setup.

A instalação do Collectd traz uma sacola de dependências. Ainda bem que temos o apt:

apt-get install collectd collectd-utils

Arquivo de configuração do collectd

O arquivo de configuração do serviço fica em /etc/collectd/collectd.conf. O hostname no arquivo será seu identificador na árvore de diretórios que aparece no browser quando abrimos a URL do Graphite. Escolha o nome que quiser, mas não use caracteres especiais.

Na parte inicial do arquivo estão dispostos os plugins que podem ser ativados. As sessões de parâmetros para a configuração de cada um deles está mais adiante. Basicamente, se for habilitado o plugin df, sua respectiva sessão pode ser localizada buscando por uma estrutura com abertura e fechamento nesse formato:

<Plugin nomedoplugin>
...
</Plugin>

Abaixo, um exemplo da configuração para o df:

<Plugin df>
    Device "none"
    MountPoint "/"
    FSType "ext4"
</Plugin>

Se estiver utilizando um container, a raíz do sistema realmente aparecerá como none. Se estiver configurando no sistema nativo, basta pegar o dispositivo raíz com o comando df ou mount.

É importante atentar-se que, se alguma sessão for descomentada, o respectivo plugin no início do arquivo também deve ser descomentado. O oposto nem sempre é necessário, porque a maioria dos plugins tem parâmtros de configuração padrão que atendem em diversos casos.

Supondo um servidor Apache rodando em uma máquina da rede, um exemplo da respectiva sessão seria algo como:

<Plugin apache>
    <Instance "Graphite">
        URL "http://172.17.0.2/server-status?auto"
        Server "apache"
    </Instance>
</Plugin>

lembre-se de ajustar o IP correto em todas as partes da configuração.

Personalização de parâmetros

Adicionalmente, parâmetros podem ser incluídos para cada um dos plugins suportados. Para conhecer os parâmetros, refíra-se à página 5 do manual do collectd.conf (digite man 5 collectd.conf no terminal do servidor em que o serviço estiver instalado).

Plugin write_graphite

Esse plugin é a estrela de nossa configuração, dê a devida atenção a essa parte, pois é através dele que conseguiremos publicar as informações no Graphite.

A porta de serviço do Graphite é a 2003/tcp. No parâmetro Prefix podemos adicionar um ponto (como lá está), de modo que todo o conteúdo relacionado a essa configuração seja criado dentro de um diretório chamado collectd.

<Plugin write_graphite>
    <Node "graphing">
        Host "localhost"
        Port "2003"
        Protocol "tcp"
        LogSendErrors true
        Prefix "collectd."
        StoreRates true
        AlwaysAppendDS false
        EscapeCharacter "_"
    </Node>
</Plugin>

Configurando o Apache para para reportar status

Puxa, vida. Voltamos ao Apache. Mas quer saber porque a configuração está distribuida? Bem, vou discorrer, querendo ou não.

O caso é que cada configuração está sendo citada conforme a parte a qual está relacionada. Se tiver erro em algum ponto da configuração, através desse tutorial você conseguirá depurar o problema com mais facilidade.

Voltando à configuração, o bloco relacionado ao server status é assim:

<Location "/server-status">
            SetHandler server-status
            Require all granted
        </Location>

O arquivo deve ficar semelhante a esse conteúdo:

<VirtualHost *:8888>

        WSGIDaemonProcess _graphite processes=5 threads=5 display-name='%{GROUP}' inactivity-timeout=120 user=_graphite group=_graphite
        WSGIProcessGroup _graphite
        WSGIImportScript /usr/share/graphite-web/graphite.wsgi process-group=_graphite application-group=%{GLOBAL}
        WSGIScriptAlias / /usr/share/graphite-web/graphite.wsgi

        Alias /content/ /usr/share/graphite-web/static/
        <Location "/content/">
                SetHandler None
        </Location>

        <Location "/server-status">
            SetHandler server-status
            Require all granted
        </Location>

        ErrorLog ${APACHE_LOG_DIR}/graphite-web_error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/graphite-web_access.log combined

</VirtualHost>

Salve a configuração e recarregue o Apache.

service apache2 reload

Faça um teste inicial para ver se a configuração foi aplicada. Para tal, abra o browser no endereço correspondente ao servidor cuja configuração está sendo aplicada (utilizando abaixo o IP do container com Ubuntu):

http://172.17.0.2/server-status

Os gráficos já deverão estar sendo exibidos no painel do Graphite, mas a maneira mais rápida e clara de perceber a comunicação do collectd é avaliando a comunicação. Para tal, utilize o programa tcpdump. Como ele não está instalado por padrão, proceda com a instalação previamente a seu uso:

apt-get install tcpdump

Para analisar a comunicação pelas flags TCP, utilize a forma mais simples do sniffer:

tcpdump -i eth0 port 2003

Aqui temos que dar atenção a alguns pontos específicos. Por exemplo, a interface. No caso do container Ubuntu, a respectiva interface era realmente a eth0, mas é necessário saber qual a interface que estabelecerá a comunicação entre os recursos. Para tal, preceda com a coleta de nomes de interfaces do servidor em questão:

ifconfig

Ainda, a conexão será estabelecida apenas uma vez, tratando-se de um socket bruto com comunicação persistente, por isso ao analisar as flags após dado o início dos serviços, só será possível notar (dentro do período estabelecido como intervalo) as flags PUSH ([P.]) e o placeholder ([.]). Não se preocupe em não ver SYN e ACK se não estiver fazendo o sniffing dos pacotes desde o início do serviço. Para finalizar os pontos de atenção dessa parte da configuração, podemos ver o número de conexões estabelecidas na porta de serviço com o comando:

netstat -naut|grep ESTA|egrep --color 2003

Para analisar os dados que estão sendo tramitados entre os pontos, podemos abrir os pacotes para ver seu conteúdo:

tcpdump -i eth0 -vvv -XX -s4192 port 2003

Configurar o dashboard do Grafana

Seguindo um exemplo simples da documentação do Grafana, após selecionar o dashboard criado na tela principal pós-login, clique na opção ADD ROW. Aparecerão diversa opções, cada qual para seu propósito. Para gráficos, selecionamos a primeira opção (Graph). Criar-se-á um painel, com o título padrão "Panel Title". Clique sobre o título e vá à opção Edit. Nesse primeiro momento a aba que se abre é a Metrics. Nela, devemos selecionar o data source então os sub-ítens. Na aba General podemos renomear o painel, entre outras configurações.

Criação de parâmetros personalizados

Primeiramente, devemos compreender que o receptor dos dados é o serviço Carbon (carbon-agent). O serviço abre um socket na porta 2003 e entre o Collectd e ele, a conexão TCP é persistente. Dependendo do número de processos monitorados e o intervalo de tempo, poderiamos agendar execuções periódicas no Cron do sistema (crontab -e). Nesse caso, executar um script shell também é uma possibilidade, entre tantas outras.

Testando um tópico

Ao enviar um novo tópico, ele é criado automaticamente na estrutura de dados e pode ser alimentado a partir de então. Quando necessário podemos testar previamente o serviço para visualizar o comportamento da monitoração pretendida.

Usando netcat

Utilizando a ferramenta de gerenciamento de pacotes da distribuição Linux em questão, instale o programa netcat. Para esse exemplo, veremos a saturação do disco, portanto devemos instalar também o programa sysstat. Para enviar um tópico através do shell, basta executar o comando a seguir (baseando-se no IP de exemplo 172.17.0.2):

echo "mysql.master.disk.io.util" $(iostat -d -x `df|egrep '/$'|cut -c-8`|egrep "`df|egrep '/$'|cut -c-8`"|awk '{print $NF}'|cut -f1 -d,) `date +%s` | nc -c 172.17.0.2 2003

Como exemplificado, a expansão das váriaveis resultaria em algo como:

echo "mysql.master.disk.io.util 0 1516363691" | nc -c 172.17.0.2 2003

Repare que temos apenas 3 campos; .

Para inserir apenas um dado simples de teste, podemos usar a seguinte linha diretamente no shell:

echo "test.bash.stats 42 `date +%s`" | nc 172.17.0.2 2003

Criando um gerente de serviço

Supopndo que queiramos tirar muitos parâmetros de uma máquina; fazê-lo por shell script abrindo um número de sockets indefinido não é uma boa ideia. Como a conexão TCP com o Carbon é persistente, podemos abrir um socket Python no sistema, que ficaria responsável por repassar os dados através de uma conexão persistente estabelecida entre ele e o Carbon. A recepção desses dados pode acontecer de diversas maneiras. Por exemplo, abrindo UNIX sockets para fazer IPC. O manager então pode receber dados via socket UNIX e repassá-los via conexão TCP. Outra maneira de fazer esse repasse é mantendo esse serviço gerente recebendo dados de um FIFO (um pipe; um arquivo descritor criado a partir do mkfifo).

Informações complementares importantes

  • Outros backends podem ser configurados para comunicar-se com o Graphite, como o Sensu ou influxDBou vários outros.
  • Lembre-se de verificar se todos os serviços relacionados estão em execução. No caso de monitoramento da própria máquina de monitoramento, também o collectd. Considerando isso, os serviços que devem estar configurados e em execução são:

mysql apache2 carbon-cache grafana-server collectd

  • Ainda que devidamente configurados, analise os logs do sistema para garantir que não haja um ponto de falha (/var/log/).
  • Não se esqueça que a porta do Graphite é a 8888, para quando desejar abrí-lo no browser.
  • A porta de comuonicação do coletor é a 2003/tcp.

Próximo artigo relacionado

Pretendo mostrar em um próximo artigo a configuração de um outro backend. O Artigo ficará bem menor, já que aqui temos um setup completo de todo o resto.

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.