Logging

Mayros registra en dos lugares:

  • Logs de archivos (líneas JSON) escritos por el Gateway.
  • Salida de consola mostrada en terminales y la UI de Control.

Esta página explica dónde viven los logs, cómo leerlos y cómo configurar niveles y formatos de log.

Dónde viven los logs

Por defecto, el Gateway escribe un archivo de log rotativo en:

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

La fecha usa la zona horaria local del host del gateway.

Puedes anular esto en ~/.mayros/mayros.json:

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

Cómo leer los logs

CLI: seguimiento en vivo (recomendado)

Usa el CLI para hacer tail del archivo de log del gateway vía RPC:

bash
mayros logs --follow

Modos de salida:

  • Sesiones TTY: líneas de log estructuradas, bonitas y coloreadas.
  • Sesiones no-TTY: texto plano.
  • --json: JSON delimitado por líneas (un evento de log por línea).
  • --plain: forzar texto plano en sesiones TTY.
  • --no-color: desactivar colores ANSI.

En modo JSON, el CLI emite objetos etiquetados por type:

  • meta: metadatos del stream (archivo, cursor, tamaño)
  • log: entrada de log parseada
  • notice: sugerencias de truncamiento / rotación
  • raw: línea de log sin parsear

Si el Gateway no está alcanzable, el CLI imprime una sugerencia corta para ejecutar:

bash
mayros doctor

UI de Control (web)

La pestaña Logs de la UI de Control hace tail del mismo archivo usando logs.tail. Consulta /web/control-ui para saber cómo abrirla.

Logs solo de canal

Para filtrar actividad de canal (WhatsApp/Telegram/etc), usa:

bash
mayros channels logs --channel whatsapp

Formatos de log

Logs de archivo (JSONL)

Cada línea en el archivo de log es un objeto JSON. El CLI y la UI de Control parsean estas entradas para renderizar salida estructurada (hora, nivel, subsistema, mensaje).

Salida de consola

Los logs de consola son conscientes de TTY y formateados para legibilidad:

  • Prefijos de subsistema (p.ej. gateway/channels/whatsapp)
  • Coloreado por nivel (info/warn/error)
  • Modo compacto o JSON opcional

El formato de consola está controlado por logging.consoleStyle.

Configurar logging

Toda la configuración de logging vive bajo logging en ~/.mayros/mayros.json.

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

Niveles de log

  • logging.level: nivel de logs de archivo (JSONL).
  • logging.consoleLevel: nivel de verbosidad de consola.

--verbose solo afecta la salida de consola; no cambia los niveles de log de archivo.

Estilos de consola

logging.consoleStyle:

  • pretty: amigable para humanos, coloreado, con marcas de tiempo.
  • compact: salida más ajustada (mejor para sesiones largas).
  • json: JSON por línea (para procesadores de log).

Redacción

Los resúmenes de herramientas pueden redactar tokens sensibles antes de que lleguen a la consola:

  • logging.redactSensitive: off | tools (predeterminado: tools)
  • logging.redactPatterns: lista de cadenas regex para anular el conjunto predeterminado

La redacción afecta solo la salida de consola y no altera los logs de archivo.

Diagnósticos + OpenTelemetry

Los diagnósticos son eventos estructurados y legibles por máquina para ejecuciones de modelo y telemetría de flujo de mensajes (webhooks, encolado, estado de sesión). No reemplazan los logs; existen para alimentar métricas, trazas y otros exportadores.

Los eventos de diagnóstico se emiten en proceso, pero los exportadores solo se adjuntan cuando los diagnósticos + el plugin exportador están habilitados.

OpenTelemetry vs OTLP

  • OpenTelemetry (OTel): el modelo de datos + SDKs para trazas, métricas y logs.
  • OTLP: el protocolo de cable usado para exportar datos OTel a un collector/backend.
  • Mayros exporta vía OTLP/HTTP (protobuf) hoy.

Señales exportadas

  • Métricas: contadores + histogramas (uso de tokens, flujo de mensajes, encolado).
  • Trazas: spans para uso de modelo + procesamiento de webhook/mensaje.
  • Logs: exportados sobre OTLP cuando diagnostics.otel.logs está habilitado. El volumen de log puede ser alto; ten en cuenta logging.level y filtros del exportador.

