Monitoring Setup: operations/plans/monitoring-setup-plan.md and
operations/monitoring/monitoring-instructions.md, covering Sentry alert
rules on the security_event tag, UptimeRobot's 6 liveness monitors, and
the two new Umami website entries for the admin SPA.
deployment-instructions.md gains a missing Observability__Environment
host var (without it, both environments would tag Sentry events as
"Production"), the nginx client_max_body_size fix for the 413 seen on
publish-test/production artifact uploads, and two troubleshooting notes
on Gitea Actions re-run behaviour: re-running deploy-test/production
alone loses the run's uploaded artifact, and re-running all jobs on an
existing (rather than a brand new) run can replay stale secrets.
deploy-scp.yaml: step names no longer show literal unresolved
${{ inputs.* }} text (Gitea doesn't interpolate that context in step
names), and a temporary debug step logs PI_MAIN_USERNAME/PASSWORD
length plus a username equality check to diagnose a persistent
Permission denied during the SSH steps, without ever logging the
secret values themselves.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015FffvxxJp5wG34Ru48GBig
6.5 KiB
Monitoring Setup Plan
Context already established (not re-asked)
The observability stack and what it must cover were already decided in Requirements Analysis and built during Construction (U4) — this stage is about configuring the real external services and writing the operational documentation, not re-deciding the approach:
- Stack: Sentry (backend
Sentry.AspNetCore+ frontend@sentry/react), self-hosted Umami analytics, UptimeRobot uptime monitoring (D-18, D-24, requirements.md § "Monitoring and observability") - Sentry projects: one project for the whole CMS,
environmenttag distinguishes test/production (D-19) — so one DSN, reused by both environments and both frontend/backend - Sentry is optional by design: an absent DSN disables it cleanly, console logging stays active (BR-U4-08) — nothing breaks if a value is left blank temporarily
- Alertable events already exist in code: six
security_eventtag values are emitted today —failed_login,authorization_denied,master_api_key_rejected,admin_bypass_rejected,rate_limit_triggered,migration_failure(SecurityEvents.cs). Alert rules must filter on thesecurity_eventtag, not message text (nfr-design-patterns.mdPattern 6) — this is explicitly named as Operations — Monitoring Setup work inlogical-components.md(FR-19) - UptimeRobot scope:
/health,/(public website) and/admin, per environment — 6 monitors total (D-23) - Umami scope: reuse the existing self-hosted instance at
analytics.slpsoftware.nl, add new website entries for this CMS rather than standing up a new instance (D-24/ASM-05). Both the admin SPA (viaVITE_UMAMI_WEBSITE_ID_<ENV>, built by this pipeline) and the public website (via the separate website-workspace, FR-09/FR-16, out of this pipeline's scope) are measured (D-25) — this stage only configures the admin SPA's two website entries; the public website's Umami wiring belongs to whichever website workspace serves it - Health endpoint: liveness only, no DB check, already built and already on the
AvailabilityMiddlewarebypass list (D-21) — nothing left to build, only to point UptimeRobot at - Log retention deviation: accepted knowingly (DEV-01) — Sentry's ~30-day retention against the 90-day SECURITY-14 minimum. No action here beyond documenting it.
Question 1: Include Monitoring Setup?
Given U4 built all the alertable-event plumbing specifically so that Operations could wire up real
alert rules and monitors on top of it, declining this stage would leave that code inert — events
would be emitted into a Sentry project that doesn't exist yet, with no alert rule reading the tag,
and no UptimeRobot monitor watching /health. Recommended: A.
A) Yes — configure the real services and document it (Recommended) B) No — monitoring is handled elsewhere or not needed C) Not sure — suggest an approach and I'll decide
X) Other (please describe after Answer: tag below)
Question 2: Monitoring Method
Confirms the stack already decided in Requirements Analysis — asked per the mandatory format, not because it's genuinely open.
A) Sentry + self-hosted Umami + UptimeRobot, exactly as scoped above (Recommended) B) Something else entirely — describe below
X) Other (please describe after Answer: tag below)
The remaining questions are the genuinely open items — real account/service facts that only you know, which nothing in Construction could decide for you.
Question 3: Sentry Project
Does a Sentry project for this CMS already exist (e.g. created ad hoc while testing U4 locally), or does this stage need to walk through creating one from scratch?
A) Already exists — I'll provide the DSN after Answer: below B) Doesn't exist yet — walk me through creating one (org, project platform picks for .NET + React, where to find the DSN afterward) C) Not yet, and I'd rather set it up myself later — document it as a TODO with exactly which Gitea secrets/variables need the DSN once it exists
X) Other (please describe after Answer: tag below)
Answer:A — DSN to be added directly to the Gitea secret/variable once shared (kept out of this doc)
Question 4: Sentry Alert Rule Thresholds
FR-19 requires alert rules for repeated auth failures and authorization violations, filtering on the
security_event tag (values: failed_login, authorization_denied, master_api_key_rejected,
admin_bypass_rejected, rate_limit_triggered; migration_failure is Critical-level and worth
its own always-fire rule regardless of count). What threshold should the repeated-failure rules use?
A) A single reasonable default for all of them (e.g. 20 occurrences in 5 minutes) — document it as a starting point, tune later from real traffic (Recommended) B) I'll specify exact thresholds per event type — describe below C) No count threshold — alert on every occurrence of each of the six (noisier, but nothing is ever missed)
X) Other (please describe after Answer: tag below)
Question 5: UptimeRobot Account and Alert Contacts
6 monitors are needed (/health, /, /admin × test/production). Do you have an UptimeRobot
account already (e.g. from the reference SlpSoftware project), and where should alerts go?
A) Existing account, reuse it — alert contact(s): describe after Answer: below (email, and/or any other channel already configured there) B) Need a new account/monitor group set up from scratch — walk me through it C) Not sure yet — document the 6 monitors' exact URLs and recommended check interval as a checklist, I'll create them myself
X) Other (please describe after Answer: tag below)
Answer:A — existing account, alert contact to be confirmed
Question 6: Umami Website Entries (Admin SPA)
Two new website entries are needed on the existing analytics.slpsoftware.nl instance — one per
environment — to obtain the VITE_UMAMI_WEBSITE_ID_TEST/_PRODUCTION values the CI workflow already
expects as Gitea variables (continuous_integration.yaml reads vars.VITE_UMAMI_WEBSITE_ID_TEST/
_PRODUCTION).
A) I have access to the Umami instance — I'll create the two entries and provide the website IDs after Answer: below B) Walk me through creating them (Umami's own UI/API steps) C) Not yet — document it as a TODO with the exact variable names the pipeline expects, I'll fill them in before the first real deploy
X) Other (please describe after Answer: tag below)
Answer:A — website IDs to be added directly to Gitea variables once created (kept out of this doc)