shared: auto-emit Langfuse trace+span per HTTP request — closes OPEN #2
Adds langfuseMiddleware in internal/shared so every daemon's shared.Run gets free production-traffic trace visibility when LANGFUSE_URL + LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY are set. Same env names + file shape as the multi_coord_stress driver, so operators ship one /etc/lakehouse/langfuse.env across the deploy. Wiring is auth-gated: middleware runs INSIDE the RequireAuth group, so 401s from credential-stuffing don't pollute traces. /health is exempt so LB probes don't either. Missing env vars → nil client → middleware is a passthrough no-op (fail-open per ADR-005 5.1). Bundled deploy: - langfuse.env.example template (mode 0640, root:lakehouse) - 11 systemd units gain `EnvironmentFile=-/etc/lakehouse/langfuse.env` (leading - so missing file = OK) - REPLICATION.md bootstrap section documents setup Tests (4): nil passthrough, /health bypass, real-request emission, status-writer wrapping. All green. STATE_OF_PLAY OPEN list: 5 rows → 4 rows. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -75,6 +75,18 @@ func Run(serviceName, addr string, register RegisterRoutes, auth AuthConfig) err
|
||||
Level: slog.LevelInfo,
|
||||
}))
|
||||
|
||||
// Optional Langfuse client from LANGFUSE_URL + LANGFUSE_PUBLIC_KEY
|
||||
// + LANGFUSE_SECRET_KEY env vars. Per OPEN item #2: every daemon
|
||||
// gets free production-traffic trace visibility when those env
|
||||
// vars are set. Missing any of the three → nil client → middleware
|
||||
// becomes a passthrough.
|
||||
lf := loadLangfuseFromEnv()
|
||||
if lf != nil {
|
||||
// Make sure pending events flush on graceful shutdown so the
|
||||
// last few requests' traces don't get lost.
|
||||
defer func() { _ = lf.Close() }()
|
||||
}
|
||||
|
||||
r := chi.NewRouter()
|
||||
r.Use(middleware.RequestID)
|
||||
r.Use(middleware.RealIP)
|
||||
@@ -95,8 +107,12 @@ func Run(serviceName, addr string, register RegisterRoutes, auth AuthConfig) err
|
||||
// Registered routes live inside an auth-gated group so
|
||||
// RequireAuth applies uniformly without per-handler wiring.
|
||||
// Empty auth → middleware is a no-op (group is transparent).
|
||||
// Langfuse middleware sits AFTER auth so we don't trace 401s
|
||||
// from credential-stuffing attempts (avoids polluting traces
|
||||
// with non-real-traffic).
|
||||
r.Group(func(authed chi.Router) {
|
||||
authed.Use(RequireAuth(auth))
|
||||
authed.Use(langfuseMiddleware(serviceName, lf))
|
||||
register(authed)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user