MyTwitterApi é um case de exemplo de uma aplicação onde são implementados os três pilares da Observabilidade: Logs, Métricas e Eventos.
- Ambientes
- Pré-Requisitos
- Deploy dos Ambientes
- Acessando os serviços
- Publicando dados na API
- Consumindo dados na API
- Logs e Métricas
- Autor
Todos os ambientes são executados em containers no Docker.
Os arquivos do projeto estão estruturados da seguinte forma:
mytwitterapi
├── infralogs # Arquivos de configuração do ambiente de logs
├── inframetrics # Arquivos de configuração do ambiente de métricas
├── exports # Arquivo de coleção do Postman e Dashboard do kibana para importação
├── twitterctl # Client de linha de comando twitterctl.py
├── twrestapi # Código fonte da api
├── docker-compose.yml # Arquivo do Compose para deploy dos containers
├── LICENSE
└── README.md
Api Rest para publicação e consulta de posts do Twitter:
- Publicação de posts do twitter
- Listagem de usuários com mais seguidores
- Contagem de posts publicados por hora do dia
- Contagem de posts publicados de um usuário de acordo com uma determinada tag agrupados por localização ou linguagem
Tecnologias:
- Flask: Framework para desenvolvimento web.
- mongoengine: Object-Document Mapper para MongoDB.
Client de linha de comando para busca de posts no Twitter e publicação na twrestapi:
- Busca de posts no twitter a partir de um conjunto de tags especificos
- Publicação de posts do twitter na twresapi
Tecnologias:
- Fire: biblioteca para gerar CLI's a partir de qualquer objeto Python.
A aplicação utiliza o banco de dados NoSQL MongoDB.
Ambiente de logs executando:
- Elasticsearch para armazenamento e indexação dos logs da aplicação.
- Kibana para visualização e analise dos logs.
- Vector para envio dos logs da aplicação para o Elasticsearch.
- Prometheus para coleta e armazenamento de métricas.
- Grafana para visualização e analise de métricas.
Você pode executar esses ambientes em qualquer sistema operacional com suporte a docker mas não posso garantir que tudo vai funcionar como esperado portando recomendo testar seguindo os requisitos abaixo:
- Sistema Operacional: Ubuntu 18 LTS
- Memória RAM: >= 6GB
Antes de começar a executar o ambiente, você vai precisar ter instalado em sua máquina as seguintes ferramentas:
# Clone este repositório
$ git clone https://github.com/ezequielsbarros/mytwitterapi.git
# Acesse a pasta do projeto no terminal/cmd
$ cd mytwitterapi
# Faça o deploy dos containers com o Compose
# A opção "--build" serve para criar o container da api rest.
# O uso dessa opção só é nescessária na primeira execução
# Ou caso o código da aplicação twrestapi seja modificado
$ docker-compose up --build
# Opcional: use a opção "-d" para executar os containers em backgroud
$ docker-compose up --build -d
Para validar se todos os containers estão up execute o seguinte comando:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0b4abb8b7747 prom/prometheus "/bin/prometheus --c…" 42 minutes ago Up 42 minutes 0.0.0.0:9090->9090/tcp mytwitterapi_prometheus_1
991fd6f5fb9d twrestapi:python3-alpine "sh entrypoint.sh" 42 minutes ago Up 42 minutes 0.0.0.0:80->8080/tcp mytwitterapi_twitterapi_1
3f347620045e docker.elastic.co/kibana/kibana:6.8.13 "/usr/local/bin/kiba…" 42 minutes ago Up 42 minutes 0.0.0.0:5601->5601/tcp mytwitterapi_kibana_1
8af6ae1d3e2f timberio/vector:latest-alpine "/usr/local/bin/vect…" 42 minutes ago Up 42 minutes 0.0.0.0:9014->9014/tcp, 0.0.0.0:9514->9514/tcp mytwitterapi_vector_1
69722b86cfff mongo "docker-entrypoint.s…" 42 minutes ago Up 42 minutes 0.0.0.0:27017->27017/tcp mytwitterapi_mongodb_1
1798f0f53988 docker.elastic.co/elasticsearch/elasticsearch:6.8.13 "/usr/local/bin/dock…" 42 minutes ago Up 42 minutes 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp mytwitterapi_elasticsearch_1
d3156c34e125 grafana/grafana "/run.sh" 42 minutes ago Up 42 minutes 0.0.0.0:3000->3000/tcp mytwitterapi_grafana_1
Os serviços podem ser acessados pelas seguintes urls após o deploy:
- twitterapi: http://localhost
- MongoDB: http://localhost:27017
- Elasticsearch: http://localhost:9200
- Prometheus: http://localhost:9090
- Kibana: http://localhost:5601
- Grafana: http://localhost:3000
Inicialmente a API não vem com dados populados.
Você pode publicar dados na API utilizando o CLI twitterctl.py
Para utilizar o CLI você precisa de um token de acesso para a API do Twitter:
Considetando que vc está dentro do diretório do projeto, execute o seguinte comandos para poder utilizar o CLI:
# Instalar o pip3
$ sudo apt-get install python3-pip
# Instalar os requerimentos
$ pip3 install -r ./twitterctl/requirements.txt
$ chmod +x ./twitterctl/twitterctl.py
Execute o comando abaixo para realizar uma busca de tweets recentes por tags e publicar na twrestapi.
Os parâmetros devem ser informados entre aspas:
- Substituir por um token Bearer válido na API do Twitter
- Substituir <LISTA DE HASHTAGS SEPARADAS POR VÍRGULA> pela sua lista de tags. Você pode incluír quantas tags quiser.
$ ./twitterctl/twitterctl.py search "<BEARER TOKEN>" "<LISTA DE HASHTAGS SEPARADAS POR VÍRGULA>"
Exemplo de busca de tweets por hashtag:
$ ./twitterctl/twitterctl.py search "AAAAAAAAAAAAAAAAAAAAAM%faketokenfaketokenfaketokenfaketokenfaketokenfaketokenfaketokenfaketokenfaketokenfaketokenA" "#openbanking, #remediation, #devops, #sre, #microservices, #observability, #oauth, #metrics, #logmonitoring, #opentracing"
# Listando os endpoints na api disponíveis
$ curl http://localhost
{
"endpoints": [
{
"method": "POST",
"url": "/twitter/api/v1/publish/posts"
},
{
"method": "GET",
"url": "/twitter/api/v1/users/followers"
},
{
"method": "GET",
"url": "/twitter/api/v1/posts/hour"
},
{
"method": "GET",
"url": "/twitter/api/v1/posts/tags/location"
},
{
"method": "GET",
"url": "/twitter/api/v1/posts/tags/lang"
}
],
"info": "Twitter API",
"version": "1.0.0"
}
# Publicando um post via API
$ curl http://localhost/twitter/api/v1/publish/posts
$ curl -H "Content-Type: application/json" http://localhost//twitter/api/v1/publish/posts -d '[ {"id":"2142345235234","text": "Learn how to instrument and troubleshoot your Go application with #Jaeger and #OpenTracing. Read our guide to get started! https://t.co/kCAlZon3tR https://t.co/2zSGpas0R6", "created_at": "2020-12-15T13:49:02.000Z", "post_hour": 13, "hashtag": " #opentracing", "lang": "en", "author_id": "2904502273", "username": "logzio", "name": "Logz.io", "location": "Israel", "followers_count": 1630} ]'
...
# Listando os usuários com mais seguidores #ETEMOSUMBUG :)
$ curl http://localhost/twitter/api/v1/users/followers
[
"username: eleconomista, followers: 656407",
"username: KirkDBorne, followers: 272189",
"username: KirkDBorne, followers: 272189",
"username: MikeSchiemer, followers: 218609",
"username: RedHat, followers: 211433"
]
# Listando os a contagem de posts publicados pela hora do dia
$ curl http://localhost//twitter/api/v1/posts/hour
[
{
"_id": 0,
"total_post": 17
},
{
"_id": 1,
"total_post": 5
},
{
"_id": 2,
"total_post": 7
},
...
# Listando a contagem de posts de cada tag agrupados por usuário e localização
$ curl http://localhost/twitter/api/v1/posts/tags/location
[
{
"count": 1,
"country": "undefined",
"hashtag": " #microservices",
"username": "einfochipsltd"
},
{
"count": 1,
"country": "St Louis",
"hashtag": " #observability",
"username": "JustinRyburn"
}
...
# Listando a contagem de posts de cada tag agrupados por usuário e linguagem
curl http://localhost/twitter/api/v1/posts/tags/lang
[
{
"count": 1,
"hashtag": " #microservices",
"lang": "en",
"username": "einfochipsltd"
},
{
"count": 1,
"hashtag": " #observability",
"lang": "en",
"username": "JustinRyburn"
}
...
Acesse: http://localhost:5601/
Ao acessar o Kibana pela primeira vez é preciso configurar o index pattern.
Crie o index pattern com o prefixo "twitterapi-*":
Selecione o campo "timestamp" e clique em "Create index pattern":
Para visualizar os logs no Kibana foi disponibilizado um dashboard para ser importado:
Para realizar o import:
- Na aba esquerda clique na opção "Management" --> "Saved Objects" --> "Import"
A aplicação implementa nos registros de log um identifiador único a fim de identificar e rastrear todo o processo de execução de uma requisição na aplicação.
O uuid também é retornado como o header "x-request-id" em todas as requisições:
$ curl localhost/twitter/api/v1/users/followers -I
HTTP/1.1 200 OK
Server: gunicorn/20.0.4
Date: Fri, 18 Dec 2020 22:29:56 GMT
Connection: keep-alive
Content-Type: application/json
Content-Length: 232
x-request-id: c7d03ac6-6253-4816-baaa-56525498e394
Buscando pelo id retornado no header é possível rastrear os logs referentes aquela requisição:
O dashboard de métricas já é importado automaticamente ao inicializar o container do grafana. Basta acessar o serviço http://localhost:3000/
Usuário: admin Senha: admin
Observação: será solicitado a troca da senha no primeiro acesso.
O dashboard "Twitter API" tem quatro painéis:
- Total de requisições por minuto
- Erros por minuto
- Requisições por minuto
- Média do tempo de resposta por minuto
Ezequiel de Souza Barros