Gateway Diagnostics Export
One-command, pre-sanitised support bundle for the gateway — safe to attach to a bug report
One command writes a portable, pre-sanitised .zip — config shape, redacted logs, health, and forensics — safe to attach to a bug report without leaking secrets.
Quick Start
An agent operator hits a snag and asks for a bundle in one line.
from praisonaiagents import Agent
agent = Agent(
name="Gateway Operator",
instructions=(
"When a user reports the bot is misbehaving, run "
"'praisonai gateway diagnostics export' and share the resulting zip path."
),
)
agent.start("Something is off with the Slack bot — grab a support bundle so I can share it.")- Export a bundle
bash praisonai gateway diagnostics export # → ~/.praisonai/diagnostics/praisonai-diagnostics-YYYYMMDD-HHMMSS.zip - Point at a specific config
bash praisonai gateway diagnostics export --config gateway.yaml - Emit JSON for scripts
bash praisonai gateway diagnostics export --json
How It Works
Each section is best-effort — a section that cannot be gathered is recorded as an error instead of aborting the bundle.
The archive lands at ~/.praisonai/diagnostics/praisonai-diagnostics-<timestamp>.zip. The path is unique — a -N suffix is appended when a same-second stamp collides, so no bundle is silently overwritten.
File in .zip | Content |
|---|---|
summary.txt | Human-readable overview (redacted). |
config_shape.json | Config reduced to keys/modes only — credential values collapsed to "<set>" / "<empty>", all other scalars replaced with their type name (e.g. "<str>", "<int>"). No endpoints, ids, or free-text values leak. |
logs.txt | Redacted tail of the local daemon service log (fallback when the gateway is down). Passes through redact_secrets. |
health.json | Best-effort reachability of the running gateway ({reachable, detail}). |
forensics.json | Latest fast ShutdownForensics().snapshot() — no chat/prompt data. |
manifest.json | Tool name, issue reference (4044), UTC generated_at, list of sections, redacted: true, list of files. |
CLI Options
| Flag | Type | Default | Description | |
|---|---|---|---|---|
--config, -c | str | "gateway.yaml" | Path to gateway.yaml (resolved through _resolve_doctor_config). | |
--output-dir | `str \ | None` | None → ~/.praisonai/diagnostics (honours $PRAISONAI_HOME) | Directory to write the bundle. |
--log-lines | int | 200 | Number of recent (redacted) log lines to include. | |
--json | bool | False | Emit JSON ({path, manifest}) instead of the human summary. |
Python API
The bundler is typer-free, so you can call it directly.
from praisonai_bot.gateway.diagnostics import build_diagnostics_bundle
result = build_diagnostics_bundle(
"gateway.yaml",
output_dir="/tmp/bundles",
log_lines=500,
)
print(result["path"]) # /tmp/bundles/praisonai-diagnostics-....zip
print(result["manifest"]) # dict with tool, issue, generated_at, sections, filesSignature:
def build_diagnostics_bundle(
config_path: Optional[str],
*,
output_dir: Optional[str] = None,
include: Sequence[str] = ("summary", "health", "config_shape", "logs", "forensics"),
log_lines: int = 200,
) -> Dict[str, Any]: ...Skip sections you do not need with include:
from praisonai_bot.gateway.diagnostics import build_diagnostics_bundle
# Lightweight report — no health probe, no forensics
build_diagnostics_bundle(
"gateway.yaml",
include=("summary", "config_shape", "logs"),
)Safety Guarantees
Which Diagnostic Do I Need?
Best Practices
Attach the whole zip, not individual files
The manifest.json records exactly what was collected. Sharing the full archive keeps the report self-describing.
Export even when the gateway is down
The command falls back to local daemon logs on purpose — a bundle is most useful precisely when the gateway is unreachable.
Widen –log-lines for slow-manifesting bugs
The default 200 is a fast tail. Use --log-lines 2000 when you need a longer window to catch an intermittent failure.
Use –json in scripts and CI
The JSON payload gives you path for auto-upload and manifest for indexing.
Verify before sharing
Open config_shape.json once and confirm every secret slot shows "<set>" / "<empty>", never a raw value.