feat(dashboards): add slo for widget data delivery (3/4)#61431
Conversation
55992e5 to
28aec47
Compare
MCP UI Apps size report
|
7ea3fdd to
f333b9f
Compare
dbd677b to
b137596
Compare
f333b9f to
b5a3124
Compare
b137596 to
ca59292
Compare
b5a3124 to
999ad3c
Compare
|
Size Change: 0 B Total Size: 81.9 MB ℹ️ View Unchanged
|
b4873e0 to
468a466
Compare
9f654c7 to
a5c395c
Compare
806c910 to
43d7f27
Compare
fcf8a71 to
2484fe6
Compare
43d7f27 to
aef4ae0
Compare
2484fe6 to
285d4bc
Compare
aef4ae0 to
f2fd850
Compare
285d4bc to
72f9878
Compare
f2fd850 to
5db6283
Compare
72f9878 to
504e583
Compare
5db6283 to
c135069
Compare
65b7b63 to
a17b4ab
Compare
c135069 to
48f528e
Compare
|
⏭️ Skipped snapshot commit because branch advanced to The new commit will trigger its own snapshot update workflow. If you expected this workflow to succeed: This can happen due to concurrent commits. To get a fresh workflow run, either:
|
a17b4ab to
6f79ef2
Compare
016ac59 to
9a6603f
Compare
6f79ef2 to
4a0a6c3
Compare
|
⏭️ Skipped snapshot commit because branch advanced to The new commit will trigger its own snapshot update workflow. If you expected this workflow to succeed: This can happen due to concurrent commits. To get a fresh workflow run, either:
|
Query snapshots: Backend query snapshots updatedChanges: 1 snapshots (1 modified, 0 added, 0 deleted) What this means:
Next steps:
|
| WHERE and(equals(events.team_id, 99999), ifNull(equals(if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id), '00000000-0000-0000-0000-000000000000'), 0), lessOrEquals(events.timestamp, toDateTime64(toDateTime64('today', 6, 'UTC'), 6, 'UTC')), greaterOrEquals(events.timestamp, toDateTime64('explicit_redacted_timestamp', 6, 'UTC')), lessOrEquals(events.timestamp, toDateTime64('today', 6, 'UTC')), notEmpty(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$session_id'), ''), 'null'), '^"|"$', ''))))), greaterOrEquals(s.min_first_timestamp, toDateTime64('explicit_redacted_timestamp', 6, 'UTC')), lessOrEquals(s.min_first_timestamp, toDateTime64('today', 6, 'UTC'))) | ||
| GROUP BY s.session_id | ||
| HAVING and(ifNull(greaterOrEquals(expiry_time, toDateTime64('today', 6, 'UTC')), 0), ifNull(equals(max(s.is_deleted), 0), 0)) | ||
| ORDER BY start_time DESC, |
There was a problem hiding this comment.
I think this AMBR is a flakiness / red herring thing, I presume that a merge from master will fix this in due time, as I don't see how these changes can be caused by this PR 😃. Might be good to double check before doing the final merge though.
c46fb2e to
e0624ac
Compare
5a5a735 to
26e655d
Compare
Emit dashboard_widget_delivery slo_operation events from run_widgets with widget_type, dashboard_id, and tile_id so delivery success is trackable per widget type on the analytics platform SLO dashboard. Co-authored-by: Cursor <cursoragent@cursor.com>
26e655d to
a210144
Compare
|
🎭 Playwright report · View test results →
These issues are not necessarily caused by your changes. |

Problem
Dashboard widgets fetch live data via
run_widgets, but we had no SLO coverage for whether that delivery succeeds — unlike subscriptions, alerts, and query service.Changes
SloOperation.DASHBOARD_WIDGET_DELIVERYand register it on the analytics platform SLO monitoring dashboard (99.95% target, US + EU)run_widgetswithslo_operation, taggingwidget_type,dashboard_id, andtile_idAccess/validation failures (missing tile, product access, API scope) are intentionally excluded — those are not platform delivery failures.
How did you test this code?
Automated tests (agent-authored):
posthog/slo/test/test_slo_context.py— existing SLO helper coveragetest_run_widgets.py::test_run_widgets_emits_slo_on_successful_widget_deliverytest_run_widgets.py::test_run_widgets_emits_slo_failure_when_widget_query_raises👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Automatic notifications
Docs update
No docs changes — internal observability only.
🤖 Agent context
Agent-assisted PR (Cursor). Follows the same
slo_operationpattern as subscription create and query service, scoped to the actual widget query execution in_run_widget_queryso we can break down delivery reliability bywidget_typeon the existing SLO monitoring terraform dashboard.Made with Cursor