Logging

Mayros registra em dois lugares:

  • Logs de arquivo (linhas JSON) escritos pelo Gateway.
  • Saída de console mostrada em terminais e na Interface de Controle.

Esta página explica onde os logs ficam, como lê-los e como configurar níveis de log e formatos.

Onde os logs ficam

Por padrão, o Gateway escreve um arquivo de log rotativo em:

/tmp/mayros/mayros-YYYY-MM-DD.log

A data usa o fuso horário local do host do gateway.

Você pode substituir isso em ~/.mayros/mayros.json:

json
{
  "logging": {
    "file": "/path/to/mayros.log"
  }
}

Como ler logs

CLI: tail ao vivo (recomendado)

Use o CLI para fazer tail do arquivo de log do gateway via RPC:

bash
mayros logs --follow

Modos de saída:

  • Sessões TTY: linhas de log bonitas, colorizadas, estruturadas.
  • Sessões não-TTY: texto simples.
  • --json: JSON delimitado por linha (um evento de log por linha).
  • --plain: forçar texto simples em sessões TTY.
  • --no-color: desabilitar cores ANSI.

No modo JSON, o CLI emite objetos marcados com type:

  • meta: metadados do stream (arquivo, cursor, tamanho)
  • log: entrada de log analisada
  • notice: dicas de truncamento / rotação
  • raw: linha de log não analisada

Se o Gateway estiver inacessível, o CLI imprime uma dica curta para executar:

bash
mayros doctor

Interface de Controle (web)

A aba Logs da Interface de Controle faz tail do mesmo arquivo usando logs.tail. Consulte /web/control-ui para como abri-la.

Logs apenas de canal

Para filtrar atividade de canal (WhatsApp/Telegram/etc), use:

bash
mayros channels logs --channel whatsapp

Formatos de log

Logs de arquivo (JSONL)

Cada linha no arquivo de log é um objeto JSON. O CLI e a Interface de Controle analisam essas entradas para renderizar saída estruturada (hora, nível, subsistema, mensagem).

Saída de console

Logs de console são conscientes de TTY e formatados para legibilidade:

  • Prefixos de subsistema (ex: gateway/channels/whatsapp)
  • Coloração de nível (info/warn/error)
  • Modo compacto ou JSON opcional

A formatação de console é controlada por logging.consoleStyle.

Configurar logging

Toda configuração de logging fica em logging em ~/.mayros/mayros.json.

json
{
  "logging": {
    "level": "info",
    "file": "/tmp/mayros/mayros-YYYY-MM-DD.log",
    "consoleLevel": "info",
    "consoleStyle": "pretty",
    "redactSensitive": "tools",
    "redactPatterns": ["sk-.*"]
  }
}

Níveis de log

  • logging.level: nível de logs de arquivo (JSONL).
  • logging.consoleLevel: nível de verbosidade do console.

--verbose afeta apenas a saída do console; não altera os níveis de log de arquivo.

Estilos de console

logging.consoleStyle:

  • pretty: amigável ao humano, colorido, com timestamps.
  • compact: saída mais apertada (melhor para sessões longas).
  • json: JSON por linha (para processadores de log).

Redação

Resumos de ferramentas podem redigir tokens sensíveis antes de chegarem ao console:

  • logging.redactSensitive: off | tools (padrão: tools)
  • logging.redactPatterns: lista de strings regex para substituir o conjunto padrão

A redação afeta apenas a saída do console e não altera os logs de arquivo.

Diagnósticos + OpenTelemetry

Diagnósticos são eventos estruturados e legíveis por máquina para execuções de modelo e telemetria de fluxo de mensagens (webhooks, enfileiramento, estado de sessão). Eles não substituem logs; existem para alimentar métricas, traces e outros exportadores.

Eventos de diagnóstico são emitidos no processo, mas exportadores só se anexam quando diagnósticos + o plugin do exportador estão habilitados.

