09 ‐ Observabilidade - BktechBrazil/elastic-eck GitHub Wiki

9.1 - O que é Observabilidade?

Observabilidade é a capacidade de entender o estado interno de um sistema a partir dos dados que ele produz. No contexto de TI, isso significa conseguir responder perguntas como: "por que a aplicação está lenta?", "qual componente causou o erro?", "o que mudou antes da falha?".

O Elastic Stack organiza a observabilidade em torno de três tipos de dados, que a comunidade chama de os três pilares da observabilidade:

Pilar O que é Exemplos
Logs Registros textuais de eventos gerados por sistemas e aplicações Erros de aplicação, eventos de sistema, logs de acesso web
Métricas Valores numéricos que representam o estado de um sistema ao longo do tempo CPU, memória, latência de requisições, número de erros por minuto
Traces Rastreamento do caminho percorrido por uma requisição dentro de um sistema distribuído Uma chamada HTTP que passa por API Gateway → serviço A → banco de dados → serviço B

A correlação entre os três pilares é o que diferencia observabilidade de simples monitoramento. No Elastic Stack, é possível partir de um spike de erros nos logs, identificar a transação específica no APM e correlacionar com um pico de CPU nas métricas — tudo na mesma interface.

Observabilidade no ECK

No Kubernetes, cada pilar chega ao Elasticsearch por um recurso gerenciado pelo operator ECK:

Pilar Coletor Recurso do ECK
Logs dos containers e dos nodes Filebeat ou Elastic Agent, como DaemonSet Beat ou Agent
Métricas dos nodes, pods e serviços Metricbeat ou Elastic Agent, como DaemonSet Beat ou Agent
Traces e métricas das aplicações APM Server, que recebe os dados dos agentes APM ApmServer

Como nos demais recursos, o elasticsearchRef configura a conexão com o cluster e o kibanaRef a conexão com o Kibana: endereço, credenciais e certificados são criados pelo operator.


9.2 - Componentes de Observabilidade no Kibana

9.2.1 - Logs

Os logs são explorados no Discover, que no Kibana 9.x reconhece dados de log e oferece uma experiência própria para eles: navegação temporal, filtragem por campos comuns (host, serviço, nível de log) e correlação com outros dados de observabilidade.

Funcionalidades principais:

  • Filtros rápidos por host.name, service.name, log.level e outros campos ECS (Elastic Common Schema)
  • Destacar palavras-chave específicas para facilitar a leitura
  • Navegar para o contexto de um log — ver os eventos antes e depois de um evento de interesse
  • Integração direta com APM: a partir de uma linha de log, é possível navegar para a transação correspondente

Na versão 9.0, os antigos Logs Stream e Logs Explorer foram removidos. A exploração de logs passou a ser feita no Discover, e as visões salvas de logs são Discover sessions.

Caminho: Menu → Discover

9.2.2 - Infrastructure

O módulo de Infrastructure oferece uma visão unificada da saúde da infraestrutura — hosts, containers, pods Kubernetes e serviços — em um único lugar.

Funcionalidades principais:

  • Inventory view: lista todos os hosts e containers monitorados com seus indicadores de saúde (CPU, memória, tráfego de rede). Permite ordenar pelo recurso mais consumido e identificar gargalos rapidamente.
  • Hosts: tabela com os hosts monitorados e suas métricas principais, com acesso a um painel completo de cada host — séries temporais de CPU, memória, disco e rede, além dos logs e processos do host.
  • Metrics Explorer: cria gráficos ad-hoc de qualquer métrica disponível. Foi descontinuado (deprecated) na 9.4, em favor da exploração de métricas no Discover.
  • Alertas de infraestrutura: configura alertas quando uma métrica ultrapassa um threshold — como CPU acima de 90% por mais de 5 minutos.

Caminho: Menu → Observability → Infrastructure

9.2.3 - APM (Application Performance Monitoring)

O APM é o componente de observabilidade focado em aplicações. Ele coleta dados sobre o desempenho interno das aplicações — tempo de resposta, erros, dependências externas — e os exibe no Kibana de forma que seja fácil identificar onde está o gargalo.

