The faithful scribe of Camelot — “because even the Knights of the Round Table needed someone to write down what happened.”
Quick Start · Usage · Examples · Troubleshooting · Support
Excalibur Chronicler exports application logs from an Excalibur v4 SAM (Streamed Access Management) deployment. It queries the embedded Loki log aggregation service, packages the results into a compressed archive, and optionally encrypts the output for secure transfer to Excalibur support.
- Minimal dependencies — requires only
dockerorkubectlon the host - Automatic container detection — finds the right container/pod without manual configuration
- Time-based filtering — relative durations (
--since 6h) or absolute date ranges (--from/--to) - Service and level filtering — narrow the export to a specific service or log level
- Automatic pagination — handles large log volumes by batching queries to Loki
- Size estimation — shows entry count and estimated size before exporting
- Encrypted export — ECDH envelope encryption (AES-256-CBC + EC P-384) using the Excalibur support public key
- Docker and Kubernetes — works with both runtimes out of the box
| Requirement | Details |
|---|---|
| Excalibur SAM | v4.0+ |
| Container runtime | Docker or Kubernetes (kubectl) |
| Shell | Bash 4.0+ |
| Host OS | Linux |
| Optional | openssl (for encrypted exports) |
- A running Excalibur v4 SAM stack with Loki enabled
- Docker or kubectl installed and available in
PATH - (Optional) openssl on the host for encrypted exports. If not available, the script uses
opensslfrom theapicontainer automatically
Download the script and make it executable:
curl -fsSL https://raw.githubusercontent.com/excalibur-enterprise/excalibur-v4-chronicler/refs/heads/devel/excalibur-chronicler.sh -o excalibur-chronicler.sh
chmod +x excalibur-chronicler.shVerify the download integrity:
echo "76a4b1d7bd1862044496fcacfc4d14df5fe544dacb6ee089659697038a75c3f6 excalibur-chronicler.sh" | sha256sum -cExport logs with default settings:
./excalibur-chronicler.shExample output:
[2026-03-26 14:15:00] INFO: Chronicler — Excalibur Log Export
[2026-03-26 14:15:00] INFO: ============================================
[2026-03-26 14:15:00] INFO: Auto-detecting api container (has curl + openssl)...
[2026-03-26 14:15:00] INFO: Using container: api
[2026-03-26 14:15:01] INFO: Consulting the Oracle (Loki)...
[2026-03-26 14:15:01] INFO: The Oracle responds.
[2026-03-26 14:15:01] INFO: LogQL query: {product="excalibur-v4"}
[2026-03-26 14:15:01] INFO: Time range: last 24h
[2026-03-26 14:15:01] INFO: Querying log statistics...
[2026-03-26 14:15:02] INFO:
[2026-03-26 14:15:02] INFO: Estimated export:
[2026-03-26 14:15:02] INFO: Entries: 12847
[2026-03-26 14:15:02] INFO: Size: 8 MB (uncompressed)
[2026-03-26 14:15:02] INFO: Batches: 3 (5000 per batch)
[2026-03-26 14:15:02] INFO:
[2026-03-26 14:15:02] INFO: Proceed with the chronicle? [Y/n] y
[2026-03-26 14:15:03] INFO: Gathering the chronicles...
[2026-03-26 14:15:04] INFO: Page 1: 5000 entries (total: 5000)
[2026-03-26 14:15:05] INFO: Page 2: 5000 entries (total: 10000)
[2026-03-26 14:15:06] INFO: Page 3: 2847 entries (total: 12847)
[2026-03-26 14:15:06] INFO: Fetched 12847 log entries in 3 page(s)
[2026-03-26 14:15:06] INFO: Packaging 3 batch file(s) into archive...
[2026-03-26 14:15:07] INFO: ============================================
[2026-03-26 14:15:07] INFO: The chronicle is complete.
[2026-03-26 14:15:07] INFO: File: ./excalibur-chronicle-20260326-141500.tar.gz
[2026-03-26 14:15:07] INFO: Size: 1 MB
[2026-03-26 14:15:07] INFO:
[2026-03-26 14:15:07] INFO: Send this chronicle to Excalibur support for analysis.
With no options, the script:
- Uses Docker as the container runtime (
--runtime docker) - Auto-detects the
apicontainer in the running Excalibur stack - Exports all log levels and all services from the last 24 hours
- Queries Loki at
http://loki:3100inside the container network - Saves the archive to the current directory
The script produces an excalibur-chronicle-<timestamp>.tar.gz archive.
For Kubernetes deployments, specify the runtime explicitly:
./excalibur-chronicler.sh --runtime kubectl./excalibur-chronicler.sh [OPTIONS]
| Flag | Description | Default |
|---|---|---|
-t, --since DURATION |
Time range to export: 30m, 6h, 2d, 1w |
24h |
--from DATETIME |
Start of date range (ISO 8601) | — |
--to DATETIME |
End of date range. Requires --from |
now |
-l, --level LEVEL |
Filter by log level: error, warn, info, debug |
all |
-s, --service NAME |
Filter by service name (e.g. api, core, repository) |
all |
-o, --output DIR |
Output directory | . |
-f, --file NAME |
Custom output archive name | excalibur-chronicle-<timestamp> |
-e, --encrypt |
Encrypt with Excalibur support public key | off |
-r, --runtime RT |
Container runtime: docker or kubectl |
docker |
-C, --container NAME |
Container/pod name to exec into | auto-detected |
-N, --namespace NS |
Kubernetes namespace (ignored for Docker) | excalibur |
--loki-url URL |
Loki URL inside the container network | http://loki:3100 |
-y, --yes |
Skip the confirmation prompt | off |
-v, --verbose |
Enable verbose/debug output | off |
-h, --help |
Show help message | — |
| Unit | Suffix | Example | Range |
|---|---|---|---|
| Minutes | m |
30m |
1m–30d |
| Hours | h |
6h |
|
| Days | d |
2d |
|
| Weeks | w |
1w |
./excalibur-chronicler.sh --since 6h --level error[2026-03-26 14:20:00] INFO: LogQL query: {product="excalibur-v4", level="error"}
[2026-03-26 14:20:00] INFO: Time range: last 6h
[2026-03-26 14:20:01] INFO: Estimated export:
[2026-03-26 14:20:01] INFO: Entries: 237
[2026-03-26 14:20:01] INFO: Size: 184 KB (uncompressed)
[2026-03-26 14:20:01] INFO: Batches: 1 (5000 per batch)
./excalibur-chronicler.sh --from 2026-03-20 --to 2026-03-22[2026-03-26 14:22:00] INFO: LogQL query: {product="excalibur-v4"}
[2026-03-26 14:22:00] INFO: Time range: 2026-03-20 to 2026-03-22
./excalibur-chronicler.sh --from 2026-03-25T14:00:00[2026-03-26 14:23:00] INFO: LogQL query: {product="excalibur-v4"}
[2026-03-26 14:23:00] INFO: Time range: 2026-03-25T14:00:00 to now
./excalibur-chronicler.sh --service core[2026-03-26 14:25:00] INFO: LogQL query: {product="excalibur-v4", appName="core"}
[2026-03-26 14:25:01] INFO: Estimated export:
[2026-03-26 14:25:01] INFO: Entries: 4210
[2026-03-26 14:25:01] INFO: Size: 3 MB (uncompressed)
[2026-03-26 14:25:01] INFO: Batches: 1 (5000 per batch)
./excalibur-chronicler.sh --since 6h --encrypt[2026-03-26 14:30:05] INFO: Packaging 1 batch file(s) into archive...
[2026-03-26 14:30:05] INFO: Sealing the chronicle with the Seal of Camelot...
[2026-03-26 14:30:06] INFO: Sealed with enchantment — only Excalibur support holds the key.
[2026-03-26 14:30:06] INFO: ============================================
[2026-03-26 14:30:06] INFO: The chronicle is complete.
[2026-03-26 14:30:06] INFO: File: ./excalibur-chronicle-20260326-143000.tar.gz.enc.tar
[2026-03-26 14:30:06] INFO: Size: 156 KB
The encrypted archive (.enc.tar) can only be decrypted by Excalibur support.
./excalibur-chronicler.sh --runtime kubectl --namespace excalibur./excalibur-chronicler.sh --since 1w --output /tmp --yes[2026-03-26 02:00:00] INFO: Gathering the chronicles...
[2026-03-26 02:00:02] INFO: Page 1: 5000 entries (total: 5000)
[2026-03-26 02:00:04] INFO: Page 2: 5000 entries (total: 10000)
...
[2026-03-26 02:00:38] INFO: Fetched 87431 log entries in 18 page(s)
[2026-03-26 02:00:39] INFO: The chronicle is complete.
[2026-03-26 02:00:39] INFO: File: /tmp/excalibur-chronicle-20260326-020000.tar.gz
[2026-03-26 02:00:39] INFO: Size: 12 MB
The script produces a .tar.gz archive containing one or more JSON batch files:
excalibur-chronicle-20260326-141500.tar.gz
└── excalibur-chronicle-20260326-141500/
├── batch-0001.json
├── batch-0002.json
└── batch-0003.json
When --encrypt is used, the output is a .tar.gz.enc.tar file containing the encrypted data and an ephemeral public key. Send the entire .enc.tar file to Excalibur support — do not extract or modify it.
The script is designed to be transparent and non-invasive:
- Read-only — only reads logs from Loki; does not modify, delete, or write any data to the Excalibur stack
- No network calls — does not transmit data anywhere; the exported archive stays on the local filesystem
- No telemetry — collects no usage data and does not phone home
- Encrypted exports — when
--encryptis used, only Excalibur support can decrypt the archive (ECDH envelope encryption with EC P-384 + AES-256-CBC) - Ephemeral keys — the encryption key material is securely deleted immediately after use
If openssl is not installed on the host, the script performs encryption inside the api container, which has openssl pre-installed.
- Detect — locates the
apicontainer/pod in the running Excalibur stack - Verify — checks Loki connectivity through the container
- Estimate — queries entry count and byte size to show expected export volume
- Gather — fetches logs using paginated
query_rangerequests (5,000 entries per batch) - Package — compresses all batches into a single
.tar.gzarchive - Seal (optional) — encrypts the archive using ECDH envelope encryption
The Excalibur stack is not running, or the container has a non-standard name.
# Docker — verify the api container is running
docker ps | grep api
# Kubernetes — verify the api pod is running
kubectl -n excalibur get pods -l app=apiYou can specify the container manually with --container <name>.
Loki is not running or is not accessible from the api container.
# Verify Loki is running
docker ps | grep loki
# Test connectivity from inside the api container
docker exec api curl -sf http://loki:3100/readyIf Loki uses a non-standard URL, specify it with --loki-url <url>.
- Verify the time range covers a period when the system was active
- Check that services are configured to push logs to Loki
- Try a broader filter (remove
--levelor--service) - Use
--verboseto see the exact LogQL query and Loki responses
The --encrypt flag requires openssl. If it is not installed on the host, the script falls back to using openssl from the api container automatically. No action is needed.
If you need help or want to submit an exported archive for analysis:
- Email: support@xclbr.com
- Website: getexcalibur.com
When contacting support, include the archive file and a brief description of the issue you are investigating. If you used --encrypt, the archive can only be read by Excalibur support — no additional encryption is needed for email transfer.
This software is provided under a proprietary EULA. See the LICENSE file for the full terms.
Copyright © 2026 Excalibur s.r.o. All rights reserved.