1 Commits
Author SHA1 Message Date
sneak 948f3133ce Name Sentry transactions after the route they matched (closes #185)
check / check (push) Failing after 4m15s
sentryhttp names each transaction after the concrete path, which the
BeforeSendTransaction hook has to withhold, so with tracing on every
transaction would land in one Sentry group, POST /(redacted). A
middleware installed beside every sentryhttp handler now renames the
transaction to the method and chi route pattern once the request is
routed, and sets its source to route. The hook keeps a route-sourced
name and withholds every other name as before, so a request that
matched no route still reads POST /(redacted). Tracing stays off.

Model: opus-5-5
2026-10-12 23:16:12 +00:00
2 changed files with 13 additions and 24 deletions

No files matched your search

-7
View File
@@ -941,13 +941,6 @@ with an error naming it: for `webhooker.db` the server and `webhooker resetpw`
stop, and an event or archive database fails as a damaged one does (see stop, and an event or archive database fails as a damaged one does (see
[Database Architecture](#database-architecture)). [Database Architecture](#database-architecture)).
**`DATA_DIR` must be on a local filesystem.** Under WAL, SQLite maps each
database's `-shm` file into memory, which network filesystems (NFS, SMB/CIFS) do
not support reliably, so they are not supported. webhooker does not check which
filesystem `DATA_DIR` is on. An error reading `disk I/O error (522)`
(`SQLITE_IOERR_SHORT_READ`) points at the storage under `DATA_DIR`, not at
locking; moving `DATA_DIR` to a plain local disk is the first thing to try.
Configuration is **not** in `DATA_DIR` — it comes from the environment and from Configuration is **not** in `DATA_DIR` — it comes from the environment and from
a `.env` file read out of the process working directory. Back that up with your a `.env` file read out of the process working directory. Back that up with your
deployment config, separately. deployment config, separately.
+13 -17
View File
@@ -1,7 +1,6 @@
package server package server
import ( import (
"context"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@@ -158,25 +157,17 @@ func sentryRoutePattern(hint *sentry.EventHint) string {
// It has to run inside the sentryhttp handler, where the transaction // It has to run inside the sentryhttp handler, where the transaction
// is on the request context. It renames on the way out, once chi has // is on the request context. It renames on the way out, once chi has
// routed the request, and does so in a defer so that a request whose // routed the request, and does so in a defer so that a request whose
// handler panics is named too. The context is taken when the defer is // handler panics is named too. A request that matched no route has no
// set up, before routing, but the chi routing context on it is a // pattern; its name is left as the SDK set it, for
// pointer that chi fills in as it routes. // scrubSentryRequest to withhold.
func nameSentryTransaction(next http.Handler) http.Handler { func nameSentryTransaction(next http.Handler) http.Handler {
return http.HandlerFunc( return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) { func(w http.ResponseWriter, r *http.Request) {
defer setSentryTransactionName(r.Context(), r.Method) defer func() {
transaction := sentry.TransactionFromContext(
next.ServeHTTP(w, r) r.Context(),
},
) )
} rctx := chi.RouteContext(r.Context())
// setSentryTransactionName does the rename for nameSentryTransaction.
// A request that matched no route has no pattern; its name is left as
// the SDK set it, for scrubSentryRequest to withhold.
func setSentryTransactionName(ctx context.Context, method string) {
transaction := sentry.TransactionFromContext(ctx)
rctx := chi.RouteContext(ctx)
if transaction == nil || rctx == nil { if transaction == nil || rctx == nil {
return return
@@ -187,8 +178,13 @@ func setSentryTransactionName(ctx context.Context, method string) {
return return
} }
transaction.Name = method + " " + pattern transaction.Name = r.Method + " " + pattern
transaction.Source = sentry.SourceRoute transaction.Source = sentry.SourceRoute
}()
next.ServeHTTP(w, r)
},
)
} }
// sentryRouteURL rebuilds an event's request URL with the route // sentryRouteURL rebuilds an event's request URL with the route