文档/Dashboards
此页面尚未翻译,当前显示英文版本。 查看英文版本
Dashboards & Saved Charts
DBFlux persists chart configurations as Saved Charts and groups them into Dashboards — a grid of chart panels (and optional markdown dividers) that share a time range and refresh policy.
For chart engine internals (rendering, axes, decimation, palette), see Charts. For the SQLite storage layer, see Architecture.
Overview
- A SavedChart is the persisted form of a chart configuration: data source binding, series, Y-axis bindings, refresh policy, and time-range preset.
- A Dashboard is a named grid of panels. Each panel is either a
Chartslot (references aSavedChartby id) or aDividerslot (inline markdown header strip — no chart, no toolbar). - Dashboards own a shared time range and refresh policy that propagate to every loaded chart panel via subscriptions.
- Remote dashboards (e.g. CloudWatch) can be browsed in the sidebar and imported into a local Dashboard when the driver advertises the right capabilities.
Storage Layer
All dashboard and saved-chart data lives in ~/.local/share/dbflux/dbflux.db
under the viz_* table prefix:
| Table | Purpose |
|---|---|
viz_dashboards | Dashboard records (profile_id nullable, ON DELETE SET NULL) |
viz_dashboard_panels | Panel slots: panel_kind discriminator + optional divider_markdown |
viz_saved_charts | Saved chart root (SavedChartDto) |
viz_saved_chart_series | Per-series settings |
viz_saved_chart_binding_y | Y-axis bindings |
viz_saved_chart_source_metric_dimensions | CloudWatch metric dimensions |
viz_saved_chart_source_metric_series | CloudWatch metric series spec |
Repositories live in crates/dbflux_storage/src/repositories/viz_*.rs and
implement the standard Repository trait
(all(), find_by_id(), upsert(), delete()).
In-Memory Managers
Both managers wrap the SQLite repositories with in-memory caches for synchronous reads. Writes go to the repository first; caches update only on success.
DashboardManager(crates/dbflux_ui_base/src/dashboard_manager.rs) — domain typesDashboard,DashboardPanel,DashboardPanelKind(Chart { saved_chart_id }|Divider { markdown }|Inspector { metric_id }),DashboardPanelDraft. New dashboards are created withgrid_columns = 12; new panels are appended atgrid_column = 0on a new row withgrid_width = 12, grid_height = 2.SavedChartManager(crates/dbflux_ui_base/src/saved_chart_manager.rs) — owns theSavedChartlifecycle, includingSavedChartRefreshPolicy(Off/Interval { every_secs }).RemoteDashboardCache(crates/dbflux_app/src/remote_dashboard_cache.rs) — session-scoped in-memory cache for upstream dashboard listings. Not persisted across restart.
Document System Integration
Dashboards open as a DashboardDocument
(crates/dbflux_ui_document/src/dashboard/):
- Dedup key:
DocumentKey::Dashboard { dashboard_id }(persisted) orDocumentKey::InstanceOverview { profile_id }(auto-generated read-only). - Chart panels: each slot wraps a
ChartDocumententity (Loaded) or a placeholder for a deleted chart (Orphan). - Inspector panels: each slot wraps an
InspectorPanelentity that hosts aDataGridPaneland refreshes on the dashboard’s shared interval. Driver-supplied row actions (e.g. terminate connection, cancel query) appear in the row context menu. - Shared toolbar: a single
TimeRangePanelpropagates window changes to all loaded panels via subscriptions. - Concurrency: panel re-execution is bounded by
PANEL_REEXEC_CAPto avoid overwhelming the connection with concurrent queries. - Grid: 12-column canonical grid; drag-to-reorder and drag-to-resize via
DragReorderState/DragResizeStateindashboard/builder.rs.
Standalone saved charts open as ChartDocument
(crates/dbflux_ui_document/src/chart_document/), keyed by
DocumentKey::Chart { saved_chart_id }. ChartDocument renders standalone or
embedded inside a DashboardDocument panel.
Instance Overview and inspectors
Connections whose driver advertises INSTANCE_METRICS or INSTANCE_INSPECTOR
expose a read-only Instance Overview — a synthesized dashboard of live
server metrics and tabular inspectors that never touches storage until the user
chooses to keep it.
Opening the Instance Overview
The sidebar shows a single Instance Overview leaf under a connected profile (above the Instance Metrics and Instance Inspectors folders). Clicking it — or choosing Open from its right-click menu — opens the overview.
| Step | Detail |
|---|---|
| Source | The driver’s DefaultInstanceDashboard descriptor (fixed 12-column layout) returned by InstanceCatalog::default_dashboard() |
| Dedup | DocumentKey::InstanceOverview { profile_id } — one tab per connection; clicking again focuses the existing tab |
| Persistence | None. The DashboardDocument is built in memory at open time; no viz_* rows are written |
| Mode | Read-only. Edit-mode transitions, Add Panel, and the Edit/View toggle are suppressed; drag-reorder and drag-resize are disabled |
Saving it as an editable dashboard
A read-only overview shows a Save as editable button (toolbar, right group;
tooltip “Clone this overview into a new editable dashboard”). It clones the
synthesized layout — including exact panel positions — into a new persisted,
user-owned Dashboard via DashboardManager::append_panels with explicit
DraftGridLayout per panel. The clone opens as a normal editable
DocumentKey::Dashboard { dashboard_id } tab. The original overview stays
read-only and re-synthesizes on each open.
Inspector panels
Inspectors are the third dashboard panel kind, alongside Chart and Divider:
| Panel kind | Backing | Notes |
|---|---|---|
Chart | SavedChart reference (saved_chart_id) | Time-series chart |
Divider | Inline markdown | Header strip; no toolbar |
Inspector | DashboardPanelKind::Inspector { metric_id } | Tabular snapshot; refreshes on the shared interval |
DashboardPanelKind::Inspector { metric_id }
(crates/dbflux_ui_base/src/dashboard_manager.rs) carries no chart reference —
the inspector is identified by metric_id alone. Each inspector panel hosts a
DataGridPanel showing the current snapshot returned by
InstanceCatalog::fetch_inspector_snapshot (e.g. PostgreSQL pg_stat_activity,
MySQL PROCESSLIST, MongoDB currentOp, Redis CLIENT LIST).
Persistence: the Inspector value is stored in viz_dashboard_panels.panel_kind
with the inspector key in inspector_metric_id. Both were added by
migration 014 (014_viz_inspector_and_instance_metric), which extends the
panel_kind CHECK — first introduced in migration 013 with chart / divider
— to also accept inspector. (Standalone inspector tabs opened directly from
the Instance Inspectors sidebar folder use
DocumentKey::InstanceInspector { profile_id, metric_id }.)
Inspector row actions
Inspector rows can expose driver-supplied row actions (right-click context menu), e.g. Kill connection / Terminate session. The flow:
- The driver returns
InspectorRowActions fromInstanceCatalog::row_actions(metric_id). Availability is gated by per-driver privilege probes (see the driver READMEs), so an under-privileged session never sees an action it cannot run. is_destructiveactions prompt a confirmation modal before execution.- On confirm, the connection is re-resolved at execution time (not at click time) and
InstanceCatalog::execute_row_action(metric_id, action_id, row_values)runs. - Every attempt records an audit event. Failures route through
report_error_async(UserFacingErrorofErrorKind::Driver), so the user gets a toast with a correlation id that links to the audit row.
Execution lives in
crates/dbflux_ui_document/src/instance_inspector/mod.rs.
Refresh behavior
Dashboard, standalone-chart, and inspector refresh timers all check
AppState::connections() for the panel’s profile before each tick and skip
their work when the connection is closed. The timer itself stays alive, so
refresh resumes automatically on reconnect without re-arming.
Built-in driver coverage
| Driver | INSTANCE_METRICS | INSTANCE_INSPECTOR | Metric / inspector list |
|---|---|---|---|
| PostgreSQL | ✓ | ✓ | README |
| MySQL / MariaDB | ✓ | ✓ | README |
| MongoDB | ✓ | ✓ | README |
| Redis | ✓ | ✓ | README |
| SQL Server | ✓ | ✓ | README |
Each driver README lists the concrete metrics, inspectors, and row actions it exposes; this document does not duplicate them.
Driver Seams
Drivers opt into dashboard interop through generic core seams — the UI never branches on driver IDs.
Importing dashboards (JSON → local Dashboard)
- Trait:
DashboardImporter(crates/dbflux_core/src/connection/dashboard_import.rs) - Capability:
DriverCapabilities::DASHBOARD_IMPORT - Value types:
WidgetImportSpec— parsed widget specMetricView::{TimeSeries, StackedArea, SingleValue}ImportedMetricSeries— series + dimensionsWidgetLayout— native layout coordinates carried through to the local grid
Drivers parse dashboard JSON into a normalized set of widgets that the UI
imports as SavedCharts and lays out on a new Dashboard.
Browsing remote dashboards (sidebar)
- Trait:
DashboardSource(crates/dbflux_core/src/connection/dashboard_source.rs) - Capability:
DriverCapabilities::DASHBOARD_SYNC - Value types:
RemoteDashboard,DashboardRef(optionallast_modified: ISO8601)
The sidebar lists upstream dashboards through this seam; results are cached in
RemoteDashboardCache. Selecting a remote dashboard triggers DashboardImporter
to materialize it locally.
Instance metrics and inspectors
- Trait:
InstanceCatalog(crates/dbflux_core/src/connection/instance_catalog.rs) - Capabilities:
DriverCapabilities::INSTANCE_METRICS(time-series),DriverCapabilities::INSTANCE_INSPECTOR(tabular snapshots) - Value types:
InstanceMetricDef,InstanceInspectorDef,DefaultInstanceDashboard,InspectorRowAction
Drivers expose live server metrics (e.g. pg.tps,
mysql.queries_per_sec) and tabular inspectors (e.g. pg.activity,
mysql.processlist, mongo.currentop, redis.client_list) through a
single catalog. Each driver also publishes a
DefaultInstanceDashboard descriptor with a fixed 12-column layout —
the workspace opens this descriptor as a read-only Instance
Overview dashboard (dedup key
DocumentKey::InstanceOverview { profile_id }). The “Save as
editable” action clones the layout into a persisted dashboard owned
by the user.
Inspector rows can declare InspectorRowActions (e.g. Terminate
connection). Action availability is gated by per-driver privilege
probes (pg_monitor / pg_signal_backend for PostgreSQL, PROCESS /
CONNECTION_ADMIN for MySQL, killOp for MongoDB, CLIENT KILL for
Redis, VIEW SERVER STATE / KILL for SQL Server) so an
under-privileged session never sees actions it could not execute.
Every refresh timer (dashboard tick, chart standalone tick, inspector
tick) checks AppState::connections() for the panel’s profile and
skips its work when the connection is closed; the timer stays alive
so refresh resumes automatically on reconnect.
For the user-facing behavior of this seam (how the Instance Overview opens, Save as editable, inspector panels and row actions), see Instance Overview and inspectors above.
CloudWatch implementation
crates/dbflux_driver_cloudwatch/src/ provides:
CloudWatchDashboardSource— lists CloudWatch dashboards via the AWS SDKCloudWatchDashboardImporter— parses CloudWatch dashboard JSON intoWidgetImportSpecs with metric series, dimensions, and stat aggregations
This is read-only browsing and import, not a sync feature. DBFlux never writes back to CloudWatch dashboards.
Capability Matrix
| Capability bit | Meaning |
|---|---|
DASHBOARD_IMPORT (51) | Driver can parse dashboard JSON into widget specs |
DASHBOARD_SYNC (52) | Driver can list upstream dashboards |
Both capabilities are independent: a driver can advertise sync without import or vice versa.
Adding a New Dashboard-Capable Driver
- Implement
DashboardSourceon the driverConnectionto list upstream dashboards. AddDASHBOARD_SYNCtoDriverMetadata.capabilities. - Implement
DashboardImporteron the driverConnectionto parse a dashboard payload intoWidgetImportSpecs. AddDASHBOARD_IMPORT. - The UI will surface the dashboard tree in the sidebar and route imports without any driver-specific branching.