Exlogare CLI
Install and use `exl` to send CI logs and read AI root-cause analyses from the terminal.
exl is the Exlogare command-line interface. Use it when you want to send CI logs from a shell step, inspect AI root-cause analyses from a terminal, or script against Exlogare without wiring a full CI-provider integration first.
The CLI wraps the same two public APIs documented elsewhere:
- Universal ingest API for sending logs.
- Read API for listing and fetching analyses.
Install
The CLI is published as a single Go binary. Pick the install path that matches your environment.
Manual download
Download the archive for your OS/arch from GitHub Releases, extract exl, and put it somewhere on your $PATH.
exl version
Debian / Ubuntu package asset
The .deb file is attached to GitHub Releases. This is a direct package asset, not an apt repository yet.
curl -fsSL \
https://github.com/exlogare/exlogare-cli/releases/latest/download/exlogare-cli_amd64.deb \
-o exl.deb
sudo dpkg -i exl.deb
Fedora / RHEL package asset
The .rpm file is attached to GitHub Releases. This is a direct package asset, not a yum/dnf repository yet.
sudo rpm -i \
https://github.com/exlogare/exlogare-cli/releases/latest/download/exlogare-cli_amd64.rpm
Docker
Use Docker when you do not want to install anything on a runner image.
docker run --rm \
-e EXLOGARE_TOKEN \
ghcr.io/exlogare/exl:latest analyses list --since 24h
Authenticate
Create an API token in the dashboard: Settings -> API tokens.
For an interactive workstation, store the token in the local keychain:
exl auth login
Paste the token when prompted. The CLI stores it in the OS-native secret store:
- Linux: a libsecret-compatible store such as GNOME Keyring or KWallet.
- macOS: Keychain.
- Windows: Credential Manager.
For CI runners, prefer an environment variable:
export EXLOGARE_TOKEN=exl_...
Check whether the CLI can see a token:
exl auth status
Remove a workstation token:
exl auth logout
Configuration precedence:
| Setting | Resolution order |
|---|---|
| Token | EXLOGARE_TOKEN -> OS keychain |
| API URL | --api-url -> EXLOGARE_API_URL -> https://api.exlogare.net |
Use EXLOGARE_API_URL=http://localhost:8000 when testing against a local API.
Global flags
These flags are available on every command.
| Flag | What it does | When to use it |
|---|---|---|
--api-url <url> | Overrides the API endpoint. | Local development, staging, self-hosted API. |
--json | Prints machine-readable JSON where the command supports it. | Scripts, jq, CI automation. |
Example against a local API:
exl --api-url http://localhost:8000 analyses list --since 24h
Same via env:
EXLOGARE_API_URL=http://localhost:8000 exl analyses list --since 24h
Auth commands
exl auth login
Stores an API token in the OS keychain.
exl auth login
You can pass the token non-interactively:
exl auth login --token exl_...
| Flag | Required | Meaning |
|---|---|---|
--token <token> | No | API token. If omitted, the CLI checks EXLOGARE_TOKEN first, then prompts interactively. |
exl auth status
Shows whether a token is configured without calling the API.
exl auth status
The command masks the token and prints its source: EXLOGARE_TOKEN env or keychain.
exl auth logout
Deletes the token from keychain. If EXLOGARE_TOKEN is still set in the environment, it continues to take precedence.
exl auth logout
Send a failed CI log
exl ingest reads the log from --log-file, or from stdin when no file is provided.
make test 2>&1 | tee build.log
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
exl ingest \
--provider buildkite \
--project myorg/web \
--status failed \
--commit "$BUILDKITE_COMMIT" \
--branch "$BUILDKITE_BRANCH" \
--pipeline-url "$BUILDKITE_BUILD_URL" \
--log-file build.log
fi
Required flags:
| Flag | Meaning |
|---|---|
--provider | CI provider label, for example jenkins, buildkite, teamcity, generic. |
--project | Project or repository identifier for grouping. |
--status | CI status. Defaults to failed. |
--log-file | Path to the failed step log. If omitted, exl reads stdin. |
The CLI enforces a 4 MiB log cap before sending the request. Trim very large logs to the failing section first.
Full exl ingest flag reference
exl ingest \
--provider buildkite \
--project myorg/web \
--status failed \
--pipeline-id "$BUILDKITE_BUILD_ID" \
--job-id "$BUILDKITE_JOB_ID" \
--job-name "unit tests" \
--branch "$BUILDKITE_BRANCH" \
--commit "$BUILDKITE_COMMIT" \
--pipeline-url "$BUILDKITE_BUILD_URL" \
--build-number "$BUILDKITE_BUILD_NUMBER" \
--log-file build.log
| Flag | Required | Meaning |
|---|---|---|
--provider <slug> | Yes | CI/source label. Examples: jenkins, buildkite, drone, teamcity, circleci, generic. |
--project <id> | Yes | Stable project identifier: org/repo, team/service, pipeline slug. |
--status <status> | No | Run status. Defaults to failed. Common values: failed, success, cancelled, timeout, error. |
--pipeline-id <id> | No | Unique run id inside the CI system. Useful for deduplication. |
--job-id <id> | No | Job/step id. Together with pipeline-id, helps avoid duplicate analyses. |
--job-name <name> | No | Human-readable step name: unit tests, build image, deploy staging. |
--branch <ref> | No | Branch or ref. |
--commit <sha> | No | Commit SHA. |
--pipeline-url <url> | No | Link back to the CI run. Exlogare surfaces it in the analysis. |
--build-number <n> | No | Display build number. Used as run identifier when pipeline-id is empty. |
--log-file <path> | No | Failed-step log file. If omitted, exl reads stdin. |
Whenever your CI exposes pipeline-id and job-id, pass both. That makes repeated exl ingest calls idempotent for the same failed step.
stdin instead of a file
cat build.log | exl ingest \
--provider generic \
--project myorg/web \
--status failed
Or:
exl ingest \
--provider jenkins \
--project myorg/web \
--status failed < build.log
Recommended CI pattern
Save the log first, send it only if the command fails, then preserve the original exit code.
set -o pipefail
make test 2>&1 | tee build.log
status=$?
if [ "$status" -ne 0 ]; then
exl ingest \
--provider generic \
--project "$CI_PROJECT" \
--status failed \
--branch "$CI_BRANCH" \
--commit "$CI_COMMIT_SHA" \
--log-file build.log
fi
exit "$status"
This keeps the pipeline red while still sending the failing log to Exlogare.
Read analyses
List recent analyses:
exl analyses list --since 24h
Get JSON for automation:
exl analyses list --since 24h --severity high --json \
| jq -r '.items[] | "[\(.severity)] \(.project_path): \(.root_cause)"'
Show one analysis:
exl analyses show <analysis-id>
exl analyses list
The list command uses cursor pagination and supports the Read API filters.
exl analyses list \
--since 24h \
--until 2026-04-28T00:00:00Z \
--severity high \
--project myorg/web \
--source generic_ingest \
--limit 50
| Flag | Meaning |
|---|---|
--since <time> | Lower time bound. Accepts ISO timestamp or duration: 24h, 7d, 2026-04-01T00:00:00Z. |
--until <time> | Upper time bound. Usually an ISO timestamp. |
--severity <level> | Severity filter: low, medium, high. |
--project <id> | Project filter. |
--source <source> | Ingestion source filter, for example generic_ingest, github_webhook, circleci_ingest. |
--limit <n> | Page size, from 1 to 100. Defaults to 20. |
--cursor <token> | Cursor returned by the previous page. |
Without --json, the command prints a tab-separated summary. If another page exists, the output ends with:
next_cursor=...
Use JSON when scripting:
exl analyses list --since 7d --limit 100 --json
exl analyses show <analysis-id>
Shows the full RCA payload:
exl analyses show 9d3c2c41-...
With JSON:
exl analyses show 9d3c2c41-... --json
Human-readable output includes id, timestamps, provider/source, project, CI ids, severity, confidence, pipeline/job links, root_cause, explanation, and fix_suggestion when available.
Create short-lived runner tokens
Use a long-lived admin token once, then mint short-lived ingest tokens for CI runners:
exl tokens create \
--name buildkite-prod \
--scope ingest \
--expires-in-days 7 \
--json
Copy the returned token immediately. Exlogare only shows the raw token once.
Full exl tokens create flag reference
| Flag | Required | Meaning |
|---|---|---|
--name <name> | Yes | Human-readable token label: jenkins-prod, buildkite-nightly, grafana-readonly. |
--scope <scope> | Yes | Token scope. Repeatable, or pass a Cobra string-slice value. Supported scopes: ingest, read. |
--expires-in-days <n> | No | TTL in days. 0 or omitting the flag means no expiry. |
--json | No | Return the full JSON response for secret managers and automation. |
Examples:
# CI log ingestion only
exl tokens create --name jenkins-prod --scope ingest --expires-in-days 30
# Read-only token for Grafana/cron reports
exl tokens create --name grafana --scope read --json
# Token with two scopes
exl tokens create --name automation --scope ingest --scope read --expires-in-days 7
The token you use to call tokens create must be allowed to create tokens. The first seed token is usually created manually in the dashboard.
Output and exit codes
- Successful commands return exit code
0. - Flag validation errors, missing tokens, network errors, and API 4xx/5xx responses return a non-zero exit code.
- For CI scripts, use
--jsoninstead of parsing human-readable output. - If no token is found, the CLI suggests:
run exl auth login or set EXLOGARE_TOKEN.
Useful checks
exl version
exl auth status
exl --help
exl ingest --help
exl analyses list --help
exl tokens create --help
Source
The CLI is open source under Apache-2.0: