Pular para o conteúdo principal

O que muda com o GPT-5: análise técnica para engenheiros

· 3 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

O que muda com o GPT-5: análise técnica para engenheiros

O lançamento do GPT-5 em março de 2026 trouxe três mudanças que importam mais do que os benchmarks de marketing: contexto de 10M tokens, modalidade visual + áudio nativa e redução de 60% no custo por token de output. O que isso muda na arquitetura de quem já roda IA em produção?

Contexto de 10M tokens — o que realmente significa

10M tokens equivale a aproximadamente:

  • 15.000 páginas de texto
  • O Linux kernel inteiro + comentários
  • ~80 horas de transcrição de podcast

Mas atenção: latência cresce não-linearmente com contexto. Em testes internos no laboratório:

Contexto Latência média (p95)
4K 820 ms
32K 1.4 s
128K 4.8 s
512K 18 s
2M 76 s

Para a maioria dos casos, RAG bem feito com 32K de contexto ainda bate carregar 2M de tokens "para garantir". O ganho é em casos específicos: análise de codebase inteira, processamento de documentos legais longos, debugging de logs corporativos.

Multimodal nativo

O grande salto não é "aceita imagem" — isso o GPT-4 já fazia. É que o modelo raciocina nativamente sobre o conteúdo visual e textual no mesmo passe. Em prática:

  • Você manda um screenshot de erro de UI + o componente React + o stack trace
  • O modelo conecta os três num único contexto de raciocínio
  • Diagnóstico cai de minutos (humano vendo cada parte) para 4 segundos

Custo: 60% mais barato, mas com pegadinhas

Output tokens caíram 60%. Input tokens caíram só 25%. Para workloads que são input-heavy (RAG, busca semântica), o ganho é menor do que parece. Para output-heavy (geração de código, escrita longa), o ganho é real.

A regra prática que estamos usando: se 70%+ do custo do seu pipeline está em output tokens, migre para GPT-5 hoje. Se está em input, espere o GPT-5 Mini sair em julho.

Quando NÃO migrar

  • Pipelines críticos com prompt engineering muito específico ao GPT-4 (vai precisar re-tunar)
  • Workloads onde Claude 4.6 ainda é melhor (tarefas de raciocínio matemático e código longo)
  • Aplicações com SLA agressivo de latência (GPT-5 é, em média, 15% mais lento que GPT-4o em prompts curtos)

Conclusão

GPT-5 é evolução, não revolução. Mas a economia de output + multimodal nativo justifica a migração para a maioria dos pipelines do laboratório. Migramos 3 dos nossos 7 pipelines até agora — os outros 4 ficam no GPT-4o ou Claude até a próxima geração.

Aula prática: containerizar uma API Python em produção

· 3 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

Aula prática: containerizar uma API Python em produção

Containerizar uma API Python parece simples — até você precisar de logs estruturados, healthcheck, graceful shutdown e multi-stage build para uma imagem final < 100MB. Esta aula reproduz o template que usamos no lab.

O Dockerfile final (que vamos construir)

# ===== Stage 1: build =====
FROM python:3.12-slim AS builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# ===== Stage 2: runtime =====
FROM python:3.12-slim
WORKDIR /app

# Non-root user
RUN useradd -m -u 1000 -s /bin/bash app

# Copy installed deps from builder
COPY --from=builder /root/.local /home/app/.local
ENV PATH=/home/app/.local/bin:$PATH

# Copy app code
COPY --chown=app:app . .
USER app

EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1

CMD ["gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", \
"--bind", "0.0.0.0:8000", "--access-logfile", "-", \
"main:app"]

Resultado: imagem final de ~92MB.

Passo 1 — Multi-stage cuts your image in half

O truque do multi-stage é instalar dependências em um stage descartável (builder), e copiar apenas o resultado para o stage final. Sem isso, sua imagem carrega gcc, headers do Python, cache do pip — tudo desnecessário em runtime.

ApproachTamanho final
python:3.12 + pip install980 MB
python:3.12-slim + pip install280 MB
python:3.12-slim + multi-stage92 MB
python:3.12-alpine + multi-stage68 MB ⚠️

Alpine é menor, mas dá problemas com libs que dependem de glibc (numpy, scipy, pandas). Para APIs simples, vale. Para data-science, fique no slim.

Passo 2 — Por que gunicorn + uvicorn workers?

