Dashboard and logs
AICR ships a built-in admin dashboard and a Prometheus metrics
endpoint. The dashboard pairs observability (statistics, live runs, events)
with configuration management (the Config tab) and complements an
external time-series system when you have one. This page expands on the
Quick start health check with how to enable admin
login, navigate the dashboard, read /metrics, and locate run logs and
snapshots.
Enabling admin login
Section titled “Enabling admin login”The dashboard has a separate super-admin login that is independent of webhook HMAC and trigger API keys. Set the admin env vars to turn it on:
AICR_ADMIN_USERNAME=adminAICR_ADMIN_PASSWORD=<strong-password># Or use a hash instead of the raw password (takes precedence):# AICR_ADMIN_PASSWORD_HASH=sha256:<hex>Corresponding config (defaults shown):
admin: username_env: AICR_ADMIN_USERNAME password_env: AICR_ADMIN_PASSWORD password_hash_env: AICR_ADMIN_PASSWORD_HASH # optional, takes precedence session_ttl_seconds: 86400 # 24 hours is the default; the field unit is seconds, not minutesWhen admin auth is configured, AICR initializes the statistics store selected by
storage.database.kind: SQLite uses storage.database.sqlite.path (default
/app/data/aicr.sqlite); PostgreSQL uses the URL named by
storage.database.postgres.url_env. The Config API can remain available when
statistics initialization fails, provided its own configuration store is available.
Navigating the dashboard
Section titled “Navigating the dashboard”The browser title and page heading are AICodeReviewer Admin. Config editors are visible only on their current page. Switching Config subpages closes clean or read-only drawers; dirty drawers require discarding changes or cancelling the switch. Switching a top-level tab hides the editor and preserves its draft. Literal credentials use password inputs: leave a stored value untouched to keep it, enter a replacement, or choose Clear stored value to remove it. Search credential rows let you choose an environment variable or a literal value.
Visit http://<aicr-host>:8080/dashboard (or /). Even before admin env is
configured, the route returns the dashboard shell with a setup-required
prompt instead of a 404; if path_prefix is set, the root paths redirect to
the prefixed entry.
After logging in, the dashboard lands on the Overview tab and has seven tabs:
-
Overview — the landing tab: total reviews, success/failure/skip counts, runs that found problems, total problems, issues created, code analyzed, LLM requests, input/output/total tokens, prompt cache hit rate with the hit/miss token split, estimated cost, average duration. A time-window selector switches between today / this week / this month / all (all in UTC). The Recent activity table includes the same per-run token total, cache hit/miss split, and hit rate as the Runs tab, plus the branch and short revision with the commit time.
-
Live — analyses running right now in this server process. Responsive cards show the worker slot, run ID, task title, attempt, workspace/trigger/repo, branch and revision (git short sha, SVN
r<N>, P4CL <N>; hover for the full revision) with the commit time when resolved, the model and agent, the phase (preparing → analyzing → publishing), the start time with a live elapsed counter, cumulative tokens with input/output and cache hit/miss/write counts (or~N est. promptwhen usage is unavailable), cache hit rate, LLM request count, retry/fallback counts, estimated cost, and the usage update time. Worker numbers identify active analysis slots in this process; a released slot can serve a later run. Kilo/OpenCode and pi/oh-my-pi update usage after each completed model turn; other agents and direct LLM calls update when the invocation finishes. Entries disappear when an execution settles or the server restarts. A Refresh button reloads on demand, and the auto-refresh selector (default Off (manual)) polls every 5/15/30/60 seconds after the previous request finishes. Polling pauses outside the Live tab and while the browser page is hidden; logout resets it to manual. A failed refresh labels retained data as stale. -
Projects — per-project aggregates (
workspaceId + triggerName + repoRef): review/success/failure/skip counts, problem totals, issues created, files changed, lines added/deleted, LLM requests, tokens, cache-hit tokens and hit rate, cost, average duration. Soft-deleted projects stay visible during their grace period and are flaggedisActive. -
Providers — per-provider+model aggregates: request count, input/output tokens, cache-hit tokens and hit rate, cost, retry/fallback/failure counts, average latency.
-
Runs — retained run details, fetched 20 at a time with Prev/Next. Each row shows real token usage when captured: total tokens with the cache-hit and non-cached input split and the hit rate;
—when the run reported no parseable usage. The Revision column shows the branch, the short revision, and the commit time when the VCS adapter could resolve it. -
Events — retained received webhook/trigger events, fetched 20 at a time. Each row shows the receipt-time decision:
executed(execution accepted),queued/duplicate(auto-commit receipt),deferred(execution window, with the scheduled resume instant),deduplicated(merged into a pending re-review),ignored(label, unsupported event, or unconfigured repository), orrejected(bad signature, invalid payload, missing configuration), with the reason and details such as matched labels or the receipt id. -
Config — database configuration, field sources, routing preview and version history. Enable
config_sources.database.enabledto use configuration management.
Events labels queued as queued at receipt, executed as execution
accepted, and deferred as deferred at receipt, with neutral badges.
The API retains the original decision values. Completed work can still have a
queued receipt; batch execution does not update that admission decision.
Queue shows current batch states, while Live shows a snapshot of running analyses.
The admin batches API exposes per-channel publications receipts while publication
is pending. Recovery with a valid saved payload skips analysis and confirmed
channels, retaining the original model usage and cost. Partial or uncertain writes
can duplicate messages on retry. Legacy or oversized checkpoints replay fully;
corrupt recovery data stops execution. Receipt attempts counts executor attempts,
not individual HTTP calls. Completed checkpoints retain local accounting only.
Refresh Live or enable auto-refresh before comparing its count with current work.
A new Recent Runs entry appears after its review result is stored. If none
appears, inspect receipt members, batch and stream state in the configured
auto-commit store, including execution windows and retry times. An unreadable
pinned configuration snapshot can prevent receipt expansion. A successful health
check or an old receipt decision alone does not establish queue progress.
Usage is aggregated across the complete review run, including the initial model
call, context or format-repair calls, and any final direct-LLM fallback. For
Kilo, each step_finish model turn counts as one request. The locally estimated
prompt size is kept separate and is shown only when real usage was unavailable;
it is never mixed into provider token totals.
Cached tokens are part of the input total: the hit rate is
cached tokens / input tokens, and the non-cached input is
input - cached - cache-write tokens. The rate shows — until a provider
reports usage with a non-zero input.
The Projects and Providers tabs each call their own time-windowed API
(GET /api/admin/stats/projects?since= and .../providers?since=). The Runs
tab uses GET /api/admin/runs?limit=20&page=1; Events and Queue use the same
server-side paging contract. Recent Runs and Events retain up to 2000 entries
by default, and Queue retains 1000 terminal batches, each for at most six calendar
months. Configure count and age independently under
storage.retention. Cleanup keeps
aggregate statistics and protects active/retrying Queue work.
The Live tab polls GET /api/admin/runs/live, which reads an
in-memory registry of the current process. Completed runs are available in
Recent Runs, subject to its retention limit. The dashboard queries real-time aggregation
as the source of truth.
Branch, revision, and commit time come from the run’s VCS stamp: the branch
travels with the webhook event; the analyzed head revision and VCS family
come from the adapter’s resolved range and kind. The commit time is resolved
best-effort by the VCS adapter after the scoped fetch (git log, svn log,
or p4 describe). Git uses the committer date; SVN uses svn:date; P4 shows
the submit time only for submitted changelists. Times display in the browser’s
local timezone. Unavailable commit times show —; legacy or unknown VCS kinds
retain the full revision without guessing a hash format.
Managing configuration
Section titled “Managing configuration”The Config editor’s JavaScript loads on first activation. Each configuration page then requests its own records, field values and reference options. Provider presets, built-in templates, built-in prompts and the weekly-schedule module load when their pages need them. Common form modules and the navigation schema are shared. Page reads must share one revision and file digest before entering the cache; a revision change retries the whole page once. Retry reloads failed pages. Switching pages ignores late responses from the previous page. New revisions clear clean form sessions while unsaved drafts retain their original conflict baseline.
In Config, edit providers, model groups, triggers, channels, routes, workspaces
and global settings. File-owned values are read-only; Copy as new database
config requires a distinct name. Database values supplement explicit file
configuration. A shadowed database record can be deleted; edit its file owner to
change the effective value. The agent, review and
queue.workers|rate_limit|retry|dead_letter prefixes are the exception: database
values win over file values, the Agent/Review/Queue pages stay editable, and
Reset database overrides clears the database overrides and falls back to the
file or default values.
Reserved Queue settings (workers.lock_ttl_seconds and dead_letter.*) remain
read-only because they have no runtime consumer. A reset also discards unsaved
page edits; a revision conflict shows the current database values before retry.
Reserved Queue settings (workers.lock_ttl_seconds and dead_letter.*) remain
read-only because they have no runtime consumer. A reset also discards unsaved
page edits; a revision conflict shows the current database values before retry.
Secret controls accept authorized environment variable
names. Replace or clear redacted legacy values before saving them.
The Templates and Prompts pages manage named template
(outputs.templates) and system-prompt (prompts.system) documents: the markdown
body is the runtime content, optional frontmatter only feeds the UI metadata.
Below the record table, read-only built-in assets (the built-in problem/summary
templates per channel kind and the built-in base prompt) offer Copy as new
database config to start a managed draft from their body. Channels reference
template names via templates.{problem,summary}; workspaces reference prompt
names via prompt.system_prompt/prompt.extra_system_prompt.
Document text round-trips unchanged, including URL fragments, credential-shaped
examples and names ending in _env. Preview and version history include these
entities. Delete or disable a referenced document only after removing its
references, or remove both in one staged publication.
Document text round-trips unchanged, including URL fragments, credential-shaped
examples and names ending in _env. Preview and version history include these
entities. Delete or disable a referenced document only after removing its
references, or remove both in one staged publication.
New providers can start from a Platform preset (Kimi For Coding, Kimi Open Platform, Zhipu, Z.AI, Alibaba Cloud, Tencent Cloud, DeepSeek), which prefills the endpoint, the wire protocol (OpenAI- or Anthropic-compatible), and the catalog mapping. Presets only prefill the draft; every field stays editable until you save. Endpoint tables and plan caveats live in LLM Providers and Models.
Use Save for one record or Save page changes for global settings. For related edits, use Stage changes or Stage page changes on each page, then Publish staged changes. For example, stage a provider, select it in a new model group, and publish both together. Staged edits share one revision and remain in browser memory; reloading the page discards them.
Reopen a staged record or page to continue editing its draft. Staging again keeps earlier changes; returning a field to its published value removes that change. Discard staged changes also clears the corresponding editor drafts.
Routing Preview includes staged changes without publishing. Stage open edits
first. Workspace path completion starts with {{, inserts segment expressions,
and uses default for nullable variables; choose a suitable fallback before
publication. Weekly schedules support multiple weekdays and time windows.
A successful save shows its revision. A conflict keeps the draft and offers a comparison before retrying. If the response is lost, check the operation status; Resubmit retries the original request. Stored, activation pending means the write is durable but the runtime has not activated it. Resolve that status before submitting another edit. Versions → Restore creates a new revision; it retains file locks and validates references. Newly accepted tasks use the published revision; already accepted tasks retain their original configuration.
The admin API
Section titled “The admin API”Queued commit events show a not before time: receipt delay and execution windows set the earliest eligible start; existing work can postpone it further.
All endpoints except /login require Authorization: Bearer <token>.
| Endpoint | Purpose |
|---|---|
POST /api/admin/login |
Verify username/password, return session token + expiry |
POST /api/admin/logout |
Revoke the session token |
GET /api/admin/stats |
Overview + today/this-week/this-month windows, projects, providers, recent runs |
GET /api/admin/stats/projects?since= |
Per-project aggregates |
GET /api/admin/stats/providers?since= |
Per-provider+model aggregates |
GET /api/admin/runs?limit=&page= |
Retained runs (limit 1..100, page from 1), with token usage, cache split and VCS stamp; page requests return {items,page,hasMore}, otherwise an array |
GET /api/admin/runs/live |
Currently running analyses from the in-process registry: phase, elapsed start time, cumulative tokens/requests/cost |
GET /api/admin/events?limit=&page= |
Received events with the same paging contract, receipt-time decision and reason |
GET /api/admin/config |
Configuration shell: head, fileDigest, provenance, per-collection counts |
GET /api/admin/config/collections/:kind |
One collection’s records, paginated with limit/offset |
GET /api/admin/config/fields, /globals |
Page/prefix-scoped field values and globals subtrees; redaction preserves full path ancestry |
GET /api/admin/config/builtin-assets?kind=templates|prompts, /provider-presets |
Built-in documents for one page, or provider presets |
GET /api/admin/config/schema, /options/:source |
Form specification and dynamic options |
POST /api/admin/config/changesets |
Atomic publication with baseRevision, fileDigest, operationId, and operations |
POST /api/admin/config/preview-route |
Read-only event preview; optional draft contains baseRevision, fileDigest, and operations |
POST /api/admin/config/validate |
Side-effect-free changeset validation; returns the redacted preview report without writing |
GET /api/admin/config/revisions/:revision |
One revision’s document plus its audit entries |
POST /api/admin/config/revisions/:revision/restore |
Publish a new revision restoring an old one; requires fileDigest, keeps file locks and reference validation |
GET /api/admin/config/operations/:id, /revisions, /status |
Operation recovery, version history and activation status |
/metrics
Section titled “/metrics”/metrics exposes low-cardinality, process-lifetime Prometheus counters and
histograms. It covers both sync and async review runs. High-cardinality
queries (per-project, per-provider) belong to the SQLite store behind the
dashboard, not /metrics. Histogram buckets, sums, and counts accumulate
over the process lifetime; only raw duration samples are windowed.
The dashboard stores only run and usage metadata — never prompts, full diffs, secrets, or un-redacted output.
Where run logs and snapshots live
Section titled “Where run logs and snapshots live”Per-run artifacts live under the workspace directory:
workspaces/<workspace_id>/runs/<run_id>/run.jsonrun.json is the audit snapshot for a run: target/workspace, provider/model,
triggerName, output and error summaries, resolved model-catalog source,
token estimates, and dispatch counts. The materialized agent runtime bundle
for the run lives under workspaces/<workspace_id>/agent/ (instructions,
skills, MCP config, manifest.json, .aicr-output-state.json).
Server-level logs go to the aicr-logs volume (/app/logs in the
container); tail them with docker compose logs -f or your container
runtime’s log driver.
Next steps
Section titled “Next steps”- Configuration fields — the
adminandstoragenamespaces. - Troubleshooting — diagnosing skipped runs and dispatch failures using the dashboard and run snapshots.