Gateway Tiered Diagnostics

Three-tier gateway health check: runtime endpoints, inbound message flow, and duplicate-service detection

Three CLI checks verify a running gateway from the outside in — HTTP endpoints reachable, inbound messages actually flowing, and no competing gateway fighting for the same tokens.

Diagram

Tiered Diagnostics

📡 Runtime
/info /health /ready /live

✅ Report

📨 Inbound
log tail + metrics delta

👯 Duplicates
tokens + LaunchAgents + logs

Quick Start

  1. Verify the gateway is reachable

    Probe the runtime endpoints of a running gateway:

    bash
    praisonai gateway test --check-runtime
  2. Confirm messages are arriving

    Check inbound delivery within a time window using a config file:

    bash
    praisonai gateway test --check-inbound --since 10m -c ~/.praisonai/gateway.yaml
  3. Detect a competing gateway

    Scan for a second gateway sharing your Slack/Telegram token:

    bash
    praisonai gateway test --check-duplicates

How It Works

Each tier answers a different “is my bot healthy?” question.

TierFlagWhat it proves
Runtime--check-runtimeHTTP endpoints respond; /ready returns ready:true, /live returns alive:true
Inbound--check-inboundReal messages arrived — via @mention received: log markers and a messages_inbound_total delta
Duplicates--check-duplicatesNo second gateway or shared token is stealing your inbound events

The inbound tier combines two independent signals: a scan of the gateway log and a Prometheus counter compared against a persisted baseline.

Diagram
/metrics endpointbot-stderr.logpraisonai gateway testUser/metrics endpointbot-stderr.logpraisonai gateway testUser–check-inbound –since 10mscan for “@mention received:” markersread messages_inbound_totaldiff against baselinemention count, last timestamp, hint

Configuration Options

The diagnostics are entirely CLI-driven — no new YAML keys.

praisonai gateway test flags:

FlagTypeDefaultDescription
--config, -cstr"gateway.yaml"Path to gateway.yaml
--check-runtimeboolFalseProbes /info, /health, /ready, /live
--check-inboundboolFalseVerifies recent inbound via logs + metrics delta
--check-duplicatesboolFalseScans for competing gateways / shared tokens
--sincestr"10m"Window for --check-inbound (accepts Xs / Xm / Xh / Xd)

praisonai gateway status flags:

FlagTypeDefaultDescription
--config, -cstr—YAML path (required by --deep/--probe)
--deepboolFalsePer-channel rows, log tail, DLQ hints, an outbox hint (praisonai gateway outbox list … — see Outbox Operator CLI), version-skew line
--probeboolFalseLive per-channel credential probe

praisonai gateway sessions subcommands:

SubcommandFlagsDescription
sessions list--platform, --active SECONDS, --jsonList active/known sessions
sessions show SESSION_REF--tail 20, --jsonShow one session’s last N transcript lines
sessions export--session-id, --out, --no-lineageExport gateway conversation state to a portable, versioned JSON payload
sessions import--in, --overwrite, --keep-live-fields, --max-sessions, --jsonRestore/migrate sessions from an exported payload (hardened)

Environment variable:

NamePurpose
GATEWAY_AUTH_TOKENBearer for /info and /metrics; attached only over loopback or HTTPS (omitted on plaintext remote to avoid leaking the credential)

/health uses the existing health_config.stale_after (default 120.0s) and startup_grace (default 60.0s).


Common Patterns

Run runtime and duplicate checks together for a fast liveness sweep:

bash
praisonai gateway test --check-runtime --check-duplicates -c gateway.yaml

Inspect stored conversations when a user reports a missing reply:

bash
praisonai gateway sessions list --platform slack --active 3600
praisonai gateway sessions show <session-ref> --tail 20

Call the checks directly from Python for custom health tooling:

python
from praisonai_bot.gateway.preflight import (
    check_runtime,
    check_inbound,
    check_duplicates,
)

runtime = check_runtime("gateway.yaml")
inbound = check_inbound("gateway.yaml", since="10m")
dupes = check_duplicates("gateway.yaml")

print(runtime.to_dict())
print(inbound.to_dict())
print(dupes.to_dict())

Each function returns a dataclass with a .to_dict() for JSON output:

FunctionReturns
check_runtime(config_path, timeout=5.0)RuntimeCheckResult
check_inbound(config_path, since="10m", log_path=None, timeout=5.0, probe_results=None)InboundCheckResult
check_duplicates(config_path)DuplicateCheckResult
list_gateway_sessions(platform=None, active_seconds=None)List[Dict]
show_gateway_session(session_ref, tail=20)Dict

Related Emissions

The inbound tier reads a counter the gateway increments on every inbound message.

  • Metric: messages_inbound_total{channel="..."} — incremented per channel, including the Slack @mention path. handle_mention now fires fire_message_received, so mentions count toward inbound and honour drop / rewritten content decisions.
  • /health additions: top-level last_inbound_at; per-channel ok, reason (from the HealthReason enum), last_activity, and optional probe.ok.
  • Two doctor checks (category BOTS, both requires_deep=True):
CheckSeverity
gateway_duplicate_servicesHIGH
gateway_no_inbound_recentMEDIUM

Run them with praisonai doctor --deep.


Best Practices

Seed the inbound baseline first

The first --check-inbound run seeds inbound_metrics_baseline.json. Re-run it after sending a test message to see a real delta within the window.

Use –check-duplicates before debugging silence

When a bot stops replying, a second gateway sharing the same token is the most common cause. Run --check-duplicates before touching config.

Keep GATEWAY_AUTH_TOKEN loopback-only for remote gateways

The bearer token is withheld over plaintext HTTP to a remote host. Probe over loopback or serve the gateway behind HTTPS so /info and /metrics stay reachable.

Widen the window for low-traffic bots

--since 10m suits busy bots. For a quiet channel use --since 2h or --since 1d so a real-but-old message still registers.


Related