FastAPI é ASGI (async). Uvicorn é o servidor ASGI de referência. Mas em produção:

  • Uvicorn sozinho: processo único. Se ele crashar, sua API morre.
  • Gunicorn como process manager: fork de N workers, restart automático, graceful shutdown.
  • Workers do tipo UvicornWorker: gunicorn gerencia, uvicorn executa o async.

A combinação dá robustez de process manager + performance async. É o padrão recomendado pela própria documentação do FastAPI.

Passo 3 — Healthcheck que faz sentido

@app.get("/health")
async def health():
# 1. Processo está respondendo? Sim (a função executou)
# 2. Conexão com banco está ok?
try:
await db.execute("SELECT 1")
except Exception:
return Response(status_code=503)
return {"status": "ok"}

Esse /health é usado tanto pelo HEALTHCHECK do Dockerfile quanto pelo liveness/readiness do Kubernetes. Não retorne sempre 200: o healthcheck precisa falhar se o banco cair, senão o orchestrator nunca remove o pod doente do load balancer.

Passo 4 — Logs estruturados

import logging, json

class JSONFormatter(logging.Formatter):
def format(self, record):
return json.dumps({
"ts": self.formatTime(record),
"level": record.levelname,
"msg": record.getMessage(),
"module": record.module,
})

handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logging.basicConfig(level=logging.INFO, handlers=[handler])

Logs JSON são indispensáveis para qualquer ferramenta de observability (CloudWatch, Datadog, Grafana Loki) extrair campos.

Passo 5 — Graceful shutdown

from contextlib import asynccontextmanager

@asynccontextmanager
async def lifespan(app):
# startup
yield
# shutdown: close connections, flush logs
await db.close()

app = FastAPI(lifespan=lifespan)

Sem isso, ao escalar para baixo, conexões DB ficam abertas no servidor, requests em vôo são abortadas.

Resultado

Imagem final pronta para:

  • ECS Fargate
  • Cloud Run
  • Kubernetes
  • Docker Compose em produção (com Caddy/Nginx na frente)

E roda em qualquer plataforma sem mudança.

Tóquio em 5 dias: guia gastronômico para devorar a cidade

· 2 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

Tóquio em 5 dias: guia gastronômico para devorar a cidade

Tóquio é uma cidade que recompensa a curiosidade gastronômica como poucas. Em cinco dias, é possível atravessar uma régua impressionante: do sushi premiado no Tsukiji ao ramen de meia-noite em becos de Shinjuku, passando por izakayas que cabem oito pessoas e cafés especializados que tratam o coado como cerimônia.

Dia 1 — Tsukiji Outer Market

Chegue cedo. Antes das 7h, antes de pensar em café. O mercado externo do antigo Tsukiji ainda funciona, e é ali que você prova um sushi de atum que reconfigura sua escala interna de qualidade. Aposte em Sushi Dai ou Daiwa Sushi — se a fila assustar, ande mais uns 200 metros: tem sempre um balcão menor com peixe igualmente fresco.

Dia 2 — Ramen tour por Shinjuku

Não existe "o melhor ramen de Tóquio". Existe o ramen que você prova nessa noite específica, depois de 14 km de caminhada e duas garrafas de chu-hi. Para começar, Fuunji (tsukemen) e Menya Musashi (tonkotsu). Vá com fome e roupa que não te incomode no calor do vapor.

Dia 3 — Mercados de bairro

Pegue um trem para Yanaka. Caminhe sem destino. Você vai encontrar:

  • Tofu artesanal preparado naquela manhã
  • Croquetes que custam menos de R$ 5
  • Cafés escondidos em casas antigas

O segredo de Tóquio não está na lista de restaurantes premiados. Está em virar uma esquina e descobrir uma soba house de quatro lugares que existe há 70 anos.

Dia 4 — Café de especialidade

Tóquio é a capital silenciosa do café de especialidade. Glitch Coffee (Kanda), Koffee Mameya (Omotesando) e Bear Pond Espresso (Shimokitazawa) são paradas obrigatórias. Reserve o dia: cada um é uma experiência longa.

Dia 5 — Izakaya em Golden Gai

O bairro de Shinjuku conhecido como Golden Gai concentra ~200 bares em vielas estreitas. Muitos cabem seis pessoas. Pague o cover, peça uma highball, converse com o dono. É o adeus que Tóquio merece.

Gastos médios por dia (jan/2026):
- Refeições: ¥ 4.500 – 8.000
- Transporte: ¥ 800 – 1.200
- Atrações: ¥ 1.000 – 3.000
Total: R$ 350 – 600/dia

