Documentation ¶
Overview ¶
Package slogproto provides a protocol buffer definition for the slog format (golang.org/x/exp/slog).
It attempts to have minimial dependencies and minimize memory allocations.
Index ¶
- Constants
- Variables
- func CompileFilter(expr string) (cel.Program, error)
- func EvalFilter(prog cel.Program, r *slog.Record) (bool, error)
- func Read(ctx context.Context, r io.Reader, fn func(r *slog.Record) bool) error
- type Handler
- type Level
- type Record
- func (*Record) Descriptor() ([]byte, []int)deprecated
- func (x *Record) GetAttrs() map[string]*Value
- func (x *Record) GetLevel() Level
- func (x *Record) GetMessage() string
- func (x *Record) GetTime() *timestamppb.Timestamp
- func (*Record) ProtoMessage()
- func (x *Record) ProtoReflect() protoreflect.Message
- func (x *Record) Reset()
- func (x *Record) String() string
- type Value
- func (*Value) Descriptor() ([]byte, []int)deprecated
- func (x *Value) GetAny() *anypb.Any
- func (x *Value) GetBool() bool
- func (x *Value) GetDuration() *durationpb.Duration
- func (x *Value) GetFloat() float64
- func (x *Value) GetGroup() *Value_Group
- func (x *Value) GetInt() int64
- func (m *Value) GetKind() isValue_Kind
- func (x *Value) GetString_() string
- func (x *Value) GetTime() *timestamppb.Timestamp
- func (x *Value) GetUint() uint64
- func (*Value) ProtoMessage()
- func (x *Value) ProtoReflect() protoreflect.Message
- func (x *Value) Reset()
- func (x *Value) String() string
- type Value_Any
- type Value_Bool
- type Value_Duration
- type Value_Float
- type Value_Group
- type Value_Group_
- type Value_Int
- type Value_String_
- type Value_Time
- type Value_Uint
Examples ¶
Constants ¶
const ( LevelInfo = Level_LEVEL_INFO LevelWarn = Level_LEVEL_WARN LevelError = Level_LEVEL_ERROR LevelDebug = Level_LEVEL_DEBUG )
Variables ¶
var ( Level_name = map[int32]string{ 0: "LEVEL_UNSPECIFIED", 1: "LEVEL_INFO", 2: "LEVEL_WARN", 3: "LEVEL_ERROR", 4: "LEVEL_DEBUG", } Level_value = map[string]int32{ "LEVEL_UNSPECIFIED": 0, "LEVEL_INFO": 1, "LEVEL_WARN": 2, "LEVEL_ERROR": 3, "LEVEL_DEBUG": 4, } )
Enum value maps for Level.
var File_slog_proto protoreflect.FileDescriptor
Functions ¶
func CompileFilter ¶
CompileFilter compiles a filter expression into a program that can be evaluated against a slog record. The expression must evaluate to a boolean value: if it's true, the record should be included. It may reference the following variables:
- msg: string
- level: int
- time: timestamp
- attrs: map[string]any
The expression may also reference any of the functions provided by the CEL standard library, as well as the following functions provided by the CEL extension libraries:
- strings
- math
- encoders
- sets
- lists
- bindings
If the expression is invalid, an error is returned.
func EvalFilter ¶
EvalFilter evaluates a filter program against a slog record. The record must be a map[string]any, and the program must have been compiled with CompileFilter. If the program is invalid, an error is returned.
The record must contain the following keys:
- msg: string
- level: int
- time: timestamp
- attrs: map[string]any
func Read ¶
Read reads protobuf encoded slog records from the reader and calls the provided function for each record. If the function returns false, the iteration is stopped.
If the context is canceled, the iteration is stopped and the error is returned. If the reader returns an error, the error is returned.
Types ¶
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler implements the slog.Handler interface and writes the log record to the writer as a protocol buffer encoded struct containing the log record, including the levem, message and attributes.
func NewHandler ¶
func NewHandler(w io.Writer, opts *slog.HandlerOptions) *Handler
NewHandler returns a new Handler that writes to the writer.
Example ¶
h := slogproto.NewHandler(os.Stdout)
Example ¶
package main import ( "bytes" "log/slog" "github.com/picatz/slogproto" ) func main() { var logBuffer bytes.Buffer logger := slog.New(slogproto.NewHandler(&logBuffer, nil)) logger.Info("this is a test", slog.Group("test", slog.Int("test1", 1), slog.String("test2", "1"), slog.Float64("test3", 1.0), ), ) logger.Info("example", slog.Int("something", 1)) }
Output:
Example (Gzip) ¶
package main import ( "bytes" "compress/gzip" "log/slog" "github.com/picatz/slogproto" ) func main() { var logBuffer bytes.Buffer w := gzip.NewWriter(&logBuffer) logger := slog.New(slogproto.NewHandler(w, nil)) logger.Info("hello world") err := w.Flush() if err != nil { panic(err) } err = w.Close() if err != nil { panic(err) } }
Output:
func (*Handler) Handle ¶
Handle writes the log record to the writer as a protocol buffer encoded struct containing the log record, including the level, message and attributes.
It will only be called when Enabled returns true. The Context argument is as for Enabled. It is present solely to provide Handlers access to the context's values. Canceling the context should not affect record processing. (Among other things, log messages may be necessary to debug a cancellation-related problem.)
Handle methods that produce output should observe the following rules:
- If r.Time is the zero time, ignore the time.
- If r.PC is zero, ignore it.
- Attr's values should be resolved.
- If an Attr's key and value are both the zero value, ignore the Attr. This can be tested with attr.Equal(Attr{}).
- If a group's key is empty, inline the group's Attrs.
- If a group has no Attrs (even if it has a non-empty key), ignore it.
func (*Handler) WithAttrs ¶
WithAttrs returns a new Handler whose attributes consist of both the receiver's attributes and the arguments.
The Handler owns the slice: it may retain, modify or discard it.
func (*Handler) WithGroup ¶
WithGroup returns a new Handler with the given group appended to the receiver's existing groups.
The keys of all subsequent attributes, whether added by With or in a Record, should be qualified by the sequence of group names.
How this qualification happens is up to the Handler, so long as this Handler's attribute keys differ from those of another Handler with a different sequence of group names.
A Handler should treat WithGroup as starting a Group of Attrs that ends at the end of the log event. That is,
logger.WithGroup("s").LogAttrs(level, msg, slog.Int("a", 1), slog.Int("b", 2))
should behave like
logger.LogAttrs(level, msg, slog.Group("s", slog.Int("a", 1), slog.Int("b", 2)))
If the name is empty, WithGroup returns the receiver.
type Level ¶
type Level int32
func (Level) Descriptor ¶
func (Level) Descriptor() protoreflect.EnumDescriptor
func (Level) EnumDescriptor
deprecated
func (Level) Number ¶
func (x Level) Number() protoreflect.EnumNumber
func (Level) Type ¶
func (Level) Type() protoreflect.EnumType
type Record ¶
type Record struct { Time *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` Level Level `protobuf:"varint,3,opt,name=level,proto3,enum=slog.Level" json:"level,omitempty"` Attrs map[string]*Value `` /* 151-byte string literal not displayed */ // contains filtered or unexported fields }
func (*Record) Descriptor
deprecated
func (*Record) GetMessage ¶
func (*Record) GetTime ¶
func (x *Record) GetTime() *timestamppb.Timestamp
func (*Record) ProtoMessage ¶
func (*Record) ProtoMessage()
func (*Record) ProtoReflect ¶
func (x *Record) ProtoReflect() protoreflect.Message
type Value ¶
type Value struct { // Types that are assignable to Kind: // // *Value_Bool // *Value_Float // *Value_Int // *Value_String_ // *Value_Time // *Value_Duration // *Value_Uint // *Value_Group_ // *Value_Any Kind isValue_Kind `protobuf_oneof:"kind"` // contains filtered or unexported fields }
func (*Value) Descriptor
deprecated
func (*Value) GetDuration ¶
func (x *Value) GetDuration() *durationpb.Duration
func (*Value) GetGroup ¶
func (x *Value) GetGroup() *Value_Group
func (*Value) GetString_ ¶
func (*Value) GetTime ¶
func (x *Value) GetTime() *timestamppb.Timestamp
func (*Value) ProtoMessage ¶
func (*Value) ProtoMessage()
func (*Value) ProtoReflect ¶
func (x *Value) ProtoReflect() protoreflect.Message
type Value_Bool ¶
type Value_Bool struct {
Bool bool `protobuf:"varint,1,opt,name=bool,proto3,oneof"`
}
type Value_Duration ¶
type Value_Duration struct {
Duration *durationpb.Duration `protobuf:"bytes,6,opt,name=duration,proto3,oneof"`
}
type Value_Float ¶
type Value_Float struct {
Float float64 `protobuf:"fixed64,2,opt,name=float,proto3,oneof"`
}
type Value_Group ¶
type Value_Group struct { Attrs map[string]*Value `` /* 151-byte string literal not displayed */ // contains filtered or unexported fields }
func (*Value_Group) Descriptor
deprecated
func (*Value_Group) Descriptor() ([]byte, []int)
Deprecated: Use Value_Group.ProtoReflect.Descriptor instead.
func (*Value_Group) GetAttrs ¶
func (x *Value_Group) GetAttrs() map[string]*Value
func (*Value_Group) ProtoMessage ¶
func (*Value_Group) ProtoMessage()
func (*Value_Group) ProtoReflect ¶
func (x *Value_Group) ProtoReflect() protoreflect.Message
func (*Value_Group) Reset ¶
func (x *Value_Group) Reset()
func (*Value_Group) String ¶
func (x *Value_Group) String() string
type Value_Group_ ¶
type Value_Group_ struct {
Group *Value_Group `protobuf:"bytes,8,opt,name=group,proto3,oneof"`
}
type Value_Int ¶
type Value_Int struct {
Int int64 `protobuf:"varint,3,opt,name=int,proto3,oneof"`
}
type Value_String_ ¶
type Value_String_ struct {
String_ string `protobuf:"bytes,4,opt,name=string,proto3,oneof"`
}
type Value_Time ¶
type Value_Time struct {
Time *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=time,proto3,oneof"`
}
type Value_Uint ¶
type Value_Uint struct {
Uint uint64 `protobuf:"varint,7,opt,name=uint,proto3,oneof"`
}