文档/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 Chart slot (references a SavedChart by id) or a Divider slot (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:

TablePurpose
viz_dashboardsDashboard records (profile_id nullable, ON DELETE SET NULL)
viz_dashboard_panelsPanel slots: panel_kind discriminator + optional divider_markdown
viz_saved_chartsSaved chart root (SavedChartDto)
viz_saved_chart_seriesPer-series settings
viz_saved_chart_binding_yY-axis bindings
viz_saved_chart_source_metric_dimensionsCloudWatch metric dimensions
viz_saved_chart_source_metric_seriesCloudWatch 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 types Dashboard, DashboardPanel, DashboardPanelKind (Chart { saved_chart_id } | Divider { markdown } | Inspector { metric_id }), DashboardPanelDraft. New dashboards are created with grid_columns = 12; new panels are appended at grid_column = 0 on a new row with grid_width = 12, grid_height = 2.
  • SavedChartManager (crates/dbflux_ui_base/src/saved_chart_manager.rs) — owns the SavedChart lifecycle, including SavedChartRefreshPolicy (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) or DocumentKey::InstanceOverview { profile_id } (auto-generated read-only).
  • Chart panels: each slot wraps a ChartDocument entity (Loaded) or a placeholder for a deleted chart (Orphan).
  • Inspector panels: each slot wraps an InspectorPanel entity that hosts a DataGridPanel and 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 TimeRangePanel propagates window changes to all loaded panels via subscriptions.
  • Concurrency: panel re-execution is bounded by PANEL_REEXEC_CAP to avoid overwhelming the connection with concurrent queries.
  • Grid: 12-column canonical grid; drag-to-reorder and drag-to-resize via DragReorderState / DragResizeState in dashboard/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.

StepDetail
SourceThe driver’s DefaultInstanceDashboard descriptor (fixed 12-column layout) returned by InstanceCatalog::default_dashboard()
DedupDocumentKey::InstanceOverview { profile_id } — one tab per connection; clicking again focuses the existing tab
PersistenceNone. The DashboardDocument is built in memory at open time; no viz_* rows are written
ModeRead-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 kindBackingNotes
ChartSavedChart reference (saved_chart_id)Time-series chart
DividerInline markdownHeader strip; no toolbar
InspectorDashboardPanelKind::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:

  1. The driver returns InspectorRowActions from InstanceCatalog::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.
  2. is_destructive actions prompt a confirmation modal before execution.
  3. 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.
  4. Every attempt records an audit event. Failures route through report_error_async (UserFacingError of ErrorKind::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

DriverINSTANCE_METRICSINSTANCE_INSPECTORMetric / inspector list
PostgreSQLREADME
MySQL / MariaDBREADME
MongoDBREADME
RedisREADME
SQL ServerREADME

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 spec
    • MetricView::{TimeSeries, StackedArea, SingleValue}
    • ImportedMetricSeries — series + dimensions
    • WidgetLayout — 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 (optional last_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 SDK
  • CloudWatchDashboardImporter — parses CloudWatch dashboard JSON into WidgetImportSpecs 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 bitMeaning
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

  1. Implement DashboardSource on the driver Connection to list upstream dashboards. Add DASHBOARD_SYNC to DriverMetadata.capabilities.
  2. Implement DashboardImporter on the driver Connection to parse a dashboard payload into WidgetImportSpecs. Add DASHBOARD_IMPORT.
  3. The UI will surface the dashboard tree in the sidebar and route imports without any driver-specific branching.
Esc
移动 打开Esc 关闭