Por que Rust está virando o padrão na AWS (e o que isso significa para nós)

· 3 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

Por que Rust está virando o padrão na AWS (e o que isso significa para nós)

Em 2018, a AWS abriu o Firecracker (a VM minimalista que roda o Lambda e o Fargate) em Rust. Em 2022, o S3 começou a migrar componentes-chave para Rust. Em 2025, o time do EC2 anunciou que o novo controlador de placement está sendo escrito em Rust do zero. Em 2026, a Amazon publicou que 40% do código novo de infra core é Rust.

Não é hype. É decisão técnica.

O que Rust resolve que Go/C++/Java não resolviam

Memória sem garbage collector. Lambda precisa de cold start de < 100ms — GC pause de Go (mesmo do Go 1.21+) pode estourar isso em workloads sensíveis.

Concorrência sem data races em compile-time. O borrow checker do Rust impede que você compile código com race condition. Em sistemas distribuídos críticos (S3 servindo milhões de req/s), isso elimina uma classe inteira de bugs.

Performance C/C++, segurança Java. Sem segfault, sem buffer overflow, sem dangling pointer — e com o mesmo overhead de runtime que C.

O custo real

AspectoGoRust
Tempo para um eng. virar produtivo2 semanas3-6 meses
Linhas de código (mesma funcionalidade)1.0x1.3x
Tempo de compilação5s90s
Bugs em produção (memória/concorrência)médioquase zero

Rust é mais caro de escrever. A AWS aceita esse custo porque o ganho operacional (menos pages às 3 da manhã) compensa em escala.

O que isso significa para times menores

Se você tem 5 engineers e está escrevendo uma API CRUD, Rust é a escolha errada. A produtividade cai mais do que o ganho de performance compensa.

Se você está escrevendo:

  • Hot path de proxy / load balancer
  • Serializer/parser que processa GB/s
  • Sistema embarcado (IoT, edge)
  • Service mesh / data plane

...Rust passa a fazer sentido econômico.

A migração no laboratório

Estamos migrando um único serviço para Rust: o API gateway interno que processa autenticação de todos os pipelines de ML. Volume: ~50k req/s no pico. Razão: o serviço atual em Node consome 8 GB de RAM em pico e o cold start em deploy custa 2-3 min de degradação.

Resultado parcial (semana 3 de 12):

  • RAM em pico: 8GB → 600MB
  • Cold start: 2-3 min → ~3 segundos
  • Custo do time: 1 engineer Rust em formação por 3 meses

Conclusão

Rust não é "o novo Go". É a linguagem certa para sistemas onde overhead e correctness importam mais do que velocidade de desenvolvimento. Para o resto, Python/Go/TypeScript seguem sendo as escolhas certas.

A AWS migra porque a conta fecha. Para a maioria dos times, ainda não fecha.

Os 6 cafés de Florianópolis que mudaram nossa rotina de trabalho remoto

· 2 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

Os 6 cafés de Florianópolis que mudaram nossa rotina de trabalho remoto

Trabalhar remoto em Floripa parece fácil — até o terceiro dia, quando você descobre que nem todo café tem tomada disponível, que algumas pousadas cortam o wi-fi às 22h e que o "espresso" de quiosque pode ser uma surpresa amarga.

Depois de seis meses morando entre Lagoa, Centro e Campeche, montamos uma lista honesta dos seis cafés que viraram nossa base de operações.

1. Café Cultura (Lagoa da Conceição)

O clássico. Wi-fi rápido, mesa grande comunal e um cold brew que segura uma manhã inteira. Pode ficar lotado no fim de semana, mas das 9h às 11h em dia útil, é praticamente um co-working com bolo de cenoura.

2. Bracarense (Centro)

Mais tradicional, com menos tomadas, mas com o melhor pão de queijo da ilha. Ideal para reuniões curtas de 1-2 horas.

3. Origens Coffee Lab (Campeche)

Quem é fissurado em coado vai amar. Trabalham com grão de origem mapeada e tem um barista que sabe nome de fazenda da Mantiqueira de cor.

4. Box 32 (Mercado Público)

Não é exatamente um café — é um café-bar dentro do Mercado. Mas tem mesa, tomada e um cortado bem feito. Funciona até as 18h.

5. Coffee Lab Daniel Brito (Trindade)

Próximo da UFSC, lotado de estudantes, mas com pelo menos quatro mesas reservadas para quem leva notebook. Atmosfera de biblioteca-com-cheiro-de-grão.

6. Casa Aberta (Itacorubi)

O mais escondido. Cardápio menor, mas o espresso tem corpo de cinema. Vai cedo: ele fecha às 14h.

Critério principal: tomada acessível ao lado da mesa. Café bom sem energia não dura uma standup matinal.

Kubernetes vs Serverless em 2026: o framework de decisão que usamos no lab

· 3 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

Kubernetes vs Serverless em 2026: o framework de decisão que usamos no lab

A pergunta volta a cada novo serviço que vamos provisionar: K8s ou serverless? Depois de 3 anos rodando os dois em paralelo no laboratório, sistematizamos a decisão num framework de 5 dimensões.

A regra rápida (pra quem só quer o palpite)

Se você tem menos de 4 microserviços ou não tem time dedicado de plataforma, comece em serverless. Migre para K8s só quando a conta da serverless ficar maior que o custo de manter um cluster.

Esse é o ponto onde a maioria dos times decide errado — começa em K8s "porque é o futuro", passa 6 meses configurando ingress, secrets, monitoring, helm, e nunca chega a entregar o produto.

As 5 dimensões

1. Custo em escala

Lambda Cloud Run K8s (EKS)
1 req/s $0.20/mês $0.50/mês $73/mês (cluster)
100 req/s $20/mês $35/mês $73/mês
10k req/s $2000/mês $1200/mês $400/mês (3 nodes)
100k req/s $20k/mês $8k/mês $1200/mês

O ponto de inflexão fica entre 1k e 5k req/s dependendo do payload. Abaixo disso, serverless ganha. Acima, K8s ganha.

2. Cold start tolerância

WorkloadTolera cold start?
Webhook receiver✅ sim, raro
API pública pra usuário⚠️ depende (300ms tolerável, 3s não)
Processamento batch✅ totalmente
Inferência de IA em tempo real❌ K8s/SageMaker
Conexão WebSocket persistente❌ K8s

3. Estado e conexões persistentes

Serverless não mantém estado entre invocações. Se você precisa:

  • Conexão pool de DB persistente
  • Cache em memória
  • WebSocket de longa duração
  • Subscriptions de eventos com state

K8s é o caminho. Lambda + ElastiCache + DynamoDB resolve, mas com mais glue code.

4. Equipe disponível

Setup mínimo para K8s saudável:
- 1 SRE/Platform engineer dedicado
- CI/CD configurado (ArgoCD ou Flux)
- Observability stack (Prometheus + Grafana + Loki)
- Política de RBAC + secrets management
- Backup/disaster recovery do etcd

Setup mínimo para Lambda saudável:
- AWS SAM ou Serverless Framework
- CloudWatch alarms básicos

Tempo de setup inicial: 2-4 semanas K8s vs 1 dia Lambda.

5. Lock-in com provedor

Serverless = lock-in alto. AWS Lambda + API Gateway + DynamoDB é difícil migrar pra GCP.

K8s = portável (em teoria). Na prática, manifests rodam em qualquer cluster, mas operadores específicos (AWS Load Balancer Controller, EFS CSI driver, etc.) prendem ao cloud.

Casos reais do laboratório

Pipeline de embedding (jobs assíncronos, batch grande)

Escolha: Lambda + SQS. Cold start de 800ms é irrelevante quando o job inteiro leva 2 minutos. Custo cai pra ~$3/mês fora dos picos.

API de inferência em tempo real (latência crítica, p99 < 100ms)

Escolha: EKS + nodes com GPU. Modelos carregados em memória, sem cold start.

Webhooks de integrações (10-50 req/s, latência não-crítica)

Escolha: Cloud Run. Auto-scaling até zero quando ninguém está chamando, paga só pelo que usa.

Dashboard interno (10 users simultâneos, baixíssima escala)

Escolha: Cloud Run (free tier cobre tudo). K8s seria caro pra esse volume.

Conclusão

Não existe escolha "futura-prova". Existe escolha certa para o estágio atual do produto e tamanho do time. Comece simples, migre quando a conta ou a complexidade da serverless exceder o custo de operar um cluster.

Lisboa em 7 dias: o roteiro que evita o turismo cansado

· 2 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

Lisboa em 7 dias: o roteiro que evita o turismo cansado

