Documentation
¶
Overview ¶
Package protoslog provides utilities for using protocol buffer messages with the log/slog package.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Message ¶
Message returns a slog.Attr for a proto.Message using the provided options. Note that these options are ignored if the slog.Value is handled by a Handler.
Example ¶
updated := time.Date(2012, time.September, 2, 15, 53, 0, 0, time.UTC)
msg := &pb.User{
Id: 123,
Name: "foobar",
Email: "[email protected]", // debug_redact
Location: &pb.Location{
Latitude: 1.23,
Longitude: 4.56,
},
Hobbies: []string{"track", "field"},
Pets: map[string]pb.PetType{
"Rover": pb.PetType_PET_TYPE_DOG,
"Fifi": pb.PetType_PET_TYPE_CAT,
},
Updated: timestamppb.New(updated),
Best_100MTime: durationpb.New(9*time.Second + 580*time.Millisecond),
}
logger := slog.New(slogHandler())
logger.Info("some event", protoslog.Message("user", msg))
Output: level=INFO msg="some event" user.id=123 user.name=foobar user.email=REDACTED user.location.latitude=1.23 user.location.longitude=4.56 user.hobbies.0=track user.hobbies.1=field user.pets.Fifi=PET_TYPE_CAT user.pets.Rover=PET_TYPE_DOG user.updated=2012-09-02T15:53:00.000Z user.best_100m_time=9.58s
func MessageValue ¶
MessageValue returns a slog.Value for a proto.Message using the provided options. Note that these options are ignored if the slog.Value is handled by a Handler.
Types ¶
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler is a slog.Handler that properly converts proto.Message attributes into the appropriate slog.Value, before delegating to a child slog.Handler. The Handler's options merge with the options associated with proto.Message types that implement slog.LogValuer. Handler must be constructed via NewHandler.
Example ¶
msg := &pb.User{
Id: 123,
Best_100MTime: durationpb.New(9*time.Second + 580*time.Millisecond),
}
handler := protoslog.NewHandler(slogHandler())
logger := slog.New(handler)
logger.Info("hello world", "user", msg)
Output: level=INFO msg="hello world" user.id=123 user.best_100m_time=9.58s
Example (AllFields) ¶
msg := &pb.Location{
Latitude: 1.23,
}
childHandler := slogHandler()
logger := slog.New(protoslog.NewHandler(childHandler))
logger.Info("default", "loc", msg)
logger = slog.New(protoslog.NewHandler(childHandler, protoslog.WithAllFields()))
logger.Info("all", "loc", msg)
Output: level=INFO msg=default loc.latitude=1.23 level=INFO msg=all loc.latitude=1.23 loc.longitude=0
Example (Any) ¶
msg, _ := anypb.New(&pb.Location{
Latitude: 1.23,
Longitude: 4.56,
})
childHandler := slogHandler()
logger := slog.New(protoslog.NewHandler(childHandler))
logger.Info("default", "any", msg)
logger.Info("unknown", "any", &anypb.Any{TypeUrl: "foobar"})
logger = slog.New(protoslog.NewHandler(childHandler, protoslog.WithSkipAnys()))
logger.Info("skip", "any", msg)
Output: level=INFO msg=default any.@type=type.googleapis.com/Location any.latitude=1.23 any.longitude=4.56 level=INFO msg=unknown any.@type=foobar level=INFO msg=skip any.@type=type.googleapis.com/Location
Example (Redaction) ¶
Messages may contain personal identifiable information (PII), secrets, or similar data that should not be written into a log. Message fields can be annotated with the debug_redact option to identify such values. By default, protoslog will redact these fields, with the behavior customizable via [options].
// message User { fixed64 id = 1; string email = 2 [debug_redact=true]; }
msg := &pb.User{
Id: 123,
Email: "[email protected]",
}
childHandler := slogHandler()
logger := slog.New(protoslog.NewHandler(childHandler))
logger.Info("default", "user", msg)
logger = slog.New(protoslog.NewHandler(childHandler, protoslog.WithDisableRedactions()))
logger.Info("disabled", "user", msg)
logger = slog.New(protoslog.NewHandler(childHandler, protoslog.WithElideRedactions()))
logger.Info("elided", "user", msg)
Output: level=INFO msg=default user.id=123 user.email=REDACTED level=INFO msg=disabled user.id=123 [email protected] level=INFO msg=elided user.id=123
func NewHandler ¶
NewHandler creates a Handler that delegates to child, using the given options. Note that these options merge with any options used in Message, MessageValue, or MessageValuer.
func (Handler) Handle ¶
Handle converts the proto.Message attributes on record before delegating the record to its child handler.
func (Handler) WithAttrs ¶
WithAttrs converts the proto.Message attributes before delegating them to its child handler.
Example ¶
loc := &pb.Location{Latitude: 1.23}
msg := &pb.User{Id: 456}
logger := slog.New(protoslog.NewHandler(slogHandler()))
logger.With("loc", loc).Info("attrs", "user", msg)
Output: level=INFO msg=attrs loc.latitude=1.23 user.id=456
type KeyFormatter ¶ added in v0.1.4
type KeyFormatter func(key string, fd protoreflect.FieldDescriptor, value protoreflect.Value) string
KeyFormatter functions provide a way to alter a slog.Attr key depending on the to be logged field of a protoreflect.Message.
type Option ¶
type Option func(o *options)
Option functions customize generation of a slog.Value from a proto.Message beyond the default behavior.
func WithAllFields ¶
func WithAllFields() Option
WithAllFields indicates that all fields, including unpopulated ones, should be included in slog.Value. Unpopulated members of a oneof are still excluded from the output.
func WithAnyResolver ¶
func WithAnyResolver(resolver protoregistry.MessageTypeResolver) Option
WithAnyResolver is the protoregistry.MessageTypeResolver used to resolve the google.protobuf.Any well-known type into a valid slog.Value. When nil, protoregistry.GlobalTypes is used. If the type cannot be found in the resolver or if unmarshaling fails, only a "@type" field is emitted.
func WithDisableRedactions ¶
func WithDisableRedactions() Option
WithDisableRedactions indicates that fields annotated with the debug_redact option should not be redacted from the slog.Value.
func WithElideRedactions ¶
func WithElideRedactions() Option
WithElideRedactions indicates that redacted fields should be removed from the slog.Value instead of being replaced with REDACTED. WithElideRedactions supersedes WithAllFields.
func WithKeyFormatter ¶ added in v0.1.4
func WithKeyFormatter(formatter KeyFormatter) Option
WithKeyFormatter is used to alter a slog.Attr key depending on the to be logged field of a protoreflect.Message.
func WithSkipAnys ¶
func WithSkipAnys() Option
WithSkipAnys indicates that google.protobuf.Any fields should not be unmarshalled during construction of the slog.Value, emitting only a "@type" field.
type Valuer ¶
type Valuer struct {
// Message is the proto.Message to produce the slog.Value.
Message proto.Message
// contains filtered or unexported fields
}
Valuer implements slog.LogValuer for a proto.Message to defer computing a slog.Value until it's needed.
func MessageValuer ¶
MessageValuer returns a Valuer for a proto.Message using the provided options. Note that these options are ignored if the Valuer is handled by a Handler.
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
Package main is the protoc-gen-slog plugin
|
Package main is the protoc-gen-slog plugin |