
Olá pessoal!
Quero compartilhar com você como é fácil escrever seu exportador para Prometheus no Golang e mostrar como isso pode ser feito usando um exemplo de um pequeno programa que monitora de onde as conexões TCP atuais são geograficamente instaladas.
0. Isenção de responsabilidade
Gostaria de delinear imediatamente, desde o início, por assim dizer, o escopo desta publicação e dizer que não diz, para que mais tarde não haja perguntas:
- Sim, isso não é uma visualização de clientes . Esta é uma visualização de conexões remotas . Ou seja, ele não divide as conexões entre aquelas nas quais o servidor remoto iniciou a conexão e as que foram iniciadas por esta máquina e mostrará tudo no mapa - por exemplo, o servidor com o repositório, onde as atualizações estão sendo baixadas para sua máquina a partir de agora.
- Sim, entendo que existem ferramentas de anonimato na rede que ocultam o IP real do cliente. O objetivo desta ferramenta não é identificar as coordenadas exatas do GPS de qualquer cliente, mas ter pelo menos uma idéia geral de sua geografia.
- whois fornece informações mais precisas do que o país do endereço IP, mas aqui eu estava conectado pelo limite do plugin do Grafan, que processa apenas países, mas não cidades.
1. Escrevemos "back-end": o exportador em movimento
Portanto, a primeira coisa que precisamos fazer é escrever um exportador que realmente coletará dados do nosso servidor e os enviará para o Prometheus. A escolha dos idiomas é ótima: o Prometheus possui bibliotecas clientes para escrever exportadores em muitos idiomas populares, mas eu escolhi Go, primeiro, porque é "mais nativo" (já que o Prometheus está escrito nele) e, segundo, porque ele próprio Eu uso na minha prática DevOps.
Bem, letras suficientes, vamos ao código. Vamos começar a escrever de baixo para cima: primeiro, as funções para determinar o país por IP e a lista de endereços IP remotos e depois enviar tudo para o Prometheus.
1.1 Determinamos o país pelo endereço IP
Bem, há absolutamente tudo na testa, eu não filosofei e apenas usei o serviço freegeoip.net , cuja API até o momento em que este artigo foi publicado estava obsoleta, e agora eles oferecem um registro gratuito e são capazes de fazer 10.000 solicitações por mês (o que é suficiente para nossos propósitos) ) Tudo é simples aqui: existe um terminal do formulário http://api.ipstack.com/<IP>?access_key=<API_KEY>
, que simplesmente nos retorna json com o campo country_code
que precisamos - é tudo o que precisamos para visualização.
Então, vamos escrever um pacote para atrair o país por IP.
Importamos as bibliotecas necessárias e criamos uma estrutura na qual o objeto json resultante será 'descompactado'. ... e a própria função, que retornará o código do país para nós. Preste atenção ao parâmetro legacy=1
, eu tenho que usá-lo para compatibilidade com versões anteriores; Obviamente, se você usar a API deles, use a versão mais recente.
Aqui, usaremos o pacote github.com/shirou/gopsutil/net
e filtraremos as conexões com o status ESTABLISHED
, excluindo endereços IP locais e endereços de uma lista negra personalizada que pode ser passada ao exportador na inicialização (por exemplo, para excluir todos os seus próprios endereços IP públicos)
Pacote com função retornando map [string] int: número de conexões do país. 1.3 E, finalmente, envie tudo para Prometeu
Mais precisamente, ele próprio vai levar tudo. Apenas ouviremos a porta e forneceremos as métricas coletadas.
Usando github.com/prometheus/client_golang/prometheus
crie uma métrica do tipo Gauge
. Na verdade, você pode criar um Counter
, então usaríamos a rate
ao consultar o banco de dados. Talvez o último seja mais eficaz do ponto de vista de Prometheus, mas enquanto escrevia este exportador (há seis meses), estava apenas começando a me familiarizar com Prometheus e Gauge
era suficiente para mim:
location = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "job_location", Help: "Location connections number", }, []string{"location"}, )
Depois de coletar as métricas usando os parágrafos anteriores, atualizamos nosso vetor:
for code, number := range c.ConnectionsByCode { location.With(prometheus.Labels{"location": code}).Set(float64(number)) }
Começamos tudo isso com um loop infinito em uma goroutine separada e apenas ligamos a porta na principal e esperamos que Prometheus tome nossas métricas:
prometheus.MustRegister(location) http.Handle("/metrics", prometheus.Handler()) log.Fatal(http.ListenAndServe(*addr, nil))
Na verdade, todo o código pode ser visualizado no repositório no GitHub , não quero copiar tudo aqui em uma linha.
2. "Front-end": Grafana
Mas primeiro, é claro, você precisa dizer ao Prometheus para coletar nossas métricas:
- job_name: 'GeoIPExporter' scrape_interval: 10s static_configs: - targets: ['127.0.0.1:9300']
(ou usando a descoberta de serviço, se você tiver, por exemplo, Kubernetes). Prometheus pode ser feito para reler a configuração enviando a ele um sinal HUP
:
$ pgrep "^prometheus$" | xargs -i kill -HUP {}
Vamos a isso na interface do usuário e verificamos se as métricas são coletadas:

Ok, agora é a vez de Grafan. Usamos o grafana-worldmap-panel
, que deve ser pré-instalado:
$ grafana-cli plugins install grafana-worldmap-panel
Em seguida, vá para ela na interface do usuário e clique em adicionar painel -> Painel Mapa do Mundo. Na guia Métricas, insira a seguinte consulta:
sum(job_location) by (location)
E especifique o formato da legenda: {{location}}
. Tudo deve ficar assim:

Em seguida, vá para a guia Mapa do Mundo e configure tudo como na captura de tela:

E isso é tudo! Aproveite o nosso mapa.
De uma maneira tão simples, você pode fazer um belo mapa de conexões no Grafan.
Agradecemos sua atenção e aguardamos seus comentários.
Todo
Obviamente, para usar a ferramenta para a finalidade a que se destina, você precisa concluí-la: filtrar os endereços das sub-redes locais e muito mais. A propósito, se alguém estiver interessado e quiser desenvolver esse exportador - bem-vindo ao repositório no GitHub!
Ligações