Dashboards & Graphs
RunReveal’s dashboard system enables you to create custom visualizations of your security data using SQL queries against your ClickHouse tables. Build dashboards that surface critical insights and track key metrics in real-time.
Getting Started: Navigate to Dashboards → Graphs to create your first visualization, or go directly to Dashboards → Create Layout to build a complete dashboard.
Dashboard Components
Your RunReveal dashboards consist of three hierarchical components:
- Graphs — Individual visualizations powered by SQL queries.
- Panels — Containers that hold and size your graphs.
- Dashboard Layouts — The overall arrangement of panels.
Available Visualization Types
Time-Based Visualizations
Line Chart
- Best for continuous trends over time
- Shows changes in metrics like event rates, response times
- Supports multiple data series
Area Chart
- Renders as a filled line for volume trends
- Useful for cumulative or stacked metrics over time
Column Chart
- Perfect for time-bucketed data
- Compares values across time periods
- Supports stacking for multi-series data
-- Example: Events over time (best practice time bounds)
SELECT
toStartOfInterval(receivedAt, INTERVAL {interval:Int64} SECOND) AS time_bucket,
count() AS event_count
FROM runreveal.logs
WHERE receivedAt BETWEEN {from:DateTime} AND {to:DateTime}
GROUP BY time_bucket
ORDER BY time_bucket
Creating Graphs
1) Navigate to Graph Creation
Go to Dashboards → Graphs → Create Graph or click the edit layout button on an existing dashboard.
2) Write Your SQL Query
Use RunReveal’s query parameters for dynamic time ranges:
SELECT
toStartOfInterval(receivedAt, INTERVAL {interval:Int64} SECOND) AS time_bucket,
count() AS events,
sourceType
FROM runreveal.logs
WHERE receivedAt BETWEEN {from:DateTime} AND {to:DateTime}
GROUP BY time_bucket, sourceType
ORDER BY time_bucket
Available Parameters
{from:DateTime}
— Start time from the time picker{to:DateTime}
— End time from the time picker (inclusive){interval:Int64}
— Time interval in seconds (auto-calculated)
3) Configure Visualization
- Chart Type: Select from supported types (Line, Column, Area, Bar, Pie, KPI; Scatter optional).
- X Axis Column: Choose your X-axis data column.
- Y Axis Column: Choose your Y-axis data column.
- Stack Column: (Optional) Column for data stacking.
- Axis Titles: Add descriptive labels.
4) Test and Save
Click Run Query to preview your visualization, adjust as needed, then save with a descriptive name.
Creating Dashboards
1) Create Dashboard Layout
Navigate to Dashboards → Create Layout and provide a Dashboard Name.
2) Add Panels
Click Add Panel to create visualization containers. Choose from panel sizes:
xs
— Extra smallsm
— Smallmd
— Mediumlg
— Largexl
— Extra large
3) Assign Graphs to Panels
- Select existing graphs from the dropdown.
- Or create new graphs directly in the panel editor.
- Configure panel-specific settings.
4) Arrange and Save
Panels automatically arrange in a responsive grid. Save your dashboard when complete.
Stacking Options
Control how multi-series data is displayed:
Stack Type | Description | Use Case |
---|---|---|
Default/None | Series rendered independently | Compare absolute values |
Stacked | Series add on top of each other | See cumulative totals |
Stacked 100% | Normalized to 100% | Compare proportions over time |
Stacking is supported for: Bar/Column, Area, and Line charts.
Query Examples
Event Volume by Source (Line Chart)
-- Event volume trends by source type
SELECT
toStartOfInterval(receivedAt, INTERVAL {interval:Int64} SECOND) ts,
sourceType,
count(*) counter
FROM
runreveal.logs
WHERE
receivedAt BETWEEN {from:DateTime} AND {to:DateTime}
GROUP BY
ts,
sourceType
ORDER BY ts
AWS S3 Events (Area Chart)
-- S3 API events over time with filled area
SELECT
toStartOfInterval(receivedAt, INTERVAL {interval:Int64} SECOND) AS time,
count() AS s3Events
FROM aws_cloudtrail_logs
WHERE receivedAt > {from:DateTime}
AND receivedAt <= {to:DateTime}
AND eventSource = 's3.amazonaws.com'
GROUP BY time
ORDER BY time
Average Bytes per Event (Stat Card)
-- KPI: Average bytes per event processed
SELECT
toStartOfInterval(timestamp, INTERVAL 15 MINUTE) as time_bucket,
sum(CASE WHEN series = 'pipeline_entered_bytes' THEN value ELSE 0 END) /
sum(CASE WHEN series = 'pipeline_entered' THEN value ELSE 0 END) as avg_bytes_per_event
FROM external_metrics
WHERE timestamp >= {from:DateTime}
AND timestamp <= {to:DateTime}
AND series IN ('pipeline_entered', 'pipeline_entered_bytes')
GROUP BY time_bucket
HAVING sum(CASE WHEN series = 'pipeline_entered' THEN value ELSE 0 END) > 0
ORDER BY time_bucket ASC
AWS CloudTrail API Errors (Bar Chart)
-- API errors and operations by service
SELECT
toStartOfHour(receivedAt) as time_bucket,
eventSource,
count(*) as api_calls,
countIf(readOnly = false) as write_operations,
countIf(errorCode != '') as error_count
FROM aws_cloudtrail_logs
WHERE receivedAt >= {from:DateTime}
AND receivedAt <= {to:DateTime}
GROUP BY time_bucket, eventSource
ORDER BY time_bucket DESC, api_calls DESC
Best Practices
Query Optimization
- Always use time filters — Leverage
{from:DateTime}
and{to:DateTime}
withBETWEEN
or>=
/<=
operators. - Limit result sets — Add
LIMIT
for top‑N queries. - Use efficient aggregations — Prefer ClickHouse‑optimized functions:
toStartOfInterval()
for time bucketingcountIf()
for conditional countingsumIf()
for conditional sums
Time Intervals
RunReveal automatically calculates appropriate intervals based on your time range:
-- Let RunReveal handle interval sizing
toStartOfInterval(receivedAt, INTERVAL {interval:Int64} SECOND)
-- Or use fixed intervals for consistency
toStartOfHour(receivedAt) -- Hourly buckets
toStartOfDay(receivedAt) -- Daily buckets
toStartOfWeek(receivedAt) -- Weekly buckets
Live Features
Real-Time Updates
- Graphs refresh automatically based on your time picker settings.
- Live data updates without manual refresh.
- Consistent data across all panels in a dashboard.
Interactivity
- Hover tooltips — See detailed values on hover.
- Time range selection — Integrated with global time picker.
- Responsive design — Adapts to different screen sizes.