O que o APM coleta:

  • Transactions: cada requisição HTTP, job em background ou operação que o agente rastreia. Exibe o tempo total, o breakdown por componente (banco de dados, chamadas externas, renderização de templates) e a taxa de erros.
  • Traces: o caminho completo de uma requisição em um sistema distribuído. Se a requisição passa por múltiplos serviços, o APM consolida o trace de todos eles em uma única visualização chamada de waterfall.
  • Errors: exceções capturadas pela aplicação com stack trace completo, agrupadas por tipo e frequência.
  • Metrics: métricas de runtime da aplicação — uso de heap da JVM, garbage collection, threads ativas.

Arquitetura do APM:

Aplicação + Agente APM
        ↓
    APM Server (porta 8200)
        ↓
   Elasticsearch
        ↓
     Kibana (APM UI)

O agente APM é uma biblioteca instalada dentro da aplicação. Ele coleta os dados automaticamente (sem necessidade de instrumentação manual na maioria dos casos) e os envia para o APM Server, que os processa e indexa no Elasticsearch.

Linguagens suportadas: Python, Java, Node.js, Go, Ruby, .NET, PHP, iOS, Android, JavaScript (RUM), e mais.

APM Server no ECK: o APM Server é o recurso ApmServer. O operator cria:

  • o Service <nome>-apm-http, na porta 8200;
  • um certificado TLS, assinado por uma CA própria, para a comunicação entre os agentes e o servidor;
  • um secret token no Secret <nome>-apm-token, que os agentes enviam para se autenticar.

A partir da 8.0, o APM Server também exige que o Kibana instale o pacote de integração apm (xpack.fleet.packages no spec.config do Kibana).

Caminho: Menu → Observability → Applications

9.2.4 - Synthetics

O Synthetics monitora a disponibilidade e o desempenho de serviços e aplicações web de forma proativa — ou seja, sem esperar que um usuário real experiencie o problema. Ele substitui o antigo app Uptime, descontinuado desde a 8.15.

Dois tipos de monitoramento:

  • Lightweight monitors (ping): verificações simples de disponibilidade via HTTP, TCP ou ICMP. Configura-se uma URL e um intervalo, e o Kibana verifica periodicamente se o serviço está respondendo e com qual tempo de resposta.
  • Browser monitors: scripts que simulam a navegação de um usuário real em um site — preenchendo formulários, clicando em botões, navegando entre páginas. Usa o Playwright por baixo. Captura screenshots e vídeos quando uma etapa falha.

Os monitores rodam nas localidades gerenciadas pela Elastic ou em Private Locations, que são Elastic Agents rodando na sua própria infraestrutura e gerenciados pelo Fleet.

Caminho: Menu → Observability → Synthetics

9.2.5 - User Experience (RUM)

O Real User Monitoring (RUM) captura dados de performance diretamente do navegador dos usuários reais que acessam sua aplicação web. Diferentemente do Synthetics — que simula usuários —, o RUM registra o que usuários reais estão experienciando.

Métricas coletadas:

  • Page load time: tempo total de carregamento da página
  • First Contentful Paint (FCP): quando o primeiro conteúdo visível aparece na tela
  • Largest Contentful Paint (LCP): quando o maior elemento visível termina de renderizar — um dos Core Web Vitals do Google
  • Transaction time: tempo de execução de ações do usuário na página (cliques, navegação SPA)
  • JS errors: exceções JavaScript capturadas no frontend, com stack trace

Caminho: Menu → Observability → User Experience

9.2.6 - Alertas

O sistema de alertas de observabilidade do Kibana permite configurar regras que monitoram métricas, logs e dados de APM, disparando notificações quando condições específicas são atendidas.

Tipos de regras disponíveis em Observability:

  • Metric threshold: alerta quando uma métrica (CPU, memória, tráfego) ultrapassa um limite por um período de tempo
  • Log threshold: alerta quando o volume de logs que correspondem a um padrão ultrapassa ou fica abaixo de um limite
  • APM anomaly: alerta quando o machine learning detecta comportamento anômalo em transações APM
  • Synthetics: alerta quando um monitor de disponibilidade detecta falha

Canais de notificação: e-mail, Slack, Teams, PagerDuty, webhook HTTP, criação de caso no Elastic Security.

Caminho: Menu → Observability → Alerts → Manage Rules

9.2.7 - Cases

O módulo de Cases permite registrar e acompanhar incidentes e investigações diretamente no Kibana, sem precisar sair para uma ferramenta externa de ticketing.

Funcionalidades:

  • Criar um caso com título, descrição, severidade e tags
  • Adicionar comentários e evidências ao longo da investigação (logs, screenshots, links para dashboards)
  • Associar alertas disparados a um caso específico — criando um histórico da investigação
  • Integração com ferramentas externas: Jira, ServiceNow, Swimlane

Caminho: Menu → Observability → Cases


9.3 - Preparação dos laboratórios

Os laboratórios usam o cluster lab-es com um node e o Kibana lab-kb. Os comandos de terminal são executados na VM, no diretório ~/eck-lab, onde fica a pasta manifests.

Recursos: rode um laboratório por vez. Cada um termina removendo o que criou.

Passo 1 — Conferir o cluster

cd ~/eck-lab
kubectl -n elastic get elasticsearch,kibana
kubectl -n elastic get beat,agent,logstash,apmserver

Resultado esperado: lab-es e lab-kb com HEALTH green, e No resources found in elastic namespace. para os coletores e o APM Server.

Passo 2 — Acessar o Kibana

PASSWORD=$(kubectl -n elastic get secret lab-es-es-elastic-user \
  -o go-template='{{.data.elastic | base64decode}}')
echo "Senha do elastic: $PASSWORD"

pkill -f "port-forward.*5601" || true
nohup kubectl -n elastic port-forward --address 0.0.0.0 service/lab-kb-kb-http 5601 > /tmp/pf-kibana.log 2>&1 &
sleep 2
cat /tmp/pf-kibana.log

Resultado esperado: a senha do usuário elastic e a mensagem Forwarding from 0.0.0.0:5601 -> 5601.

O túnel fica ligado ao pod do Kibana que estava rodando quando ele foi aberto. Se esse pod for reiniciado ou recriado, o túnel cai e o Kibana deixa de responder no navegador: execute este bloco novamente.

No navegador, abra https://<IP_DA_VM>:5601 e faça login com o usuário elastic.


9.4 - Laboratório 1: logs e métricas do cluster Kubernetes

Neste laboratório, um Filebeat coleta os logs de todos os containers do cluster e um Elastic Agent coleta as métricas do node. Com os dois rodando, os dados aparecem nas telas de observabilidade do Kibana: logs no Discover e métricas em Infrastructure.

Passo 1 — Criar o manifesto do Filebeat

