Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ContextHandler ¶
type ContextHandler struct {
// contains filtered or unexported fields
}
func NewHandler ¶
func NewHandler(internal slog.Handler) *ContextHandler
func (*ContextHandler) Handle ¶
Handle redacts protobuf attributes and records the active span on the log record.
Redaction: an attribute whose value is a proto.Message with a populated debug_redact field is replaced by a copy with those fields masked (see protoredact). The message may be the attribute's own value, a member of a group at any depth, or what a LogValuer resolves to; attributes bound with With are handled once by WithAttrs. Doing this here rather than at each call site means any slog call in a process that installs this handler is covered, not only the gRPC interceptor.
Not covered: a message reached only through a slice, map, or non-proto struct (slog.Any("env", []*EnvVar{...})), a message formatted into a string before the call (fmt.Sprintf("%v", msg)), a message packed inside google.protobuf.Any, and the OTLP copy of an actor event, which internal/actorevent builds from the attributes itself. Log such a value as a direct attribute instead.
Cost: the record is copied only when an attribute changes. A message that needs masking is one such change; a LogValuer is the other, since it is resolved here once and the record keeps the resolved value rather than having the terminal handler compute it again. A record with neither, which is nearly all of them, passes through after a scan that allocates nothing.
Trace correlation: the span is recorded under the field names the OTel spec fixes for non-OTLP log formats, so a collector can lift them onto the log record's own trace fields. Gated on the whole span context being valid: a trace ID without a span ID names a request but not the operation within it.