Catálogo de eventos de diagnóstico

Uso de modelo:

  • model.usage: tokens, costo, duración, contexto, proveedor/modelo/canal, IDs de sesión.

Flujo de mensajes:

  • webhook.received: ingreso de webhook por canal.
  • webhook.processed: webhook manejado + duración.
  • webhook.error: errores del manejador de webhook.
  • message.queued: mensaje encolado para procesamiento.
  • message.processed: resultado + duración + error opcional.

Cola + sesión:

  • queue.lane.enqueue: encolar carril de cola de comandos + profundidad.
  • queue.lane.dequeue: desencolar carril de cola de comandos + tiempo de espera.
  • session.state: transición de estado de sesión + razón.
  • session.stuck: advertencia de sesión atascada + edad.
  • run.attempt: metadatos de reintento/intento de ejecución.
  • diagnostic.heartbeat: contadores agregados (webhooks/cola/sesión).

Habilitar diagnósticos (sin exportador)

Usa esto si quieres eventos de diagnóstico disponibles para plugins o sumideros personalizados:

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

Banderas de diagnósticos (logs dirigidos)

Usa banderas para activar logs de depuración extra y dirigidos sin elevar logging.level. Las banderas no distinguen mayúsculas de minúsculas y soportan comodines (p.ej. telegram.* o *).

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

Anulación de entorno (una vez):

MAYROS_DIAGNOSTICS=telegram.http,telegram.payload

Notas:

  • Los logs de banderas van al archivo de log estándar (igual que logging.file).
  • La salida aún se redacta según logging.redactSensitive.
  • Guía completa: /diagnostics/flags.

Exportar a OpenTelemetry

Los diagnósticos se pueden exportar vía el plugin diagnostics-otel (OTLP/HTTP). Esto funciona con cualquier collector/backend de OpenTelemetry que acepte 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
    }
  }
}

Notas:

  • También puedes habilitar el plugin con mayros plugins enable diagnostics-otel.
  • protocol actualmente solo soporta http/protobuf. grpc se ignora.
  • Las métricas incluyen uso de tokens, costo, tamaño de contexto, duración de ejecución y contadores/histogramas de flujo de mensajes (webhooks, encolado, estado de sesión, profundidad/espera de cola).
  • Trazas/métricas se pueden alternar con traces / metrics (predeterminado: on). Las trazas incluyen spans de uso de modelo más spans de procesamiento de webhook/mensaje cuando están habilitadas.
  • Establece headers cuando tu collector requiere auth.
  • Variables de entorno soportadas: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_PROTOCOL.

Métricas exportadas (nombres + tipos)

Uso de modelo:

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

Flujo de mensajes:

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

Colas + sesiones:

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

Spans exportados (nombres + atributos clave)

  • 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

Muestreo + vaciado

  • Muestreo de traza: diagnostics.otel.sampleRate (0.0–1.0, solo spans raíz).
  • Intervalo de exportación de métrica: diagnostics.otel.flushIntervalMs (mín 1000ms).

Notas de protocolo

  • Los endpoints OTLP/HTTP se pueden establecer vía diagnostics.otel.endpoint o OTEL_EXPORTER_OTLP_ENDPOINT.
  • Si el endpoint ya contiene /v1/traces o /v1/metrics, se usa tal cual.
  • Si el endpoint ya contiene /v1/logs, se usa tal cual para logs.
  • diagnostics.otel.logs habilita la exportación de log OTLP para la salida del logger principal.

Comportamiento de exportación de log

  • Los logs OTLP usan los mismos registros estructurados escritos en logging.file.
  • Respetan logging.level (nivel de log de archivo). La redacción de consola no se aplica a los logs OTLP.
  • Las instalaciones de alto volumen deberían preferir muestreo/filtrado del collector OTLP.

Consejos para solución de problemas

  • ¿Gateway no alcanzable? Ejecuta mayros doctor primero.
  • ¿Logs vacíos? Verifica que el Gateway esté ejecutándose y escribiendo a la ruta de archivo en logging.file.
  • ¿Necesitas más detalle? Establece logging.level a debug o trace y reintenta.