logging

package
v0.1.16 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TraceBodyEnvVar = "APPXIMO_TRACE_BODY"
	TraceBodyMax    = 4 << 10
)

TraceBodyEnvVar opts request BODIES into persisted error traces. Off by default: a body can carry passwords, tokens or personal data — the trade-off is written in docs/BACKEND_SPEC_LLM.md §3.9. When on, at most TraceBodyMax bytes are kept and sensitive JSON fields are redacted before persistence.

Variables

View Source
var ClaimsExtractor func(ctx context.Context) (userID, role string)

ClaimsExtractor reads (user_id, role) off a request context. Set by the app at boot (auth.ClaimsFromCtx) — logging cannot import auth without a cycle.

Log is the package-level structured logger. Call Init before using.

Functions

func FromCtx added in v0.1.16

func FromCtx(ctx context.Context) *zerolog.Logger

FromCtx returns the request-scoped logger (carries trace_id). Falls back to the global logger outside a request.

func Init

func Init(env string)

Init configures the global logger for the given environment. All output passes through RedactWriter to strip sensitive field values.

func RedactBody added in v0.1.16

func RedactBody(b []byte) string

RedactBody replaces the values of sensitive JSON keys and caps the length.

func RequestLogger

func RequestLogger(
	record func(tenantID string, durationUs int64, fromCache bool),
	observe func(tenantID string, us float64),
	tap func(RequestTap),
) func(http.Handler) http.Handler

RequestLogger returns a chi-compatible middleware that logs each request with zerolog. The Authorization header is intentionally NOT logged — only method, path, status, duration, tenant_id, and request_id are recorded. record receives duration in microseconds and a fromCache flag (true = served from the response cache, detected via the X-Cache: HIT header set by the cache middleware). observe receives duration in microseconds as float64. tap receives a fully-populated RequestTap. All three callbacks are optional (nil-safe).

func SetDefaultWriter added in v0.1.4

func SetDefaultWriter(w io.Writer)

SetDefaultWriter redirects where subsequent Init calls send log output. Call it before the engine boots (appximo.New re-runs Init).

Types

type PGXQueryTracer

type PGXQueryTracer struct{}

PGXQueryTracer implements pgx.QueryTracer and logs SQL statements at DEBUG level WITHOUT their bound parameter values ($1, $2, …) to prevent accidental exfiltration of PII or sensitive data into structured logs.

func (PGXQueryTracer) TraceQueryEnd

func (PGXQueryTracer) TraceQueryEnd(_ context.Context, _ *pgx.Conn, data pgx.TraceQueryEndData)

TraceQueryEnd is called after a query completes or fails.

func (PGXQueryTracer) TraceQueryStart

func (PGXQueryTracer) TraceQueryStart(ctx context.Context, _ *pgx.Conn, data pgx.TraceQueryStartData) context.Context

TraceQueryStart is called before a query executes. Only the SQL template is logged — args are intentionally omitted.

type RedactWriter

type RedactWriter struct {
	// contains filtered or unexported fields
}

RedactWriter wraps an io.Writer and scrubs sensitive JSON field values before they reach the underlying writer. Applied to every structured log line.

func NewRedactWriter

func NewRedactWriter(w io.Writer) RedactWriter

NewRedactWriter wraps w with sensitive-field redaction.

func (RedactWriter) Write

func (r RedactWriter) Write(p []byte) (int, error)

type RequestTap

type RequestTap struct {
	TenantID   string
	Method     string
	Path       string
	Route      string
	Status     int
	StartUS    int64 // request start, unix microseconds
	DurationUS int64
	FromCache  bool
	TraceID    string                      // 16-hex request trace id (also in X-Trace-ID)
	Spans      []observability.Span        // per-stage breakdown from the SpanTracker
	ErrMsg     string                      // error message for an errored request ("" otherwise)
	Capture    *observability.ErrorCapture // symbolized stack for a 500 (nil otherwise)
	IP         string                      // client IP (X-Real-IP / X-Forwarded-For / RemoteAddr)
	UserAgent  string                      // raw User-Agent header
	Headers    map[string]string           // filtered request headers (persisted traces only)
	FullURL    string                      // scheme://host/path?query (persisted traces only)
	// OBSERVABILIDAD-ERRORES-S1: who (from the JWT, populated for EVERY trace,
	// not only captured 500s), the failed statement the driver noted, and the
	// redacted request body when APPXIMO_TRACE_BODY is on.
	UserID string
	Role   string
	SQL    string
	Body   string
}

RequestTap carries the per-request facts a downstream consumer (Prometheus metrics, the per-tenant ring buffer) needs, so RequestLogger stays the single measurement point. Route is the chi route pattern (e.g. "/api/{entity}"), preferred over the raw Path for bounded metric/label cardinality.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL