Add SQLite persistence and run history to the Dashboard - #18768
James Newton-King (JamesNK) wants to merge 102 commits into
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 18768Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 18768" |
00f9f9e to
bd4214e
Compare
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
PR Testing ReportPR Information
Artifact Version Verification
Changes Analyzed (279 files)Change Categories
Persistence modes (from PR)
Test Scenarios ExecutedScenario 1: CLI help shows new optionsObjective:
Scenario 2: Standalone dashboard,
|
| Scenario | Status | Notes |
|---|---|---|
| 1. CLI help shows new options | ✅ Passed | --application-name, --persistence present with correct descriptions |
2. Standalone None (default) |
✅ Passed | Temp WAL DB created; deleted on graceful stop; no run selector |
3. Standalone Resume |
✅ Passed | Deterministic app-scoped DB; persists + reused across restart; app name in header |
4. AppHost Run + run history |
✅ Passed | Per-run DB/lock/metadata; selector shows Live + completed; historical run read-only |
5. Invalid --persistence |
✅ Passed | Precise validation error, exit 12, no startup |
Overall Result
✅ PR VERIFIED — All 5 scenarios passed. The new aspire dashboard run --application-name/--persistence options, the three persistence modes (None/Run/Resume), and the run-history selector with read-only historical runs all behave as described.
Recommendations
- Consider confirming the
run.jsonfinalization on gracefulaspire stop(Scenario 4 observation): the exclusive lock is released butEndedAtUtc/CleanShutdownstay unset, so completed runs surface as abandoned rather than cleanly ended. Functionally harmless (runs are still browsable), but the metadata may be worth tidying.
Tested with the "Dogfood this PR" CLI in an isolated temp directory; dashboard UI verified with Playwright/Chromium. No changes made to the repository.
David Pine (IEvangelist)
left a comment
There was a problem hiding this comment.
Code review focused on issues not already covered by the existing review threads, across the SQLite persistence layer, run lifecycle/config/CLI, and the read-only invariant. 3 findings: one reachable bug (Resume-mode console-log duplication), one latent read-only defense-in-depth gap, and one low-severity startup-robustness issue. Everything else reviewed (run-store locking/retention math, data-source pool ref-counting/disposal, config validation, CLI --application-name/--persistence wiring, SQL parameterization/transactions/disposal, batch-insert chunking, and the rest of the read-only gating) was clean or already covered. Submitting as comments, not a formal approval.
David Pine (IEvangelist)
left a comment
There was a problem hiding this comment.
Tested this locally against the Stress and TestShop playgrounds — the SQLite persistence modes (None/Run/Resume) and the header run-history selector all work as expected, including completed runs persisting across AppHost restarts and opening read-only. Approving.
|
Superseded by the same-repository native stack #18926:
Recreated upstream because GitHub native stacks require every branch to belong to the same repository. |
Specification: Dashboard persistence
Fixes #4256
Description
Dashboard resources and telemetry previously existed only for the lifetime of the Dashboard process. This change adds SQLite-backed persistence so users can inspect completed application runs, compare telemetry before and after code changes, or keep a standalone Dashboard's data across restarts.
Highlights
Nonecreates a temporary database for one Dashboard process and remains the standalone Dashboard default.Runcreates a persistent database for each Dashboard process, retains up to ten runs per application, and is the AppHost Dashboard default.Resumereuses one persistent database across Dashboard restarts without exposing run selection.Live runand completed runs without reloading the browser. Historical runs are opened read-only, mutation controls are disabled, and metric views use the latest stored timestamp as their fixed end time.--application-nameand--persistencetoaspire dashboard run.Microsoft.Data.Sqlitewith the transitiveSQLitePCLRaw.bundle_e_sqlite3andSQLitePCLRaw.lib.e_sqlite3native packages, including the required native assets in the managed Dashboard bundle.Persistence scenarios
Temporary standalone Dashboard
Run the standalone Dashboard without persistence configuration:
The default
Nonemode is useful for a single development or diagnostic session. Its temporary database is deleted when the Dashboard stops.Compare AppHost runs
Start an AppHost normally. Its Dashboard defaults to
Run, so each AppHost start creates a separate run database. After changing application code and restarting the AppHost, use the header selector to compare resources and telemetry fromLive runwith completed runs.Resume a standalone Dashboard
Give a standalone Dashboard a stable application name and select
Resume:The Dashboard reopens the same database after restart. Container deployments must mount
ASPIRE_DASHBOARD_DATA_DIRECTORYfrom persistent storage and reuse the same application name, directory, and persistence mode.Screenshots / Recordings
Security considerations
Persisted Dashboard data can contain sensitive application-supplied values. Resource properties marked sensitive are stored without redaction or encryption, although their sensitivity marker is retained and current and historical values remain masked in the UI.
The database has no independent authorization or encryption layer. Operators must ensure that
ASPIRE_HOMEorDashboard:Data:Directory, plus backups and copies, have restrictive filesystem access controls that prevent unauthorized users from reading or modifying persisted data. The Dashboard does not set or validate specific ACLs or Unix file modes.This change does not add a network endpoint. Network ingestion, endpoint authentication and authorization, transport security, and data-read APIs are existing Dashboard concerns and are documented separately.
Validation
dotnet test --project tests/Aspire.Dashboard.Tests/Aspire.Dashboard.Tests.csproj --configuration Release --no-launch-profile -- --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"dotnet test --project tests/Aspire.Dashboard.Components.Tests/Aspire.Dashboard.Components.Tests.csproj --no-launch-profile -- --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"dotnet build src/Aspire.Dashboard/Aspire.Dashboard.csproj --no-restoreChecklist
<remarks />and<code />elements on your triple slash comments?