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 21 additions and 32 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
[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
a `.env` file read out of the process working directory. Back that up with your
deployment config, separately.
+21 -25
View File
@@ -1,7 +1,6 @@
package server
import (
"context"
"net/http"
"net/url"
"strings"
@@ -158,39 +157,36 @@ func sentryRoutePattern(hint *sentry.EventHint) string {
// 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
// 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
// set up, before routing, but the chi routing context on it is a
// pointer that chi fills in as it routes.
// handler panics is named too. A request that matched no route has no
// pattern; its name is left as the SDK set it, for
// scrubSentryRequest to withhold.
func nameSentryTransaction(next http.Handler) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
defer setSentryTransactionName(r.Context(), r.Method)
defer func() {
transaction := sentry.TransactionFromContext(
r.Context(),
)
rctx := chi.RouteContext(r.Context())
if transaction == nil || rctx == nil {
return
}
pattern := rctx.RoutePattern()
if pattern == "" {
return
}
transaction.Name = r.Method + " " + pattern
transaction.Source = sentry.SourceRoute
}()
next.ServeHTTP(w, r)
},
)
}
// 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 {
return
}
pattern := rctx.RoutePattern()
if pattern == "" {
return
}
transaction.Name = method + " " + pattern
transaction.Source = sentry.SourceRoute
}
// sentryRouteURL rebuilds an event's request URL with the route
// pattern in place of the concrete path.
//