Sentry Improvements (WIP) - #4829
Conversation
NB. Requires new env vars
Fx collision with shared config
| # dsn = "" | ||
| # environment = "dev" |
There was a problem hiding this comment.
I assume these commented variables are ones you would want to set if enabling sentry. Is it worth adding a comment here explaining that, or will it be obvious to everyone?
There was a problem hiding this comment.
(Alternatively we could document that possibility in the readme maybe?)
| "lint": "eslint public/js && htmllint public/js/**/*.html", | ||
| "lint-fix": "eslint public/js --fix && htmllint public/js/**/*.html", | ||
| "dist": "webpack --config webpack.config.prod.js", | ||
| "sentry:upload-sourcemaps": "if [ -n \"$SENTRY_AUTH_TOKEN\" ] && [ -n \"$SENTRY_ORG\" ] && [ -n \"$SENTRY_PROJECT\" ] && [ -n \"$SENTRY_RELEASE\" ]; then npx -y @sentry/cli@2 releases new \"$SENTRY_RELEASE\" && npx -y @sentry/cli@2 releases files \"$SENTRY_RELEASE\" upload-sourcemaps public/dist --url-prefix '~/assets/dist' --validate && npx -y @sentry/cli@2 releases finalize \"$SENTRY_RELEASE\"; else echo 'Skipping Sentry sourcemap upload (missing Sentry env vars)'; fi", |
There was a problem hiding this comment.
Is it possible to conveniently spin this out into a separate script that we call from here? I know it’s not a very complex script, but it’d be nicer to edit if it weren’t inlined in a string like this.
There was a problem hiding this comment.
It’s cool to learn how this is done though! I took a look at these docs, which are hopefully the correct ones. A couple of other options are listed there, like creating deploys and setting commits: is it worth trying to do those as well? (Maybe in a later PR?)
| def init(config: CommonConfig): Unit = { | ||
| if (isEnabled(config)) { | ||
| Sentry.init((options: SentryOptions) => { | ||
| options.setDsn(config.sentryDsn.get) | ||
| options.setEnvironment(config.sentryEnvironment) | ||
| options.setServerName(config.appName) | ||
| options.setRelease(sys.env.getOrElse("BUILD_VCS_NUMBER", "unknown")) | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| def shutdown(config: CommonConfig): Future[Unit] = Future.successful { | ||
| if (isEnabled(config)) { | ||
| Sentry.close() | ||
| } | ||
| } |
There was a problem hiding this comment.
Is it definitely ok to use Future.successful here (and not use Futures at all for init)? It’s hard to see exactly what work Sentry.close() and Sentry.init() do, but it seems plausible that there might be blocking IO in there, so I’d wonder about erring on the side of caution and choosing to put the calls on a separate execution context.
Fix indent in sentry.js Make sure no chance of calling get on an empty value Remove unnecessary execution context (not transforming any futures)
…rontend and backend
…dian/grid into maintainance/sentry-updates
| <script> | ||
| window.SENTRY_RELEASE = { id: "@utils.buildinfo.BuildInfo.gitCommitId" }; | ||
| </script> | ||
|
|
There was a problem hiding this comment.
Alternatives to mutating this set as a config var?
| // (i.e. after the subclass constructor has completed). | ||
| private lazy val sentryInitialised: Unit = | ||
| SentrySupport.init(config, buildInfo.gitCommitId) | ||
|
|
There was a problem hiding this comment.
Follow up on this logic
What does this change?
Note: New env vars required for reporting - no failure if not present
For sourcemaps:
SENTRY_AUTH_TOKEN
SENTRY_ORG
SENTRY_PROJECT
SENTRY_RELEASE currently set to github.sha in ci.yml
For scala sentry coverage:
sentry.enabled
sentry.dsn
sentry.environment
are required in CommonConfig.scala / defaults in application.conf
Further deployment notes - NB the following is AI generated and needs to be edited / reviewed before we merge
Sentry Setup & Deployment Guide
This document describes the actions required to enable and deploy the Sentry error
monitoring added on the
maintainance/sentry-updatesbranch. It covers both thebackend (Scala/Play services) and the frontend (Kahuna browser app).
1. What this branch enables
BuildInfo.gitCommitId(baked in at build time)console.warn/console.errorwindow.SENTRY_RELEASE.id=BuildInfo.gitCommitIdBoth tiers are off by default (
sentry.enabled = false) and only activate whenexplicitly enabled and a DSN is provided.
2. One-time setup (Sentry + GitHub)
2.1 Create Sentry project(s)
frontend events — see note in §4.3).
2.2 Create a Sentry auth token
Create an internal integration / auth token with permissions to create releases
and upload files:
project:releasesproject:read2.3 Add GitHub Actions secrets
In the repository settings (Settings → Secrets and variables → Actions), add:
SENTRY_AUTH_TOKENSENTRY_ORGSENTRY_PROJECT3. Per-environment configuration (deploy targets)
Backend and frontend are both driven by the Play service configuration for each
service. The defaults live in
common-lib/src/main/resources/application.conf:To enable Sentry in a given environment, override these in that environment's config
(e.g. the deployed
application.conf/ config bucket for the stage):Config keys (from
CommonConfig)sentry.enabledfalsesentry.dsnenabled = truesentry.environmentSTAGEImportant behaviour
sentry.enabledgates both tiers. The frontend DSN is only rendered into thepage (
<link rel="sentry-dsn">inmain.scala.html) whensentry.enabledis true,so setting
enabled = falsereliably silences the browser app as well as the server.at build time from
BuildInfo.gitCommitId; the deployed process does not needSENTRY_RELEASEorBUILD_VCS_NUMBERset.4. Releases & sourcemaps (CI)
4.1 What CI does
The
Kahuna (client-side)step in.github/workflows/ci.ymlbuilds the productionbundle and uploads sourcemaps to Sentry:
The
sentry:upload-sourcemapsnpm script (inkahuna/package.json) uses the@sentry/clidev dependency to:releases new),public/distwith url-prefix~/assets/dist(--validate),releases finalize).The script is a no-op (prints a skip message) if any of the four
SENTRY_*env varsare missing, so forks / environments without Sentry secrets are unaffected.
4.2 The release-name consistency requirement
For uploaded sourcemaps to resolve against browser events, the release name used at
upload time must equal the release the app reports at runtime:
SENTRY_RELEASE=${{ github.sha }}window.SENTRY_RELEASE.id=BuildInfo.gitCommitIdgitCommitIdis resolved inbuild.sbtin this order:BUILD_VCS_NUMBER(TeamCity, deprecated — not set in GitHub Actions) →GITHUB_SHA(set by GitHub Actions, identical togithub.sha) →local
git rev-parse HEAD(dev only).Because CI runs on GitHub Actions,
GITHUB_SHAis used, which is the same value asthe
SENTRY_RELEASE: ${{ github.sha }}used for the sourcemap upload — so the runtimeand upload releases are guaranteed to match, including for PR merge-commit builds.
4.3 Note: Kahuna uses one DSN for both tiers
Kahuna's
sentry.dsnis used for both its server-sideSentrySupportand thebrowser app (via the rendered link tag). If you want frontend and backend events in
separate Sentry projects, that requires a code change (a distinct config key for
the browser DSN); the current design shares one DSN per service.
5. Deployment checklist
SENTRY_AUTH_TOKEN,SENTRY_ORG,SENTRY_PROJECTadded as GitHub Actions secrets.sentry.enabled = trueandsentry.dsn = "..."(and optionally
sentry.environment).6. Verification
confirm the event appears in Sentry with tags
app,stage,method,path,and
requestId.console.error('sentry test')in the browser console on Kahunaand confirm the event appears, with the correct
releaseand a de-minified stacktrace (proves sourcemaps resolved).
environmenttag matches the stage.7. Disabling / rollback
sentry.enabled = falsein the environment config and redeploy — this stopsboth backend and frontend reporting immediately. No code change or DSN removal
required.
--- End of AI text
How should a reviewer test this change?
How can success be measured?
Who should look at this?
Tested? Documented?