mkdir -p manifests
cat <<'EOF' > manifests/filebeat.yaml
# Filebeat via CRD Beat do ECK — coleta logs de containers em todos os nós (DaemonSet)
# Namespace: elastic. RBAC incluído para o add_kubernetes_metadata enriquecer os eventos.
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: filebeat
  namespace: elastic
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: filebeat
rules:
  - apiGroups: [""]
    resources: ["namespaces", "pods", "nodes"]
    verbs: ["get", "watch", "list"]
  - apiGroups: ["apps"]
    resources: ["replicasets"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: filebeat
subjects:
  - kind: ServiceAccount
    name: filebeat
    namespace: elastic
roleRef:
  kind: ClusterRole
  name: filebeat
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: beat.k8s.elastic.co/v1beta1
kind: Beat
metadata:
  name: filebeat
  namespace: elastic
spec:
  type: filebeat
  version: 9.4.2
  elasticsearchRef:
    name: lab-es            # operator injeta host, usuário, senha e CA automaticamente
  kibanaRef:
    name: lab-kb            # habilita o setup de dashboards do Filebeat
  config:
    filebeat.inputs:
      - type: filestream
        id: container-logs
        paths:
          - /var/log/containers/*.log
        parsers:
          - container: {}
        prospector:
          scanner:
            fingerprint.enabled: true
            symlinks: true
        file_identity.fingerprint: {}
    processors:
      - add_kubernetes_metadata:
          host: ${NODE_NAME}
          matchers:
            - logs_path:
                logs_path: "/var/log/containers/"
  daemonSet:
    podTemplate:
      spec:
        serviceAccountName: filebeat
        automountServiceAccountToken: true
        terminationGracePeriodSeconds: 30
        hostNetwork: true
        dnsPolicy: ClusterFirstWithHostNet
        securityContext:
          runAsUser: 0
        containers:
          - name: filebeat
            resources:
              requests:
                memory: 200Mi
                cpu: 100m
              limits:
                memory: 300Mi
            env:
              - name: NODE_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: spec.nodeName
            volumeMounts:
              - name: varlogcontainers
                mountPath: /var/log/containers
              - name: varlogpods
                mountPath: /var/log/pods
              - name: varlibdockercontainers
                mountPath: /var/lib/docker/containers
        volumes:
          - name: varlogcontainers
            hostPath:
              path: /var/log/containers
          - name: varlogpods
            hostPath:
              path: /var/log/pods
          - name: varlibdockercontainers
            hostPath:
              path: /var/lib/docker/containers
EOF

O Filebeat roda como DaemonSet, lê os logs de todos os containers do node com o input filestream e acrescenta a cada evento os metadados do Kubernetes (pod, namespace, labels) com o processor add_kubernetes_metadata.

Passo 2 — Criar o manifesto do Elastic Agent

cat <<'EOF' > manifests/elastic-agent-standalone.yaml
# Elastic Agent STANDALONE via CRD Agent do ECK — coleta métricas do sistema (DaemonSet).
# A configuração de coleta vive em spec.config (sem Fleet/UI). O operator cria a saída
# "default" automaticamente a partir do elasticsearchRefs.
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: elastic-agent
  namespace: elastic
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: elastic-agent
rules:
  - apiGroups: [""]
    resources: ["nodes", "namespaces", "pods", "events", "services"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["replicasets", "deployments", "daemonsets", "statefulsets"]
    verbs: ["get", "list", "watch"]
  - nonResourceURLs: ["/metrics"]
    verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: elastic-agent
subjects:
  - kind: ServiceAccount
    name: elastic-agent
    namespace: elastic
roleRef:
  kind: ClusterRole
  name: elastic-agent
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: agent.k8s.elastic.co/v1alpha1
kind: Agent
metadata:
  name: elastic-agent
  namespace: elastic
spec:
  version: 9.4.2
  elasticsearchRefs:
    - name: lab-es          # cria a saída "default" com host/credenciais/CA automaticamente
  daemonSet:
    podTemplate:
      spec:
        serviceAccountName: elastic-agent
        automountServiceAccountToken: true
        hostNetwork: true
        dnsPolicy: ClusterFirstWithHostNet
        securityContext:
          runAsUser: 0
        containers:
          - name: agent
            resources:
              requests:
                memory: 350Mi
                cpu: 100m
              limits:
                memory: 500Mi
  config:
    id: lab-agent
    agent:
      monitoring:
        enabled: true
        use_output: default
        logs: true
        metrics: true
    inputs:
      - id: system-metrics
        type: system/metrics
        use_output: default
        data_stream:
          namespace: default
        streams:
          - id: cpu
            data_stream: { dataset: system.cpu, type: metrics }
            metricsets: [cpu]
            period: 10s
          - id: memory
            data_stream: { dataset: system.memory, type: metrics }
            metricsets: [memory]
            period: 10s
          - id: network
            data_stream: { dataset: system.network, type: metrics }
            metricsets: [network]
            period: 10s
          - id: filesystem
            data_stream: { dataset: system.filesystem, type: metrics }
            metricsets: [filesystem]
            period: 1m
EOF

O Agent roda como DaemonSet, no modo standalone, e coleta métricas de CPU, memória, rede e filesystem para os data streams metrics-system.*-default.

Passo 3 — Aplicar os dois manifestos

kubectl apply -f manifests/filebeat.yaml
kubectl apply -f manifests/elastic-agent-standalone.yaml

kubectl -n elastic get beat filebeat -w
kubectl -n elastic get agent elastic-agent -w

Resultado esperado: o Beat filebeat e o Agent elastic-agent chegam a HEALTH green, com AVAILABLE 1 e EXPECTED 1. Pressione Ctrl+C.

Passo 4 — Conferir os dados e ajustar as réplicas

No Console:

GET /_data_stream/filebeat-*,metrics-system.*

Se algum data stream aparecer com status YELLOW, ajuste as réplicas para 0 (o lab-es tem um único node):

PUT /filebeat-*,metrics-*,logs-*/_settings
{
  "index.number_of_replicas": 0
}

Passo 5 — Explorar os logs dos pods

  1. Abra o Discover e crie uma Data View com o padrão filebeat-* e o campo de tempo @timestamp (se ela ainda não existir).
  2. Filtre os logs dos pods do Elastic Stack:
    kubernetes.namespace : "elastic"
    
  3. Adicione as colunas kubernetes.pod.name, kubernetes.container.name e message.
  4. Filtre só os logs do Elasticsearch:
    kubernetes.namespace : "elastic" and kubernetes.pod.name : lab-es-es-default-0
    
  5. Clique em um evento e use a opção de ver os documentos ao redor (surrounding documents) para ver o que aconteceu antes e depois dele.

Passo 6 — Explorar as métricas do node

  1. Abra Menu → Observability → Infrastructure → Hosts.
  2. O node do cluster aparece na lista com CPU, memória e rede.
  3. Clique no host para abrir o painel com as séries temporais das últimas horas.
  4. Abra também Infrastructure → Inventory e alterne a visão para Hosts, colorindo por CPU.

Passo 7 — Criar um alerta de infraestrutura

  1. Em Infrastructure → Inventory, abra o menu Alerts and rules → Infrastructure e escolha Create inventory rule.
  2. Configure: tipo de nó Hosts, condição CPU usage acima de 80 (%) por 5 minutos.
  3. Em Actions, escolha o conector Index ou deixe sem ação — a regra aparece em Observability → Alerts quando disparar.
  4. Salve a regra com o nome CPU alta no node.

Para ver a regra em funcionamento sem esperar uma carga real, edite-a baixando o limite para 1 (%): em poucos minutos o alerta aparece em Observability → Alerts. Depois, apague a regra em Alerts → Manage Rules.

Passo 8 — Remover os coletores

kubectl delete -f manifests/filebeat.yaml
kubectl delete -f manifests/elastic-agent-standalone.yaml

Resultado esperado: os recursos e o RBAC dos dois coletores são removidos. Os dados já coletados continuam no lab-es.


9.5 - Laboratório 2: instalando e configurando o APM Server

Neste laboratório vamos instalar o APM Server com o recurso ApmServer do ECK, conectá-lo ao lab-es e ao lab-kb e verificar que ele está recebendo requisições.

Passo 1 — Instalar o pacote APM no Kibana

O APM Server exige o pacote de integração apm no Kibana. O manifesto abaixo é o kibana.yaml com a seção config acrescentada:

cat <<'EOF' > manifests/kibana-apm.yaml
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: lab-kb
spec:
  version: 9.4.2
  count: 1
  elasticsearchRef:
    name: lab-es
  config:
    xpack.fleet.packages:
      - name: apm
        version: latest
  podTemplate:
    spec:
      containers:
        - name: kibana
          resources:
            requests:
              memory: 1Gi
              cpu: 500m
            limits:
              memory: 2Gi
EOF

O Kibana baixa o pacote do Elastic Package Registry, na internet: o pod precisa ter acesso a ela.

kubectl apply -n elastic -f manifests/kibana-apm.yaml
kubectl -n elastic get pods -w

Resultado esperado: um novo pod lab-kb-kb-<sufixo> é criado e o antigo é removido. Aguarde o novo ficar 1/1 Running e pressione Ctrl+C.

O pod do Kibana foi recriado, então o túnel caiu. Abra-o novamente:

pkill -f "port-forward.*5601" || true
nohup kubectl -n elastic port-forward --address 0.0.0.0 service/lab-kb-kb-http 5601 > /tmp/pf-kibana.log 2>&1 &
sleep 2
cat /tmp/pf-kibana.log

Resultado esperado: Forwarding from 0.0.0.0:5601 -> 5601.

Passo 2 — Criar o manifesto do APM Server

cat <<'EOF' > manifests/apm-server.yaml
apiVersion: apm.k8s.elastic.co/v1
kind: ApmServer
metadata:
  name: lab-apm
  namespace: elastic
spec:
  version: 9.4.2
  count: 1
  elasticsearchRef:
    name: lab-es
  kibanaRef:
    name: lab-kb
EOF
  • elasticsearchRef: o operator configura a saída do APM Server para o lab-es, com usuário e CA;
  • kibanaRef: o operator configura o endereço do Kibana no APM Server;
  • não há apm-server.yml para editar, nem senha no manifesto.

Passo 3 — Aplicar e acompanhar

kubectl apply -f manifests/apm-server.yaml
kubectl -n elastic get apmserver lab-apm -w

Resultado esperado: HEALTH green e NODES 1. Pressione Ctrl+C e confira o pod e o Service:

kubectl -n elastic get pods | grep lab-apm
kubectl -n elastic get svc lab-apm-apm-http

Resultado esperado: um pod lab-apm-apm-server-<sufixo> em 1/1 Running e o Service lab-apm-apm-http na porta 8200/TCP.

Passo 4 — Obter o secret token e abrir o túnel até o APM Server

Os agentes APM precisam do secret token que o operator gerou:

APM_TOKEN=$(kubectl -n elastic get secret lab-apm-apm-token \
  -o go-template='{{index .data "secret-token" | base64decode}}')
echo "Secret token do APM: $APM_TOKEN"

pkill -f "port-forward.*8200" || true
nohup kubectl -n elastic port-forward service/lab-apm-apm-http 8200 > /tmp/pf-apm.log 2>&1 &
sleep 2
cat /tmp/pf-apm.log

Resultado esperado: o token e a mensagem Forwarding from 127.0.0.1:8200 -> 8200.

O túnel fica ligado ao pod do APM Server. Se esse pod for reiniciado ou recriado, execute este bloco novamente.

Passo 5 — Verificar que o APM Server está funcionando

curl -k -H "Authorization: Bearer $APM_TOKEN" https://localhost:8200/

Resultado esperado: um JSON com informações do servidor, incluindo a versão ("version": "9.4.2").

O -k é necessário porque o certificado do APM Server é assinado pela CA própria que o operator criou, e não por uma CA conhecida pelo sistema.


9.6 - Laboratório 3: instrumentando uma aplicação Django com o agente APM

Neste laboratório vamos instrumentar uma aplicação Django existente com o agente Python do Elastic APM e verificar os dados chegando no Kibana. A aplicação roda direto na VM e envia os dados para o APM Server pelo túnel aberto no laboratório anterior.

Instalando a aplicação

mkdir -p ~/eck-lab/apm-app
cd ~/eck-lab/apm-app
wget https://github.com/BktechBrazil/elasticstacktotal/raw/main/find_search.tar.gz
tar zxfv find_search.tar.gz

Resultado esperado: a pasta find_search extraída em ~/eck-lab/apm-app.

Criando o ambiente virtual Python

sudo apt install python3-venv python3-pip -y
cd ~/eck-lab/apm-app
python3 -m venv venv
source venv/bin/activate

Resultado esperado: o prompt do terminal passa a começar com (venv).

Instalando as dependências da aplicação e o agente APM

cd ~/eck-lab/apm-app/find_search/
pip install -r requirements.txt
pip install elastic-apm

Resultado esperado: as dependências e o pacote elastic-apm instalados sem erros.

Configurando o agente no settings.py

vi ~/eck-lab/apm-app/find_search/core/settings.py

Faça as seguintes alterações no arquivo:

1. Adicionar o agente em INSTALLED_APPS:

INSTALLED_APPS = [
    # ... apps existentes ...
    'elasticapm.contrib.django',
]

2. Adicionar o bloco de configuração do APM:

ELASTIC_APM = {
    'SERVICE_NAME': 'find-search-app',
    'SERVER_URL': 'https://localhost:8200',
    'SECRET_TOKEN': 'COLE_AQUI_O_SECRET_TOKEN',
    'VERIFY_SERVER_CERT': False,
    'ENVIRONMENT': 'lab',
    'DEBUG': True,  # Necessário para enviar dados com Django em modo debug
}
  • SERVER_URL: o APM Server, pelo túnel na porta 8200. Com o ECK, a conexão é HTTPS;
  • SECRET_TOKEN: o valor exibido no Passo 4 do laboratório anterior (echo $APM_TOKEN);
  • VERIFY_SERVER_CERT: False: o agente aceita o certificado assinado pela CA do operator. Em produção, em vez disso, configure no agente o certificado da CA (SERVER_CA_CERT_FILE).

3. Adicionar o middleware de tracing:

Localize a variável MIDDLEWARE no settings.py e adicione o middleware do APM como primeiro item da lista:

MIDDLEWARE = [
    'elasticapm.contrib.django.middleware.TracingMiddleware',
    # ... middlewares existentes ...
]

O middleware precisa ser o primeiro da lista para capturar o tempo total de cada requisição corretamente.

Validando a configuração do agente

cd ~/eck-lab/apm-app/find_search/
python3 manage.py elasticapm check

Resultado esperado: a verificação do agente conclui sem erros de configuração e consegue se conectar ao APM Server em https://localhost:8200.

Iniciando a aplicação

cd ~/eck-lab/apm-app/find_search/
python3 manage.py runserver 0.0.0.0:8000

Resultado esperado: a mensagem Starting development server at http://0.0.0.0:8000/.

Acesse a aplicação no navegador em http://<IP_DA_VM>:8000 e navegue por algumas páginas para gerar transações.

Se algum data stream do APM ficar yellow, ajuste as réplicas no Console:

PUT /traces-apm*,metrics-apm*,logs-apm*/_settings
{
  "index.number_of_replicas": 0
}

Verificando os dados no Kibana

  1. Acesse Menu → Observability → Applications → Service Inventory
  2. O serviço find-search-app deve aparecer na lista de serviços
  3. Clique no serviço para ver:
    • Transactions: lista das rotas da aplicação com tempo médio de resposta e taxa de erros
    • Dependencies: dependências externas detectadas automaticamente (banco de dados, chamadas HTTP)
    • Errors: exceções capturadas durante a execução
  4. Clique em uma transação específica para ver o trace waterfall — o detalhamento do tempo gasto em cada operação dentro da requisição

O que o agente captura automaticamente no Django

Sem nenhuma instrumentação manual no código, o agente APM captura:

  • Todas as requisições HTTP recebidas pela aplicação
  • Queries de banco de dados (SQLite, PostgreSQL, MySQL) com o tempo de execução
  • Chamadas HTTP externas feitas pela aplicação
  • Renderização de templates Django
  • Exceções não tratadas (status 500)

Encerrando a aplicação

No terminal da aplicação, pressione Ctrl+C e desative o ambiente virtual:

deactivate

9.7 - Limpeza do ambiente

Remova o APM Server, feche o túnel da porta 8200 e volte o Kibana ao manifesto original:

cd ~/eck-lab
pkill -f "port-forward.*8200" || true
kubectl delete -f manifests/apm-server.yaml
kubectl apply -n elastic -f manifests/kibana.yaml
kubectl -n elastic get pods -w

Resultado esperado: o pod do APM Server é removido e o Kibana é recriado sem a seção config. Aguarde o novo pod lab-kb-kb-<sufixo> ficar 1/1 Running, pressione Ctrl+C e abra o túnel do Kibana novamente, com o bloco da seção 9.3.

O pacote apm continua instalado no Kibana e os dados de APM continuam no lab-es, nos data streams traces-apm*, metrics-apm* e logs-apm*.


Resumo do capítulo

  • Observabilidade combina logs, métricas e traces; o valor está na correlação entre os três, na mesma interface.
  • No Kibana 9.x, os logs são explorados no Discover (Logs Stream e Logs Explorer foram removidos na 9.0); a infraestrutura em Infrastructure (Inventory e Hosts); as aplicações em APM; a disponibilidade no Synthetics, que substitui o Uptime; e a experiência dos usuários no RUM.
  • No ECK, logs e métricas chegam por recursos Beat e Agent rodando como DaemonSet, e os traces pelo recurso ApmServer.
  • O operator cria para o APM Server o Service <nome>-apm-http, o certificado TLS e o secret token no Secret <nome>-apm-token; o Kibana precisa do pacote apm em xpack.fleet.packages.
  • Os agentes APM se conectam ao APM Server por HTTPS, com o secret token, e capturam transações, dependências e erros sem instrumentação manual.
  • Regras de alerta de infraestrutura, logs e APM transformam os dados em notificações, e os Cases registram as investigações.

Origem do conteúdo

9.1 e 9.2 - Observabilidade e componentes no Kibana

9.4 - Logs e métricas do cluster Kubernetes

9.5 a 9.7 - APM Server no ECK e agente Python

⚠️ **GitHub.com Fallback** ⚠️