Plataforma de observabilidade da Equipe Tech. Um contrato OpenTelemetry, um Collector por stack e adapters para cada runtime. O mesmo pipeline roda no desenvolvimento local e na produção.
Status: pipeline local, adapters por runtime e provisionamento implementados. A CLI também cria datasets, tokens Axiom e projetos Sentry por ambiente.
- OpenTelemetry como contrato: OTLP, W3C Trace Context e semantic conventions.
- A aplicação conhece somente um endpoint OTLP. Ela não conhece Axiom, Sentry ou outro backend.
- Wide events complementam os traces. Uma operação gera um root span, child spans nas fronteiras e um wide event de conclusão.
- Paridade local: o Collector fica entre a aplicação e o destino em todos os ambientes.
- Transferível: um projeto muda de dono com troca de endpoints e credenciais, sem mudança de código.
Browser
+--> Sentry frontend (SDK nativo)
+--> /_telemetry/events (API do projeto)
|
API + Workers + Jobs
+--> OTel Collector (sidecar por stack)
|
+--> Axiom logs
+--> Axiom traces
+--> Axiom metrics
Backend exceptions --> Sentry backend (SDK nativo)
| Componente | Responsabilidade |
|---|---|
| Pacote | Instrumentação, contrato de eventos, contexto e adapters |
| Collector | Redação, batch, retry, roteamento e enriquecimento |
| Axiom | Logs, traces, métricas, dashboards e monitores |
| Sentry | Exceções, releases, source maps e Session Replay |
| Cloudflare | Tunnel, WAF, rate limit e correlação via CF-Ray |
app -> otel-collector -> otel-desktop-viewer
O otel-desktop-viewer recebe os três sinais por OTLP e publica somente em loopback.
app -> otel-collector (Kamal accessory) -> Axiom
O Collector roda como accessory do Kamal, com filas persistentes limitadas por sinal e sem porta OTLP pública. Saúde e métricas internas são publicadas somente em loopback. Consulte Operar a fila persistente do Collector antes do primeiro deploy.
packages/
telemetry/ @equipe-tech/observability: núcleo neutro, contratos, política, identidade e lifecycle
evlog/ @equipe-tech/observability-evlog: eventos tipados com fila e entrega OTLP do evlog
sentry/ @equipe-tech/observability-sentry: captura sanitizada de defeitos Node e browser
react/ @equipe-tech/observability-react: runtime React web, listeners e entrega coordenada
nestjs/ @equipe-tech/observability-nestjs: integração HTTP e lifecycle do NestJS
effect/ @equipe-tech/observability-effect: integração HTTP e Layers para aplicações Effect
cli/ observability dev|provision: CLI, assets da stack local e do Collector de produção
docs/ padrões de código, erros, testes e workflow
tools/oxlint/ plugins de lint do projeto (anti-slop, effect)
repos/ repositórios vendorados para agentes (gitignored)
O núcleo @equipe-tech/observability publica entrypoints explícitos:
| Entrypoint | Conteúdo |
|---|---|
./effect |
WideEvent, layerWideEvent e effectEventsAdapter para aplicações Effect |
./metrics |
Facade sem dependência de framework para counters, histogramas, gauges observáveis, flush e close |
./node |
runMain, composição Node, digest SHA-256 de auditoria, lifecycle e ingestão do browser |
./browser |
BrowserTelemetry compatível com Effect, com fila limitada, batch e transporte injetável |
./browser/client |
Cliente imperativo do browser sem tipos Effect na API pública |
./testing |
Captura em memória dos exports OTLP reais para asserts de spans, logs e métricas |
A integração NestJS vive na raiz de @equipe-tech/observability-nestjs. Ela publica TelemetryModule, TelemetryInterceptor, withRequestSpan, createBrowserEventsController e a política HTTP. O adapter oficial de eventos vive em @equipe-tech/observability-evlog e fornece registration, drops() e pending().
A integração Effect nativa vive em @equipe-tech/observability-effect. Ela publica layerObservability, o middleware httpTelemetry, o limite errorBoundary com defineErrorCatalog e layerBrowserEventsRoute para effect/http. Aplicações Effect usam o perfil effect-api e o adapter de eventos effectEventsAdapter, sem evlog. Consulte Semântica HTTP do adapter Effect.
Os adaptadores Sentry publicam entrypoints separados para Node e browser, uma política compartilhada e um plano de upload de source maps sem credenciais.
O cliente imperativo do browser publica emit, flush, pending e dispose sem tipos Effect e documenta o ciclo de vida React suportado. O contrato do endpoint /_telemetry/events vive em BrowserEvents no entrypoint raiz. O servidor faz o parse com parseBrowserEventBatch e re-emite os eventos como wide events com atributos de servidor (event.source, browser.event.id). O cliente sanitiza nomes e campos antes da fila conforme a política de dados da telemetria do browser.
O pacote @equipe-tech/observability-nestjs publica o endpoint pronto. Registre createBrowserEventsController(observability.runtime, { eventLayer: observability.eventLayer }) nos controllers do módulo. Assim, o endpoint usa o mesmo adapter de eventos do servidor. O controller responde 202 { accepted } e rejeita batches inválidos com 400 { code, message, correlationId }. O valor correlationId é um identificador seguro para suporte. O limite de corpo bruto pertence ao transporte HTTP; o Express responde 413 acima do limite configurado.
Consulte Auditoria no servidor para contratos, ordem durável, outbox, privacidade e mapeamento evlog.
Consulte Métricas sem dependência de framework para lifecycle, limites de cardinalidade, atributos e erros.
Consulte a política de dados para classificações, mascaramento, descartes e limites por sinal.
Consulte Semântica HTTP do adapter NestJS para rotas, status, proxy, privacidade e exclusões.
Requisitos: Bun 1.4+ e Vite+ 0.3.0.
bun install # instala e habilita os hooks de git
bun repos:sync # clona os repositórios vendorados em repos/
bun check # lint (type-aware) + format + type-check
bun run build # compila os pacotes e gera as declarações
bun run test # testes
bun run test:package # valida os pacotes instalados fora do repositóriobun packages/cli/src/main.ts dev up # sobe collector + viewer (UI em http://localhost:8000)
bun packages/cli/src/main.ts dev status # estado da stack
bun packages/cli/src/main.ts dev down # derruba a stackA CLI copia os assets versionados para OBSERVABILITY_HOME. O diretório padrão é ~/.local/state/observability.
bun packages/cli/src/main.ts provision --dir ~/projeto --name meu-app
bun packages/cli/src/main.ts provision --dir ~/projeto --name meu-app --queue-mode best-effortSem --queue-mode, a CLI usa durable. Esse modo mantém as filas no disco e repete a exportação sem limite de tempo. Use best-effort para manter filas de até 64 requisições por sinal somente na memória. O modo best-effort perde o backlog quando o Collector reinicia e descarta itens que não forem enviados em cinco minutos.
O comando escreve observability/collector.yaml, observability/kamal.accessory.yml e observability/provision.json. O estado registra o modo, o projeto e os digests dos assets gerenciados.
O comando é idempotente. Uma mudança de modo ou um arquivo modificado gera OBS_CLI_PROVISION_CONFLICT antes de qualquer escrita. Use --force para substituir o bundle completo. No modo durable, prepare o filesystem dedicado de 8 GiB, valide owner 10001:10001 e mode 0700, e defina AXIOM_TOKEN no Kamal. Pare produtores antes de 75% de uso ou com menos de 2 GiB livres. Consulte Operar as filas do Collector para health, alertas, drain, backup e rotação.
A CLI autentica com Axiom e Sentry, cria recursos isolados por ambiente e salva as credenciais com modo 0600. Datasets Axiom usam kinds específicos por sinal, aceitam edge deployment e retenção explícitos e nunca são excluídos automaticamente. A exportação de um ambiente Axiom espera a ação manual de Correlation e --correlation-confirmed.
Consulte estes documentos:
- Perfis oficiais de observabilidade
- Ambientes isolam dados sem acoplar a aplicação
- Configurar um projeto com ambientes remotos
- Preparar uma aplicação gerada para release
- Referência da CLI
- Migrar o SDK e a CLI para 0.3
Com a stack no ar, o canário valida traces, logs e métricas no pipeline completo:
OBSERVABILITY_E2E=1 bun test:canaryO alvo deployed roda o canário na fronteira de aceitação real. A fronteira é aplicação -> Collector -> Axiom. O teste usa APL para traces e logs. O teste usa MPL para métricas.
Use production.yaml com datasets E2E dedicados. Defina estas variáveis:
AXIOM_TOKEN.AXIOM_DATASET_TRACES.AXIOM_DATASET_LOGS.AXIOM_DATASET_METRICS.
OBSERVABILITY_E2E_DEPLOYED=1 bun test:canary:deployedNa CI, o passo roda somente quando o secret AXIOM_TOKEN está configurado, junto com as variables AXIOM_DATASET_*. Use datasets E2E dedicados com retenção curta (1 dia); a limpeza dos dados de teste é feita pela retenção. Não aponte o canário para datasets de produção.
O projeto usa Effect v4 e conventional commits.
Toda preparação e publicação segue o runbook de publicação independente. Cada pacote usa um tag <slug>@<semver>, notas e checksum próprios. Não crie tags, releases, assets ou publicações npm fora do gate humano documentado no runbook.
Não existe modo de propriedade. As credenciais e os endpoints definem o dono: os recursos vivem na org Axiom, Sentry e Cloudflare que as envs do projeto apontam. Para transferir um projeto, troque as credenciais. O código não muda.
Quando a transferência para o cliente é um cenário previsto, provisione na org do cliente desde o início. A transferência vira revogação de acesso, sem migração de dados.