Skip to content

Logging — níveis configuráveis por env var

Todos os serviços do monorepo usam o pacote compartilhado flow-ai-logger para emitir logs estruturados via pino. O nível de log pode ser controlado globalmente ou por serviço através de variáveis de ambiente, sem precisar alterar código.

Nota: logging estruturado (flow-ai-logger) e observabilidade/tracing são concerns separados. Traces, spans e métricas OpenTelemetry são responsabilidade do pacote flow-ai-telemetry (initTelemetry(serviceName), configurado via UI pela chave Redis observability:config), não deste pacote.


Pacote compartilhado

packages/flow-ai-logger expõe uma única factory:

ts
import { createLogger, type Logger } from "flow-ai-logger"

export const logger: Logger = createLogger("meu-servico")

Cada serviço chama createLogger com seu próprio nome e exporta o singleton logger. O nome é usado para identificar a origem nos logs estruturados (campo name do pino) e para o override de nível por serviço.


Resolução de nível

A prioridade é decrescente:

PrioridadeVariávelExemplo
1 (maior)LOG_LEVEL_{NOME_EM_MAIÚSCULO}LOG_LEVEL_ENGINE=trace
2LOG_LEVELLOG_LEVEL=debug
3 (padrão)Derivado de NODE_ENVproductioninfo; qualquer outro valor (incl. não definido) → debug

O NOME_EM_MAIÚSCULO é o nome passado para createLogger transformado com .toUpperCase().replace(/-/g, '_'). Exemplos:

ServiçoNome passadoVariável de override
flow-ai-core"core"LOG_LEVEL_CORE
flow-ai-meta-api"meta-api"LOG_LEVEL_META_API
flow-ai-orchestrator"orchestrator"LOG_LEVEL_ORCHESTRATOR
flow-ai-engine"engine"LOG_LEVEL_ENGINE
flow-ai-agent"agent"LOG_LEVEL_AGENT
flow-ai-webchat-gateway"webchat-gateway"LOG_LEVEL_WEBCHAT_GATEWAY
flow-ai-ig-api"ig-api"LOG_LEVEL_IG_API

Comportamento especial por NODE_ENV

NODE_ENVNível padrãoFormato
testsilent (sempre, ignora LOG_LEVEL)
developmentdebugpino-pretty (colorido, single-line)
productioninfoJSON nativo

Em NODE_ENV=test o logger é silenciado independentemente de qualquer variável, evitando poluição no output do vitest.


Níveis disponíveis

Do mais verboso ao mais silencioso: tracedebuginfowarnerrorfatal.

Definir LOG_LEVEL=warn suprime todos os logs de nível info e debug.


Exemplos de uso

Nível global em desenvolvimento

bash
LOG_LEVEL=warn pnpm dev:local
# Apenas warn, error e fatal aparecem em todos os serviços

Trace só no engine

bash
LOG_LEVEL=info LOG_LEVEL_ENGINE=trace pnpm dev:local
# Engine emite trace+; demais serviços emitem info+

Por serviço no .env local

env
LOG_LEVEL=info
LOG_LEVEL_ORCHESTRATOR=debug
LOG_LEVEL_AGENT=trace

Convenção de chamada (pino)

O pino inverte a ordem dos argumentos em relação ao console.*: o objeto de contexto vem antes da mensagem.

ts
// Correto
logger.info({ sessionId, flowId }, "flow iniciado")
logger.warn({ rule }, "nenhuma condição casou")
logger.error({ err }, "falha ao persistir mensagem")

// Errado (não passa context para campo estruturado)
logger.info("flow iniciado: " + sessionId)

Para erros, envolva o objeto de erro na chave err:

ts
try {
  // ...
} catch (err) {
  logger.error({ err }, "[serviço] operação falhou")
}

Arquivos de referência

ArquivoPapel
packages/flow-ai-logger/src/index.tsFactory createLogger e tipo Logger
services/flow-ai-*/src/log/logger.tsSingleton de cada serviço
packages/flow-ai-telemetryConcern separado: tracing/observabilidade OpenTelemetry (initTelemetry)
.env.exampleDocumentação das variáveis LOG_LEVEL e LOG_LEVEL_*
turbo.jsonglobalEnv com as variáveis de nível para evitar cache stale

Nota: LOG_LEVEL_IG_API funciona em runtime — createLoggerprocess.env[envKey] dinamicamente — mas ainda não está listado em .env.example nem no globalEnv do turbo.json. Logo, ele não aparece ao copiar o .env.example e não invalida o cache do turbo quando alterado.

flow-ai — plataforma proprietária de atendimento via WhatsApp