Lisboa é uma cidade que vive de luz. A primeira impressão é sempre o brilho dourado batendo nas fachadas de azulejo. Mas depois das fotos no mirante de Santa Catarina, a maioria dos viajantes cai na mesma armadilha: três horas de fila no Pastéis de Belém, dois dias no Chiado, e Alfama virou um cartão postal sem alma.

Esse roteiro de 7 dias tenta fugir disso.

Dias 1-2: Centro e Chiado (cedo)

Faça a turistada inicial, mas antes das 10h. Praça do Comércio, Rua Augusta, Chiado. Almoce na Cantinho do Avillez (reservar) ou no Time Out Market (sem reserva).

Dia 3: Alfama de noite

Alfama de manhã é Disneylândia. De noite, depois das 21h, vira o que sempre foi: bairro de gente que mora ali, fado nas tascas e luz de poste no calçamento. Vá ao A Baiuca e peça o vinho da casa.

Dia 4: Belém sem o Pastéis de Belém

Sim. Vá ao Mosteiro dos Jerónimos, à Torre de Belém, ao MAAT. E coma o pastel na Manteigaria mesmo (no Chiado) — tem gente que prefere. Diferença é mínima e a fila é zero.

Dia 5: LX Factory + Time Out

Manhã na LX Factory (bookshop Ler Devagar vale a viagem). Almoço/tarde no Time Out Market.

Dia 6: Sintra

Pegue um Uber, não o trem. Saia das 8h. Faça Quinta da Regaleira primeiro (poço inverso!), depois Palácio da Pena. Volte tomando vinho na Quinta da Cevada.

Dia 7: Cascais ou Setúbal

Praia. Marisco. Final de viagem. Setúbal tem o melhor choco frito do planeta. Cascais é mais fácil de chegar.

Custo médio total (7 dias, casal):
- Hospedagem (Alfama, Airbnb): R$ 4.500
- Comida + bebida: R$ 4.000
- Transporte: R$ 1.200
Total: R$ 9.700

Edge computing: o que aprendemos rodando IA na borda em 6 meses

· 3 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

Edge computing: o que aprendemos rodando IA na borda em 6 meses

Em 2026, "rodar IA na borda" deixou de ser pesquisa experimental e virou opção real de arquitetura. Em 6 meses no laboratório, testamos três cenários reais. O resumo: muito mais difícil do que vendem, e muito mais útil do que parece em alguns casos específicos.

Cenário 1: classificação de texto em Cloudflare Workers AI

Modelo: Llama-3.2-3B quantizado para 4-bit Tarefa: classificar tickets de suporte em 12 categorias Volume: ~80k requests/dia

Resultado

  • Latência média: 120 ms (vs 800 ms chamando OpenAI)
  • Custo: $8/mês (vs $240/mês na OpenAI no mesmo volume)
  • Acurácia: 91% (vs 96% no GPT-4o)

Trade-off claro: 5% menos preciso, 30x mais barato, 7x mais rápido. Para classificação de ticket onde o humano revisa de qualquer jeito, vale demais.

O que não documentavam

  • Tamanho do modelo no edge: Cloudflare Workers AI cobra por modelo ativo. Modelos > 8GB têm cold start de 5-8s na primeira request da hora.
  • Determinismo: quantização 4-bit introduz não-determinismo perceptível. Mesmo input pode dar saídas diferentes em 1-2% das requests.

Cenário 2: ONNX no navegador (busca semântica client-side)

Modelo: all-MiniLM-L6-v2 (22 MB após quantização) Tarefa: busca semântica em um catálogo de 5k itens Onde roda: direto no navegador do usuário, via WebAssembly

Resultado

  • Latência de inferência: 40-80 ms (M1 Mac), 200 ms (Android médio)
  • Custo de servidor: $0 (tudo no client)
  • Privacidade: dados nunca saem do device

O que não documentavam

  • Download inicial de 22MB trava o primeiro paint. Solução: lazy-load com IntersectionObserver na busca, não na home.
  • Memória: modelos em WebAssembly não liberam memória depois de carregados — chrome chega a 800MB de RAM no tab. Não dá pra carregar 3 modelos diferentes.
  • iOS Safari tem implementação WASM limitada. Em iPhones antigos, a inferência leva 2-3s.

Cenário 3: llama.cpp em Raspberry Pi 5 (lab-only, off-grid)