OpenTelemetry vs OTLP

  • OpenTelemetry (OTel): o modelo de dados + SDKs para traces, métricas e logs.
  • OTLP: o protocolo de transmissão usado para exportar dados OTel para um coletor/backend.
  • Mayros exporta via OTLP/HTTP (protobuf) hoje.

Sinais exportados

  • Métricas: contadores + histogramas (uso de tokens, fluxo de mensagens, enfileiramento).
  • Traces: spans para uso de modelo + processamento de webhook/mensagem.
  • Logs: exportados via OTLP quando diagnostics.otel.logs está habilitado. Volume de log pode ser alto; mantenha logging.level e filtros de exportador em mente.

Catálogo de eventos de diagnóstico

Uso de modelo:

  • model.usage: tokens, custo, duração, contexto, provedor/modelo/canal, ids de sessão.

Fluxo de mensagem:

  • webhook.received: ingresso de webhook por canal.
  • webhook.processed: webhook tratado + duração.
  • webhook.error: erros do handler de webhook.
  • message.queued: mensagem enfileirada para processamento.
  • message.processed: resultado + duração + erro opcional.

Fila + sessão:

  • queue.lane.enqueue: enfileiramento de lane de fila de comandos + profundidade.
  • queue.lane.dequeue: desenfileiramento de lane de fila de comandos + tempo de espera.
  • session.state: transição de estado de sessão + razão.
  • session.stuck: aviso de sessão presa + idade.
  • run.attempt: metadados de tentativa/repetição de execução.
  • diagnostic.heartbeat: contadores agregados (webhooks/fila/sessão).

Habilitar diagnósticos (sem exportador)

Use isso se você quiser eventos de diagnóstico disponíveis para plugins ou sinks personalizados:

json
{
  "diagnostics": {
    "enabled": true
  }
}

Flags de diagnóstico (logs direcionados)

Use flags para ativar logs de depuração extras e direcionados sem aumentar logging.level. Flags não diferenciam maiúsculas de minúsculas e suportam wildcards (ex: telegram.* ou *).

json
{
  "diagnostics": {
    "flags": ["telegram.http"]
  }
}

Substituição de env (único uso):

MAYROS_DIAGNOSTICS=telegram.http,telegram.payload

Observações:

  • Logs de flag vão para o arquivo de log padrão (mesmo que logging.file).
  • A saída ainda é redigida de acordo com logging.redactSensitive.
  • Guia completo: /diagnostics/flags.

Exportar para OpenTelemetry

Diagnósticos podem ser exportados via plugin diagnostics-otel (OTLP/HTTP). Isso funciona com qualquer coletor/backend OpenTelemetry que aceite OTLP/HTTP.

json
{
  "plugins": {
    "allow": ["diagnostics-otel"],
    "entries": {
      "diagnostics-otel": {
        "enabled": true
      }
    }
  },
  "diagnostics": {
    "enabled": true,
    "otel": {
      "enabled": true,
      "endpoint": "http://otel-collector:4318",
      "protocol": "http/protobuf",
      "serviceName": "mayros-gateway",
      "traces": true,
      "metrics": true,
      "logs": true,
      "sampleRate": 0.2,
      "flushIntervalMs": 60000
    }
  }
}

Observações:

  • Você também pode habilitar o plugin com mayros plugins enable diagnostics-otel.
  • protocol atualmente suporta apenas http/protobuf. grpc é ignorado.
  • Métricas incluem uso de tokens, custo, tamanho de contexto, duração de execução e contadores/histogramas de fluxo de mensagens (webhooks, enfileiramento, estado de sessão, profundidade/espera de fila).
  • Traces/métricas podem ser alternados com traces / metrics (padrão: on). Traces incluem spans de uso de modelo mais spans de processamento de webhook/mensagem quando habilitado.
  • Defina headers quando seu coletor requer autenticação.
  • Variáveis de ambiente suportadas: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_PROTOCOL.

