9.8 KiB
Product Analytics Dashboard Setup
This document turns product-analytics-instrumentation.md into dashboard setup steps. It intentionally excludes Discord / QQ ingestion and daily / weekly report automation.
After setting up the dashboards, run verifications/product-analytics-smoke.md against the deployed environment.
Scope
In scope:
- PostHog insights for frontend product journeys.
- Grafana panels for server-side product event health.
- Alert rules that can be configured directly in PostHog / Grafana.
Out of scope for this pass:
- Discord / QQ bot or spreadsheet synchronization.
- Daily / weekly report generation scripts.
Destination Rules
| Question | Destination | Reason |
|---|---|---|
| Can a user start chatting? | PostHog | Frontend journey and distinct user funnels |
| Where does provider setup fail? | PostHog | Provider config events are frontend PostHog events |
| Which voice is selected or previewed? | PostHog / Postgres metadata | voice_id is high-cardinality and must not be a Prometheus label |
| Is server TTS healthy right now? | Grafana | Server product events and OTel metrics are Prometheus-safe |
| Are users submitting feedback? | PostHog | App feedback is frontend product analytics |
PostHog Dashboard
Create a dashboard named AIRI Activation And Feedback.
Live dashboard created on 2026-06-30:
- Project:
Project AIRI (Web)(90721) - URL:
https://us.posthog.com/project/90721/dashboard/1779029 - Current cards:
- Text card:
AIRI product analytics runbook - Funnel:
Chat activation funnel - Trend:
Official provider usage - Funnel:
Official TTS activation - Trend:
Paywall exposure - Trend:
Provider config failures - Trend:
TTS voice selection and preview - Trend:
Top selected TTS voices - Trend:
Voice input friction - Trend:
Feedback and bug reports
- Text card:
Insight 1: Chat Activation Funnel
Type: Funnel
Steps:
chat_activation_startedchat_activation_succeededsecond_turn_started
Breakdowns:
provider_modeapp_surface
Filters:
- Date range: last 7 days
- Exclude internal users if the project has an internal user cohort.
Watch for:
- Official provider conversion lower than custom provider conversion.
- Large drop after
chat_activation_started. - First-turn success but weak
second_turn_startedconversion.
Insight 1b: Official Provider Selection
Type: Trends
Events:
official_provider_selected
Breakdowns:
provider_idsourceauto_selected
Watch for:
- Official provider auto-selection is present but users do not reach
second_turn_started. - A single provider id dominates errors or activation drop-off.
Insight 2: Chat Activation Failures
Type: Trends
Events:
chat_activation_failed
Breakdowns:
failure_stageerror_codeprovider_mode
Display:
- Stacked bar or line chart.
Watch for:
failure_stage = provider_configfailure_stage = model_listfailure_stage = llm_response
Insight 2a: All Message Round Failures
Type: Trends
Event:
message_round_failed
Breakdowns:
failure_stageerror_codeprovider_idapp_surface
Watch for:
- Failures where
turn_index > 1, which are intentionally outside the activation-failure series. - Repeated failures for the same
conversation_idwith differentround_idvalues.
Insight 3: Provider Configuration Health
Type: Funnel
Steps:
provider_config_startedprovider_config_succeeded
Breakdowns:
provider_modestep
Companion trend:
- Event:
provider_config_failed - Breakdown:
error_code
Watch for:
- Official provider failures greater than zero for more than 15 minutes.
step = manual_chat_pingfailures after auto validation succeeds.
Insight 4: Model List Health
Type: Trends
Events:
model_list_loadedmodel_list_failed
Breakdowns:
provider_idprovider_mode
Watch for:
model_list_failedspikes for one provider.- High failure rate after a release.
Insight 5: TTS Voice Selection
Type: Trends
Events:
voice_selectedvoice_preview_playedvoice_pack_boundofficial_tts_exposedofficial_tts_preview_startedofficial_tts_preview_succeededofficial_tts_auto_enabled
Breakdowns:
voice_typetts_provider_idsource
Do not use:
- Prometheus labels for
voice_idorvoice_pack_id.
Use PostHog or SQL when grouping by:
voice_idvoice_pack_id
Watch for:
- Users see official TTS but do not preview it.
- Official TTS preview succeeds but chat auto TTS is not triggered later.
Insight 6: Voice Input Friction
Type: Funnel
Steps:
voice_input_startedstt_succeeded
Companion trends:
microphone_permission_deniedaudio_device_unavailablevoice_input_cancelledstt_failed
Breakdowns:
stt_provider_iderror_codeapp_surface
Insight 7: Feedback And Bug Reports
Type: Trends
Events:
feedback_submittedbug_report_submitted
Breakdowns:
categoryseverityentrypointapp_surface
Watch for:
severity = blockerspikes.entrypoint = about_update_errorafter desktop releases.
Grafana Dashboard
Source of truth:
apps/server/otel/grafana/dashboards/build.ts- Generated JSON:
apps/server/otel/grafana/dashboards/airi-server-overview-cloud.json
The Product Analytics row includes:
Product Events (range)Product Failure %TTS Success %TTS Failed / Blocked (range)TTS Blocked by ReasonTTS Blocked by Flux BucketTop Product Actions (range)Product Event RateTTS Event Rate by Source
Live import status:
- Imported on 2026-06-30.
- Live URL:
https://projairi.grafana.net/d/ad8qbp5/airi-server-overview - Dashboard:
AIRI Server Overview - Product Analytics(ad8qbp5) - The live dashboard now shows the full
Product Analyticsrow:Product Events (range)Product Failure %TTS Success %TTS Failed / Blocked (range)TTS Blocked by ReasonTTS Blocked by Flux BucketTop Product Actions (range)Product Event RateTTS Event Rate by Source
- The generated JSON remains the source of truth for the Product Analytics / TTS panel set.
Permission notes from the import retry:
- The first import attempt with title
AIRI Server Overviewand UIDrbr55dnshowed duplicate title / UID warnings because it targets the existing dashboard. - A second import attempt with a new title / UID (
AIRI Server Overview - Product Analytics Test,airi-product-analytics-test) removed the duplicate warnings, but still did not import. - API confirmation returned
403 Access denied:You'll need additional permissions to perform this action. Permissions needed: any of dashboards:create, dashboards:write. - The logged-in Grafana user
1260907335@qq.comhas org roleViewer; API metadata for/d/rbr55dn/airi-server-overviewreportscanSave=false,canEdit=false,canAdmin=false. - After permissions were updated, the generated dashboard was imported from Microsoft Edge. Grafana assigned the imported dashboard UID
ad8qbp5instead of overwriting the earlierrbr55dndashboard, so the imported dashboard was renamed toAIRI Server Overview - Product Analyticsto avoid ambiguity. - On 2026-07-01, the live
ad8qbp5dashboard was updated to includeTTS Blocked by ReasonandTTS Blocked by Flux Bucket. The live dashboard uses panel id105for the Flux bucket panel because id103was already occupied by the importedUser Engagementrow.
Regenerate after dashboard changes:
node node_modules/tsx/dist/cli.mjs apps/server/otel/grafana/dashboards/build.ts
Alert Setup
PostHog Alerts
Configure these as insight subscriptions or monitor-style alerts.
| Alert | Insight | Trigger |
|---|---|---|
| Activation drop | Chat Activation Funnel | chat_activation_succeeded / chat_activation_started drops by 15% vs previous 24h |
| Provider config regression | Provider Configuration Health | Official provider provider_config_failed is greater than 0 for 15 minutes |
| Voice input spike | Voice Input Friction | stt_failed / voice_input_started exceeds 20% over 1h |
| Feedback spike | Feedback And Bug Reports | bug_report_submitted doubles vs previous 24h |
Grafana Alerts
Use these PromQL expressions from the server dashboard context.
TTS success below 95% over 15 minutes:
100 * sum(increase(airi_product_events_total{feature="tts", action="speech_succeeded", status="succeeded"}[15m]))
/
clamp_min(sum(increase(airi_product_events_total{feature="tts", action="speech_requested", status="started"}[15m])), 1)
< 95
TTS blocked spike over 15 minutes:
sum(increase(airi_product_events_total{feature="tts", action="speech_blocked", status="blocked"}[15m])) > 10
TTS failed spike over 15 minutes:
sum(increase(airi_product_events_total{feature="tts", action="speech_failed", status="failed"}[15m])) > 5
Product failure ratio above 10% over 15 minutes:
100 * sum(increase(airi_product_events_total{feature!="", action!="", status="failed"}[15m]))
/
clamp_min(sum(increase(airi_product_events_total{feature!="", action!=""}[15m])), 1)
> 10
Verification Checklist
- PostHog can show
chat_activation_started -> chat_activation_succeeded -> second_turn_startedbyprovider_mode. - PostHog can show
official_provider_selectedbyprovider_id,source, andauto_selected. - PostHog can show
voice_selectedbyvoice_typeandtts_provider_id. - PostHog can show official TTS exposure / preview / auto-enabled events.
- PostHog can show
paywall_seenbyflux_balance_bucket. - PostHog can show
feedback_submittedandbug_report_submitted. - Grafana dashboard JSON contains
TTS Success %,TTS Failed / Blocked (range),TTS Blocked by Reason,TTS Blocked by Flux Bucket, andTTS Event Rate by Source. - Grafana product analytics panels use only bounded labels:
feature,action,status,source,reason,flux_balance_bucket.