Skip to content
Exlogare

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:

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:

SettingResolution order
TokenEXLOGARE_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.

FlagWhat it doesWhen to use it
--api-url <url>Overrides the API endpoint.Local development, staging, self-hosted API.
--jsonPrints 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_...
FlagRequiredMeaning
--token <token>NoAPI 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:

FlagMeaning
--providerCI provider label, for example jenkins, buildkite, teamcity, generic.
--projectProject or repository identifier for grouping.
--statusCI status. Defaults to failed.
--log-filePath 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
FlagRequiredMeaning
--provider <slug>YesCI/source label. Examples: jenkins, buildkite, drone, teamcity, circleci, generic.
--project <id>YesStable project identifier: org/repo, team/service, pipeline slug.
--status <status>NoRun status. Defaults to failed. Common values: failed, success, cancelled, timeout, error.
--pipeline-id <id>NoUnique run id inside the CI system. Useful for deduplication.
--job-id <id>NoJob/step id. Together with pipeline-id, helps avoid duplicate analyses.
--job-name <name>NoHuman-readable step name: unit tests, build image, deploy staging.
--branch <ref>NoBranch or ref.
--commit <sha>NoCommit SHA.
--pipeline-url <url>NoLink back to the CI run. Exlogare surfaces it in the analysis.
--build-number <n>NoDisplay build number. Used as run identifier when pipeline-id is empty.
--log-file <path>NoFailed-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

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
FlagMeaning
--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

FlagRequiredMeaning
--name <name>YesHuman-readable token label: jenkins-prod, buildkite-nightly, grafana-readonly.
--scope <scope>YesToken scope. Repeatable, or pass a Cobra string-slice value. Supported scopes: ingest, read.
--expires-in-days <n>NoTTL in days. 0 or omitting the flag means no expiry.
--jsonNoReturn 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 --json instead 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: