Draft

Observability & Logging

How Propel monitors infrastructure — uptime, metrics, logs, traces — and the data-privacy guarantees that make it safe across many client accounts. Serves two audiences: internal (how we build and cost it) and client-facing (where your data lives and how it's protected).

How it works

Separate the control plane from the data plane. Your telemetry stays in your account (native services or cheap OSS on S3); Propel runs only a thin pane that queries in place and stores nothing. That keeps our cost flat as clients are added and means client data never has to live with us.

flowchart LR
    subgraph C["Your AWS account — data + cost live here"]
        APP[Your apps] --> OTEL[OpenTelemetry
Collector] OTEL --> MET[Metrics
CloudWatch / AMP] OTEL --> LOG[Logs
CloudWatch Logs] OTEL --> TRC[Traces
X-Ray / Tempo] end subgraph P["Propel control plane — stores nothing"] GRAF[Grafana
one org / workspace per client] UPTIME[Uptime Kuma
+ status pages] end MET -.query in place.-> GRAF LOG -.query in place.-> GRAF TRC -.query in place.-> GRAF GRAF --> ALERT[Alerts → Slack / PagerDuty] UPTIME --> ALERT
  • Instrument on OpenTelemetry, not a vendor SDK — so the backend can change (CloudWatch today, self-hosted or a client's Datadog tomorrow) without touching app code.
  • "Query-in-place, stores nothing" is real. Grafana assumes a cross-account read role and calls CloudWatch APIs live (GetMetricData; Logs Insights). A "last 30 days" panel queries the client account on demand — the window is bounded by the client's log retention. Grafana's DB holds only dashboards/config/alert rules, never the data. Caveats: keep query caching off; alert history may hold small value snippets; logs must live in CloudWatch (S3-only → query via Athena); Logs Insights is slower/pricier at volume (see OpenObserve below).

What we collect

Signal Tool (cheap default) Where it runs Cost
Uptime + status pages Uptime Kuma (OSS) Propel pane Free
Metrics CloudWatch → Amazon Managed Prometheus at scale Client account CW $0.30/custom metric; AMP ~$0.90/10M samples
Logs CloudWatch Logs, queried in place Client account $0.50/GB ingest; $0.005/GB scanned
Traces OTel → X-Ray (or Tempo-on-S3) Client account pennies
Dashboards + alerting Grafana, one org/workspace per client Propel pane see below

No central log store by default — centralizing telemetry is where residency breaks and ingestion + storage costs appear. OpenObserve enters only if CloudWatch Logs gets too slow/expensive: it's a cheap, S3-backed log/trace store you run in the client's account and point Grafana at — a backend under the same pane, not a second UI.

Platform & cost

The pane (dashboards/alerting) is the only thing Propel pays for; telemetry storage is client-side in every option.

Option Cost model Isolation Ops Verdict
Amazon Managed Grafana $9/editor + $5/viewer (active users) + query costs Workspace-per-customer = hard Zero — AWS-run, HA, private SSO built in Recommended. Customers log in to their own workspace; seat cost is billable
Grafana OSS — self-hosted ~$175–295/mo infra (HA ECS + RDS + LB + private networking) + maintenance Unlimited orgs (no per-seat) You run it (~2–4 hrs/mo) + build ingress/SSO Only wins past ~20+ customers
Grafana Cloud — Free $0 (3-user cap) Shared Zero Fine for a 1–2 client pilot

Why AMG's realistic total beats self-hosted: a client-facing self-hosted pane isn't a $15 box — it needs HA (2–3 Fargate tasks), a real RDS Postgres, a load balancer, and private networking (NAT/VPC endpoints) ≈ $175–295/mo infra, plus a maintenance tax (~$200–500/mo) and one-time build of ingress + SSO. AMG has none of that.

TCO at 10 customers × 3 viewers + Propel staff (query costs ~$50/mo either way; maintenance at $100/loaded hr):

Self-hosted Grafana OSS Amazon Managed Grafana
Infra + ingress + SSO ~$175–295 (build & run) $0 (built in)
Customer seats (30) $0 30 × $5 = $150 (billable to customers)
Staff seats $0 ~$80–270
Maintenance ~$200–500 $0
Propel net / mo ≈ $425–845 ≈ $130–370 (after billing the ~$150 through)

Recommendation: Amazon Managed Grafana, one workspace per customer. Cheaper and far less work at our scale; AWS handles HA, private login, and patching; the customer seat is billable. Revisit self-hosted only past ~20 customers or for multi-cloud beyond AMG's data sources. Keep staff oversight in a central cross-account view (avoids the per-workspace staff-seat multiplier); run Uptime Kuma for status pages regardless (free, no seats).

Customer login & data isolation

Customers can log in, see only their own data, and the seat is billable — this is the clean answer to private access + multi-tenancy:

  • Private SSO, built in. AMG authenticates via IAM Identity Center / SAML — AWS hosts the MFA-capable login. No Cloudflare/ALB/VPN to build.
  • Hard isolation: one workspace per customer — each is a separate Grafana with only that customer's users and a data source scoped to only their account. No path to another tenant's data.
  • Billable seat: treat the $5/viewer as a pass-through and mark it up in the customer's fee.
  • Staff-seat gotcha: a user active in N workspaces is billed N times → keep staff oversight central, use per-customer workspaces mainly for customer self-service.
  • Hooking into accounts: a read-only cross-account IAM role per client (sts:AssumeRole + unique ExternalId, no static keys), provisioned via the client's landing zone, separate from the deploy role.

(Self-hosted alternative if you outgrow AMG: Grafana one-org-per-client behind Cloudflare Access / oauth2-proxy, OIDC role-mapping to scope each client to their org — but you build and run that ingress yourself.)

Log privacy & PII

Effective operations needs logs — but that never requires hosting your logs with us. Retention lives where the logs are; access is federated and controlled.

Pick a log-privacy tier:

Tier What Propel can do with logs For the client who…
0 — Metrics only Never sees log content; log access only via break-glass assume-role, time-boxed + alerted in your CloudTrail is strictest / regulated (PHI)
1 — Query-in-place (default) Queries logs live; results transient, nothing stored our side; every access in your CloudTrail wants us operating, not hosting
2 — Centralized (opt-in) Logs shipped to a shared store for richer search/retention explicitly consents

PII scrubbing — layered, earliest-possible: ① app discipline (never log PII); ② scrub at the OTel Collector (redaction/transform masks/hashes before storage — free, primary control); ③ CloudWatch Logs data-protection masks PII at ingestion, unmask needs an IAM permission our read role lacks; ④ logs encrypted with your KMS key, deep dives are break-glass.

The guarantee: Your telemetry stays in your account under your KMS key; we log in through your MFA-gated SSO, reach your data only via a scoped role you granted with PII already scrubbed, and you can see and revoke everything we do.


Underpins the monitoring in every engagement scenario. Internal delivery standards: Engineering Operating Model.