Modelo: Llama-3.2-1B quantizado em 4-bit (700 MB) Tarefa: assistant para o sistema de monitoramento de sensores do lab Onde roda: Raspberry Pi 5 8GB conectado direto aos sensores, sem internet

Resultado

  • Tokens/segundo: 8-12 (suficiente para resposta de 100 tokens em ~10s)
  • RAM: 1.8 GB em uso constante
  • Funciona offline, sem dependência de API externa

Custo

  • Raspberry Pi 5 8GB: R$ 900
  • SD card 128GB: R$ 80
  • Cooler ativo: R$ 60
  • Total: R$ 1040 hardware único vs ~R$ 100/mês de API perpétua

Em 11 meses se paga. Útil para cenários air-gapped (laboratórios sensíveis, ambientes sem internet).

Quando edge NÃO compensa

  • Modelos > 8 GB (Llama 70B, GPT-5) — edge não tem RAM/GPU pra isso
  • Workloads com baixíssimo volume (< 100 req/dia) — overhead de operação não compensa
  • Aplicações onde 5% de queda na precisão é inaceitável (saúde, jurídico, financeiro)

Checklist para considerar edge no seu caso

  1. Volume > 10k req/dia? ✅ sim, vale avaliar
  2. Modelo tem versão quantizada de qualidade conhecida? ✅ vale avaliar
  3. Latência atual é gargalo? ✅ vale avaliar
  4. Custo de API hoje > R$ 500/mês? ✅ vale avaliar
  5. Time tem alguém disposto a aprender quantização? ✅ vale avaliar

Se respondeu sim em 3+, faça um POC de 1 semana.

Conclusão

Edge AI é tecnologia real e útil — mas apenas em casos específicos onde o trade-off de precisão por latência/custo/privacidade compensa. Para 80% dos workloads, chamar OpenAI ainda é a escolha certa.

A pergunta correta não é "podemos colocar IA na borda?" mas "esse caso específico paga o custo operacional de manter modelo na borda?"

Bolonha: por que essa cidade é a capital mundial da pasta

· 2 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

Bolonha: por que essa cidade é a capital mundial da pasta

Bolonha tem três apelidos: La Dotta (a culta — por causa da universidade mais antiga do mundo), La Rossa (a vermelha — pelas telhas) e La Grassa (a gorda — pela comida). É esse terceiro nome que nos interessa.

A pasta fresca como religião

Em Bolonha, pasta seca é coisa de gente apressada. A pasta de verdade é fresca, feita ovo + farinha 00, esticada à mão ou com cilindro manual. As sfogline (mulheres que fazem pasta em vitrines de rua) são uma instituição local — você passa e vê tagliatelle nascendo na sua frente.

O ragù bolonhês de verdade

Esqueça espaguete à bolonhesa. Em Bolonha, o ragù é servido com tagliatelle (massa larga, que carrega o molho) ou em lasanha verde. Os ingredientes não incluem alho. Incluem:

  • Carne de boi moída grossa
  • Pancetta
  • Sofrito de cebola, cenoura e aipo
  • Vinho branco (não tinto)
  • Leite no final (a parte controversa)
  • Tomate em pouca quantidade

Quem coloca alho em ragù em Bolonha é deportado simbolicamente.

Tortellini in brodo

O outro prato-bandeira. Tortellini minúsculos recheados de mortadela, lombo, parmigiano e noz-moscada, servidos em um caldo de carne claro e perfeito. É comida de inverno, comida de domingo, comida de avó.

Por que Bolonha não tem pizza?

A pizza é napolitana. Bolonha tem piadina — pão fino, achatado, recheado com mortadela e squacquerone. Não é pizza, mas resolve.

Onde comer (não erra)

  1. Trattoria Anna Maria — tagliatelle al ragù exemplar
  2. Sfoglia Rina — pasta fresca para levar
  3. Osteria dell'Orsa — tortellini in brodo + crostini
Tip prático:
Reserve sempre antes das 13h ou 20h.
Bolonha almoça no horário, jantar começa 19h30.

Aula: observability em Go do zero — traces, metrics e logs em 1 hora

· 3 min para ler
Lab IA/SW
Laboratórios de IA & Desenvolvimento de Software

Aula: observability em Go do zero — traces, metrics e logs em 1 hora

Esta aula é um passo-a-passo prático: pegamos uma API Go básica e instrumentamos os três pilares de observability (logs, metrics, traces) em 60 minutos. No final, você tem um serviço pronto para produção com visibilidade completa.

