API usando Kibanana como LOGGING
Aprenda a integrar o Kibana em sua API Dockerizada para visualizar logs de maneira eficiente, permitindo que você monitore e analise o desempenho da sua aplicação com facilidade!
Logging de API com Kibana: Um Projeto Simples e Prático
E aí, galera! Hoje vou compartilhar com vocês meu projeto de logging de API que usei em uma aplicação Dockerizada. O foco aqui é integrar tudo com o Kibana para ter uma visão clara do que tá rolando na minha API. Vamos nessa!
Sobre como criar a API, o Docker e o PostgreSQL nos próximos posts. Esse é só um guia de como usar o Kibana para o logging da sua API.
Por Que Usar Kibana?
Kibana é massa, Kibana é 10!
Kibana é uma ferramenta incrível que permite visualizar dados armazenados no Elasticsearch. E PASMEM: É DE GRAÇA! Com ela, você pode criar gráficos, tabelas e dashboards interativos. E o melhor: se você tem dificuldade com interfaces, vai achar “facin, facin”.
Como Funciona?
Estrutura do Projeto: O projeto é dividido em alguns serviços no Docker, incluindo a API, o banco de dados PostgreSQL, Elasticsearch e Kibana. Vamos ver como integrar tudo na nossa API (mais conhecido como SHOW ME THE CODE).
Primeiro, criamos o cliente Elasticsearch na main.go
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// main.go
package main
import (
"fmt"
"log"
"os"
"github.com/elastic/go-elasticsearch/v7"
)
var es *elasticsearch.Client
func main() {
// Inicializar o cliente Elasticsearch
es, err := elasticsearch.NewClient(elasticsearch.Config{
Addresses: []string{
os.Getenv("ELASTICSEARCH_HOST"),
},
Username: os.Getenv("ELASTICSEARCH_USER"),
Password: os.Getenv("ELASTICSEARCH_PASSWORD"),
})
if err != nil {
log.Fatalf("Erro ao criar cliente Elasticsearch: %v", err)
}
log.Println("Cliente Elasticsearch criado com sucesso")
// Aqui você pode adicionar qualquer funcionalidade adicional que precise
// para a interação com o Elasticsearch, se necessário.
}
Depois, capturamos os Logs: Cada vez que uma ação é realizada na API, como a criação de um usuário, um log é gerado e enviado para o Elasticsearch. A função createUserHandler
registra o log no Elasticsearch quando um usuário é criado.
1
2
3
4
5
6
7
8
9
10
11
// main.go
func createUserHandler(w http.ResponseWriter, r *http.Request) {
// Aqui se cria o usuário, valida os dados e insere no banco de dados.
// Registrar o log no Elasticsearch
logToElasticsearch(fmt.Sprintf("Usuário %s criado com sucesso", user.Username))
w.WriteHeader(http.StatusCreated)
w.Write([]byte("Usuário criado com sucesso"))
}
Agora fazemos o código ler e mostrar em JSON: A função logToElasticsearch
registra uma mensagem no Elasticsearch, transformando-a em JSON e enviando para um índice específico (logs). Ela também lida com possíveis erros, garantindo que tudo seja registrado direitinho.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// main.go
func logToElasticsearch(message string) {
// Cria um documento com a mensagem e a hora atual
doc := map[string]interface{}{
"message": message,
}
// Converte o documento para JSON
docJSON, err := json.Marshal(doc)
if err != nil {
log.Printf("Erro ao marshaller o documento: %v", err)
}
// Envia o documento JSON para o Elasticsearch
req := bytes.NewReader(docJSON)
res, err := es.Index("logs", req)
if err != nil {
log.Printf("Erro ao enviar log para Elasticsearch: %v", err)
}
defer res.Body.Close() // Garante que o corpo da resposta seja fechado
// Verifica se a resposta do Elasticsearch é um erro
if res.IsError() {
log.Printf("Erro ao indexar log: %s", res.String())
}
}
Assim finalizamos o código da main, a estrutura que vai comandar todo esse processo. Agora vamos para o arquivo do Docker!
Configuração do Docker Compose
Para configurar tudo isso, eu usei um docker-compose.yml
para gerenciar os serviços. Aqui está uma visão geral do que inclui:
Serviço de API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
version: '3.8'
services:
api:
build: .
ports:
- "8080:8080"
environment:
- POSTGRES_HOST=exemplo
- POSTGRES_USER=exemplo
- POSTGRES_PASSWORD=exemplo
- POSTGRES_DB=exemplo
- ELASTICSEARCH_HOST=http://elasticsearch:9200 # Variável para Elasticsearch
- ELASTICSEARCH_USER=elastic # Usuário padrão do Elasticsearch
- ELASTICSEARCH_PASSWORD=pass # Senha do Elasticsearch
depends_on:
- db
- elasticsearch
Serviço do Banco de Dados
1
2
3
4
5
6
7
8
db:
image: postgres:latest
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: bwapi
volumes:
- postgres_data:/var/lib/postgresql/data
Configurações do Elasticsearch e Kibana
Usuários e senhas hardcoded. Meramente ilustrativas. NÃO FAÇAM ISSO EM CASA!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.5.0
environment:
- discovery.type=single-node
- ELASTIC_PASSWORD=pass # Senha do usuário 'elastic'
- xpack.security.http.ssl.enabled=false # Desabilita HTTPS
ports:
- "9200:9200"
- "9300:9300"
volumes:
- es_data:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:8.5.0
environment:
ELASTICSEARCH_HOSTS: "http://elasticsearch:9200"
ELASTICSEARCH_USERNAME: "kibana_user" # Use 'elastic' como usuário padrão
ELASTICSEARCH_PASSWORD: "kibana_pass" # A mesma senha do Elasticsearch
ports:
- "5601:5601" # Porta padrão do Kibana
depends_on:
- elasticsearch
volumes:
postgres_data:
es_data:
Pra dar um PLUS++, criei um Makefile pra que ele pudesse fazer a construção do binário do Golang, subir todos os containers do Docker e deixar os links prontos.
1
2
3
4
5
6
up: build
@echo "Iniciando o ambiente com docker-compose"
docker-compose up --build -d
@sleep 2 # Esperar um pouco para o container iniciar
@echo "A API está rodando em: http://localhost:8080"
@echo "O Kibana está rodando em: http://localhost:5601/"
O código completo tá disponível aqui se você tiver mais curiosidade.
Interface do Elasticsearch
Como vimos, a URL http://localhost:5601/ deve estar pronta para login. Use as credenciais que você adicionou no Docker.
Agora ‘seja’ SIMPLES: use a barra de pesquisa do Elastic e digite data views
, e logo vai aparecer a informação pra você.
Crie uma nova data view com base na sua API.
Pode dar o nome que preferir. Estou usando log*
como padrão, porque não estou usando mais nenhum log, exceto os da única API.
Vamos de novo para a barra de pesquisa e escreva Discover
. Isso vai te levar direto para a página que você quer.
AMIGX: Pra que haja logs, é preciso movimentação. Então preparei um comando simples com a ferramenta
curl
pra facilitar a criação de usuários:
1
2
3
curl -X POST http://localhost:8080/create-user \
-H "Content-Type: application/json" \
-d '{"username": "novo_usuario", "password": "senha_secreta"}'
Caso não queira usar a linha de comando, pode usar ferramentas como Postman, Insomnia, etc. Faz um POST
nesse link: http://localhost:8080/create-user e adicione o corpo JSON:
1
2
3
4
{
"username": "novo_usuario",
"password": "senha_secreta"
}
Daí deve aparecer exatamente assim no seu Elastic:
Dificuldades
Permissões do Usuário Kibana
Por várias vezes, o Kibana não estava pronto quando eu subia todos os containers. Isso foi por falta de permissões corretas. Se acontecer com você, aqui vão algumas dicas que podem ajudar, bem aqui na documentação.
Conclusão
Esse projeto é uma maneira prática de aprender sobre logging e visualização de dados. Se você está começando ou só quer aprimorar suas habilidades, eu recomendo fortemente dar uma olhada. O repositório tá disponível aqui e vou ficar feliz em ouvir o que vocês acham!
Espero que goste das melhorias! Se precisar de mais alguma coisa, é só avisar.