Métricas exportadas (nomes + tipos)

Uso de modelo:

  • mayros.tokens (counter, attrs: mayros.token, mayros.channel, mayros.provider, mayros.model)
  • mayros.cost.usd (counter, attrs: mayros.channel, mayros.provider, mayros.model)
  • mayros.run.duration_ms (histogram, attrs: mayros.channel, mayros.provider, mayros.model)
  • mayros.context.tokens (histogram, attrs: mayros.context, mayros.channel, mayros.provider, mayros.model)

Fluxo de mensagem:

  • mayros.webhook.received (counter, attrs: mayros.channel, mayros.webhook)
  • mayros.webhook.error (counter, attrs: mayros.channel, mayros.webhook)
  • mayros.webhook.duration_ms (histogram, attrs: mayros.channel, mayros.webhook)
  • mayros.message.queued (counter, attrs: mayros.channel, mayros.source)
  • mayros.message.processed (counter, attrs: mayros.channel, mayros.outcome)
  • mayros.message.duration_ms (histogram, attrs: mayros.channel, mayros.outcome)

Filas + sessões:

  • mayros.queue.lane.enqueue (counter, attrs: mayros.lane)
  • mayros.queue.lane.dequeue (counter, attrs: mayros.lane)
  • mayros.queue.depth (histogram, attrs: mayros.lane ou mayros.channel=heartbeat)
  • mayros.queue.wait_ms (histogram, attrs: mayros.lane)
  • mayros.session.state (counter, attrs: mayros.state, mayros.reason)
  • mayros.session.stuck (counter, attrs: mayros.state)
  • mayros.session.stuck_age_ms (histogram, attrs: mayros.state)
  • mayros.run.attempt (counter, attrs: mayros.attempt)

Spans exportados (nomes + atributos principais)

  • mayros.model.usage
    • mayros.channel, mayros.provider, mayros.model
    • mayros.sessionKey, mayros.sessionId
    • mayros.tokens.* (input/output/cache_read/cache_write/total)
  • mayros.webhook.processed
    • mayros.channel, mayros.webhook, mayros.chatId
  • mayros.webhook.error
    • mayros.channel, mayros.webhook, mayros.chatId, mayros.error
  • mayros.message.processed
    • mayros.channel, mayros.outcome, mayros.chatId, mayros.messageId, mayros.sessionKey, mayros.sessionId, mayros.reason
  • mayros.session.stuck
    • mayros.state, mayros.ageMs, mayros.queueDepth, mayros.sessionKey, mayros.sessionId

Amostragem + descarga

  • Amostragem de trace: diagnostics.otel.sampleRate (0.0–1.0, apenas spans raiz).
  • Intervalo de exportação de métrica: diagnostics.otel.flushIntervalMs (mín 1000ms).

Notas de protocolo

  • Endpoints OTLP/HTTP podem ser definidos via diagnostics.otel.endpoint ou OTEL_EXPORTER_OTLP_ENDPOINT.
  • Se o endpoint já contém /v1/traces ou /v1/metrics, ele é usado como está.
  • Se o endpoint já contém /v1/logs, ele é usado como está para logs.
  • diagnostics.otel.logs habilita exportação de log OTLP para a saída do logger principal.

Comportamento de exportação de log

  • Logs OTLP usam os mesmos registros estruturados escritos em logging.file.
  • Respeitam logging.level (nível de log de arquivo). A redação de console não se aplica a logs OTLP.
  • Instalações de alto volume devem preferir amostragem/filtragem do coletor OTLP.

Dicas de solução de problemas

  • Gateway não acessível? Execute mayros doctor primeiro.
  • Logs vazios? Verifique se o Gateway está em execução e escrevendo no caminho do arquivo em logging.file.
  • Precisa de mais detalhes? Defina logging.level como debug ou trace e tente novamente.