O serviço base (5 minutos)

package main

import (
"net/http"
"github.com/go-chi/chi/v5"
)

func main() {
r := chi.NewRouter()
r.Get("/users/{id}", getUser)
http.ListenAndServe(":8080", r)
}

func getUser(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
// ... lógica de fetch user
w.Write([]byte(`{"id":"` + id + `","name":"Maria"}`))
}

Funcional, mas cego. Vamos instrumentar.

Pilar 1: logs estruturados com slog (10 min)

A stdlib Go ganhou log/slog em 1.21 — não precisa mais de Zap, Logrus, etc.

import (
"log/slog"
"os"
)

func init() {
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
}))
slog.SetDefault(logger)
}

func getUser(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
slog.Info("user fetch",
"user_id", id,
"method", r.Method,
"path", r.URL.Path,
)
// ...
}

Output:

{"time":"2026-05-02T10:00:00Z","level":"INFO","msg":"user fetch","user_id":"42","method":"GET","path":"/users/42"}

Já consumível por CloudWatch, Loki, Datadog sem parser custom.

Pilar 2: metrics com Prometheus (15 min)

import "github.com/prometheus/client_golang/prometheus/promhttp"
import "github.com/prometheus/client_golang/prometheus"

var (
requestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total de requests HTTP",
},
[]string{"method", "endpoint", "status"},
)
requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Buckets: []float64{0.01, 0.05, 0.1, 0.3, 1, 3, 10},
},
[]string{"endpoint"},
)
)

func init() {
prometheus.MustRegister(requestsTotal, requestDuration)
}

// Middleware
func metricsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
ww := &statusWriter{ResponseWriter: w, status: 200}
next.ServeHTTP(ww, r)
requestsTotal.WithLabelValues(r.Method, r.URL.Path, fmt.Sprintf("%d", ww.status)).Inc()
requestDuration.WithLabelValues(r.URL.Path).Observe(time.Since(start).Seconds())
})
}

// main()
r.Use(metricsMiddleware)
r.Handle("/metrics", promhttp.Handler())

Agora curl :8080/metrics retorna formato Prometheus pronto pra scrape.

Pilar 3: traces com OpenTelemetry (25 min)

import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)

func initTracer(ctx context.Context) (*sdktrace.TracerProvider, error) {
exporter, err := otlptracegrpc.New(ctx,
otlptracegrpc.WithEndpoint("localhost:4317"),
otlptracegrpc.WithInsecure(),
)
if err != nil { return nil, err }

tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceName("users-api"),
)),
)
otel.SetTracerProvider(tp)
return tp, nil
}

func main() {
ctx := context.Background()
tp, _ := initTracer(ctx)
defer tp.Shutdown(ctx)

r := chi.NewRouter()
r.Use(metricsMiddleware)
r.Method("GET", "/users/{id}",
otelhttp.NewHandler(http.HandlerFunc(getUser), "users.get"),
)
http.ListenAndServe(":8080", r)
}

func getUser(w http.ResponseWriter, r *http.Request) {
ctx, span := otel.Tracer("users").Start(r.Context(), "fetch_from_db")
defer span.End()
// ... fetch user, e cada query passa ctx pra trazer no trace
}

Spans aparecem em qualquer backend OTel: Jaeger, Tempo, Datadog APM, Honeycomb.

Stack docker-compose pra testar localmente

services:
prometheus:
image: prom/prometheus
ports: ["9090:9090"]
volumes: ["./prometheus.yml:/etc/prometheus/prometheus.yml"]

grafana:
image: grafana/grafana
ports: ["3000:3000"]

tempo:
image: grafana/tempo
command: ["-config.file=/etc/tempo.yaml"]
ports: ["4317:4317"]

Em 1 hora você tem:

  • Dashboard de RPS, latência, erro por endpoint
  • Distributed tracing entre serviços
  • Logs estruturados queryable

Custo operacional

  • Self-hosted (lab): 1 VM 4GB roda Prometheus + Grafana + Loki + Tempo sem suar.
  • Managed: Grafana Cloud free tier (10k metrics series, 50GB logs, 50GB traces) cobre serviços médios.
  • Datadog: caro mas turn-key. Considere para times sem SRE.

Conclusão

Observability não é luxo. É o que te avisa antes do usuário reclamar. Em Go, com a stack acima, o custo de instrumentar é ~200 linhas pra um serviço médio — e o ganho é noites dormindo durante incidentes.