Skip to content

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:

bash
gcloud monitoring dashboards create \
  --config-from-file=infra/monitoring/dashboard.json \
  --project=YOUR_PROJECT
PanelMetricDescription
Request Raterun.googleapis.com/request_countRequests per second to the API
Latency p50/p95/p99run.googleapis.com/request_latenciesRequest duration percentiles
Error Raterun.googleapis.com/request_count (filtered by 4xx/5xx)Percentage of failed requests
Instance Countrun.googleapis.com/container/instance_countActive Cloud Run instances
DB Connectionscloudsql.googleapis.com/database/postgresql/num_backendsActive PostgreSQL connections
DB CPUcloudsql.googleapis.com/database/cpu/utilizationDatabase CPU utilization
DB Memorycloudsql.googleapis.com/database/memory/utilizationDatabase memory utilization
DB Diskcloudsql.googleapis.com/database/disk/utilizationDatabase disk utilization
Uptime Statusmonitoring.googleapis.com/uptime_check/check_passedHealth 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

Create a custom dashboard in Sentry (Dashboards > Create Dashboard) with:

  1. Error count by environment — Track staging vs production error rates
  2. Top 5 slowest transactions — Identify performance bottlenecks
  3. Web vitals over time — Track frontend performance trends
  4. 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

EventFired byPropertiesRoadmap metric it answers
goal_createdGoalTracking::AddGoalsurface: 'goal_tracking', goal_id, goal_type, is_first_goal, from_templateItem 29b: 30%+ of new goals are template-derived
habit_checked_inGoalTracking::CheckInHabitsurface: 'goal_tracking', goal_id, habit_completion_id, new_streak, has_noteItem 24: 25%+ of check-ins include a journal note
community_joinedSocial::JoinCommunitysurface: 'social', community_id, community_member_id, is_first_communityItem 41: community discovery join-volume baseline
feature_usedUserIdentity::UpdatePrivacySettings (reference implementation — future flagged mutations should emit this same event shape)surface: 'user_identity', feature: 'privacy_controls_v1', go_it_alone, private_modeItem 29: 10–15% "go it alone" adoption

Notes

  • goal_created skips milestone/template child rowsAddGoal#track_goal_created returns early when goal.parent_goal_id.present?, so template-derived milestone rows don't inflate top-level goal-creation counts.
  • is_first_community is snapshotted before the DB writeJoinCommunity#first_community? is evaluated before CommunityMember.create!, not after, so the property reflects genuine first-join state (fixed during PR #1596 review; the pre-fix version always read false). 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.capture defaults every event's surface property to 'admin', but each caller above passes its own surface: in properties, and Hash#merge lets 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:

InsightEventBreakdownAnswers
Goals createdgoal_createdgoal_type, from_templateItem 29b template-derived %, general creation volume
Habit check-inshabit_checked_inhas_noteItem 24's 25%+ journal-note metric
Communities joinedcommunity_joinedis_first_communityItem 41 baseline join volume
Flagged-feature usagefeature_usedfeatureItem 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

CadenceWeekly
OwnerWhoever holds PostHog project access — a crew agent with Insight/Dashboard write scope, or the workspace owner
LocationPostHog "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:

  1. Open the "Phase 1 — Core Engagement" dashboard and read each Insight's week-over-week trend.
  2. 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).
  3. Cross-check GAP-AUDIT.md's deferred bucket — as new events land (e.g. a discovery_source property on community_joined, or instrumentation for a newly-shipped Phase 2–6 feature), tick the corresponding metric from ⏸ DEFERRED to ✅/🆕 and update that document.
  4. 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:

  1. Make changes in infra/monitoring/dashboard.json
  2. Delete the existing dashboard: gcloud monitoring dashboards delete DASHBOARD_ID
  3. 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

Loading…