Dashboards
Objectuve uses three dashboard surfaces: GCP Cloud Monitoring for infrastructure metrics, Sentry for application-level error and performance visibility, and PostHog for product analytics (user behavior, feature adoption, funnel/retention metrics).
GCP Cloud Monitoring Dashboard
Creating the Dashboard
A dashboard definition can be stored at infra/monitoring/dashboard.json and applied via:
gcloud monitoring dashboards create \
--config-from-file=infra/monitoring/dashboard.json \
--project=YOUR_PROJECTRecommended Panels
| Panel | Metric | Description |
|---|---|---|
| Request Rate | run.googleapis.com/request_count | Requests per second to the API |
| Latency p50/p95/p99 | run.googleapis.com/request_latencies | Request duration percentiles |
| Error Rate | run.googleapis.com/request_count (filtered by 4xx/5xx) | Percentage of failed requests |
| Instance Count | run.googleapis.com/container/instance_count | Active Cloud Run instances |
| DB Connections | cloudsql.googleapis.com/database/postgresql/num_backends | Active PostgreSQL connections |
| DB CPU | cloudsql.googleapis.com/database/cpu/utilization | Database CPU utilization |
| DB Memory | cloudsql.googleapis.com/database/memory/utilization | Database memory utilization |
| DB Disk | cloudsql.googleapis.com/database/disk/utilization | Database disk utilization |
| Uptime Status | monitoring.googleapis.com/uptime_check/check_passed | Health check pass/fail |
Accessing the Dashboard
- Production: GCP Console > Monitoring > Dashboards > "Objectuve Production"
- Staging: GCP Console > Monitoring > Dashboards > "Objectuve Staging"
Not yet on this dashboard
Two Cloud Monitoring alert policies page on conditions with no dedicated panel above — they're detection-only for now, not (yet) visualized here: Cloud Run startup-probe failure rate and Cloud SQL connection saturation. See docs/operations/alerting.md § GCP Cloud Monitoring Alerts for both alerts' definitions, thresholds, and verification commands.
Cloud Monitoring alignment and falsifiable zero-activity checks
Any "N hours of zero X" acceptance criterion checked against a Cloud Monitoring metric must name its alignmentPeriod and perSeriesAligner in the AC text itself, or it isn't falsifiable — a wide ALIGN_MAX bucket can misread routine sub-minute activity as a continuous nonzero signal (see the ALIGN_MAX measurement-trap gotcha). Worked example — OBJ-3429's revised AC3: "objectuve_staging on enkidu-postgres shows zero application backends for a full 24h ... sampled at alignmentPeriod=60s with perSeriesAligner=ALIGN_MEAN and no cross-series reducer ... ALIGN_MAX over any bucket wider than 60s is explicitly disallowed for this check."
Sentry Dashboards
Error Monitoring
Sentry's default Issues view provides:
- Error trends over time
- Most frequent issues
- New vs. regressed issues
- Error count by release
Access: Sentry > Issues
Performance Monitoring
Sentry's Performance view provides:
- Transaction duration trends
- Slowest transactions
- Web vitals (frontend)
- Database query spans
Access: Sentry > Performance
Recommended Custom Dashboard Widgets
Create a custom dashboard in Sentry (Dashboards > Create Dashboard) with:
- Error count by environment — Track staging vs production error rates
- Top 5 slowest transactions — Identify performance bottlenecks
- Web vitals over time — Track frontend performance trends
- Error count by GraphQL operation — Identify problematic mutations/queries
PostHog Product Analytics
Server-side product-analytics events, added in v4.6 Phase 1 (Analytics Instrumentation, OBJ-1507) to validate the success metrics defined across docs/product/roadmap.md Phases 2–6. All events are captured via the existing PosthogNotifier.capture wrapper (rails_api/app/services/posthog_notifier.rb), keyed by distinct_id: user.public_id, with no PII beyond public_id in any event property. This is a foundation phase — no new telemetry stack, no user-facing surface.
Full gap-audit of every roadmap Phase 2–6 success metric (covered / instrumented / deferred, with evidence) lives at .planning/phases/v4.6-phase-1-analytics-instrumentation/GAP-AUDIT.md — treat it as the source of truth for what's covered and what's genuinely still a gap; this page documents only what's live today. For an example of a fuller PostHog event taxonomy + manual-setup runbook on a different feature, see docs/operations/critical-path-analytics.md.
Event Taxonomy
| Event | Fired by | Properties | Roadmap metric it answers |
|---|---|---|---|
goal_created | GoalTracking::AddGoal | surface: 'goal_tracking', goal_id, goal_type, is_first_goal, from_template | Item 29b: 30%+ of new goals are template-derived |
habit_checked_in | GoalTracking::CheckInHabit | surface: 'goal_tracking', goal_id, habit_completion_id, new_streak, has_note | Item 24: 25%+ of check-ins include a journal note |
community_joined | Social::JoinCommunity | surface: 'social', community_id, community_member_id, is_first_community | Item 41: community discovery join-volume baseline |
feature_used | UserIdentity::UpdatePrivacySettings (reference implementation — future flagged mutations should emit this same event shape) | surface: 'user_identity', feature: 'privacy_controls_v1', go_it_alone, private_mode | Item 29: 10–15% "go it alone" adoption |
Notes
goal_createdskips milestone/template child rows —AddGoal#track_goal_createdreturns early whengoal.parent_goal_id.present?, so template-derived milestone rows don't inflate top-level goal-creation counts.is_first_communityis snapshotted before the DB write —JoinCommunity#first_community?is evaluated beforeCommunityMember.create!, not after, so the property reflects genuine first-join state (fixed during PR #1596 review; the pre-fix version always readfalse). Known follow-up nit: on the admin-joins-another-user path,first_community?still reads the acting admin's membership count rather than the target user's — narrow edge case, not fixed as of this PR.PosthogNotifier.capturedefaults every event'ssurfaceproperty to'admin', but each caller above passes its ownsurface:inproperties, andHash#mergelets the caller's value win — confirmed intentional, not a bug.- All four events are new as of PR #1596; nothing here retroactively backfills historical data.
Dashboard: "Phase 1 — Core Engagement"
Recommended PostHog Dashboard, one Trend Insight per event above:
| Insight | Event | Breakdown | Answers |
|---|---|---|---|
| Goals created | goal_created | goal_type, from_template | Item 29b template-derived %, general creation volume |
| Habit check-ins | habit_checked_in | has_note | Item 24's 25%+ journal-note metric |
| Communities joined | community_joined | is_first_community | Item 41 baseline join volume |
| Flagged-feature usage | feature_used | feature | Item 29's go-it-alone/private-mode adoption; extend as future mutations adopt the feature_used pattern |
Status: spec only, not yet created. Building it is a one-time PostHog setup task (Insights + Dashboard, project 368400) — no repo code. As of 2026-07-20 this is no longer credential-blocked: the Multica agent Codi holds a PostHog key with the Insight and Dashboard write scopes needed to create it (see Feature Flags § Credential gotchas for the exact scopes). Unblocked is not the same as done — the dashboard still needs to actually be built from the table above. Once built, link the live dashboard URL here.
Weekly Metrics Review
| Cadence | Weekly |
| Owner | Whoever holds PostHog project access — a crew agent with Insight/Dashboard write scope, or the workspace owner |
| Location | PostHog "Phase 1 — Core Engagement" dashboard (see above); findings posted as a comment on the relevant Multica issue so they're visible to the crew |
Process:
- Open the "Phase 1 — Core Engagement" dashboard and read each Insight's week-over-week trend.
- Compare against the roadmap item's numeric target (e.g. item 24's 25%+ journal-note rate, item 29's 10–15% "go it alone" adoption).
- Cross-check
GAP-AUDIT.md's deferred bucket — as new events land (e.g. adiscovery_sourceproperty oncommunity_joined, or instrumentation for a newly-shipped Phase 2–6 feature), tick the corresponding metric from ⏸ DEFERRED to ✅/🆕 and update that document. - File a Multica issue for any metric trending materially off its roadmap target, tagged to the owning roadmap phase.
Updating the Dashboard
To update the GCP dashboard definition:
- Make changes in
infra/monitoring/dashboard.json - Delete the existing dashboard:
gcloud monitoring dashboards delete DASHBOARD_ID - Recreate:
gcloud monitoring dashboards create --config-from-file=infra/monitoring/dashboard.json
Or edit directly in the GCP Console UI and export the JSON for version control.
Last updated: 2026-09-13 (OBJ-3515: added the Cloud Monitoring alignment / falsifiable zero-activity-check rule)
Previously (2026-09-08): OBJ-3167 Task 3 — cross-referenced the Cloud Run startup-probe and Cloud SQL connection-saturation alerts, which page without a dedicated dashboard panel
Previously (2026-07-20): Codi PostHog credential fix — Core Engagement dashboard no longer credential-blocked