Documentation ¶
Overview ¶
package message defines the Composer interface and a handful of implementations which represent the structure for messages produced by grip.
Message Composers ¶
The Composer interface provides a common way to define messages, with two main goals:
1. Provide a common interface for representing structured and unstructured logging data regardless of logging backend or interface.
2. Provide a method for *lazy* construction of log messages so they're built *only* if a log message is over threshold.
The message package also contains many implementations of Composer which should support most logging use cases. However, any package using grip for logging may need to implement custom composer types.
The Composer implementations in the message package compose the Base type to provide some common functionality around priority setting and data collection.
The logging methods in the Journaler interface typically convert all inputs into a reasonable Composer implementations.
Error Messages ¶
The error message composers underpin the Catch<> logging messages, which allow you to log error messages but let the logging system elide logging for nil errors.
Message Futures and Functional Logging ¶
Grip can automatically converts functions which produce Composers or types that can be trivially converted to messages..
The benefit of this logging model, is that the message is generated only when the message is above the logging threshold. In the case of conditional logging (i.e. When), if the conditional is false, then the function is never called. Similarly, if the message is a Debug, then the function is never logged.
For sending architectures where, there's a buffer between the logger and the message being sent or persisted, the function call that resolves the message can be deferred.
Additionally, the message conversion in grip's logging method can take these function types and convert them to these messages, which can clean up some call-site operations, and makes it possible to use defer with io.Closer methods without wrapping the method in an additional function, as in:
defer grip.Error(file.Close)
Although the WrapErrorFunc method, as in the following may permit useful annotation, as follows, which has the same "lazy" semantics.
defer grip.Error(message.WrapErrorFunc(file.Close, message.Fields{}))
Bytes Messages ¶
The bytes types make it possible to send a byte slice as a message.
Stack Messages ¶
The Stack message Composer implementations capture a full stacktrace information during message construction, and attach a message to that trace. The string form of the message includes the package and file name and line number of the last call site, while the Raw form of the message includes the entire stack. Use with an appropriate sender to capture the desired output.
All stack message constructors take a "skip" parameter which tells how many stack frames to skip relative to the invocation of the constructor. Skip values less than or equal to 0 become 1, and are equal the call site of the constructor, use larger numbers if you're wrapping these constructors in our own infrastructure.
In general Composers are lazy, and defer work until the message is being sent; however, the stack Composers must capture the stack when they're called rather than when they're sent to produce meaningful data.
Index ¶
- Constants
- func GetDefaultFieldsMessage(msg Composer, val string) string
- func IsMulti(comp Composer) bool
- func KV(k string, v any) dt.Pair[string, any]
- type Base
- type Builder
- func (b *Builder) Annotate(key string, val any) *Builder
- func (b *Builder) Any(msg any) *Builder
- func (b *Builder) AnyMap(f map[string]any) *Builder
- func (b *Builder) Bytes(in []byte) *Builder
- func (b *Builder) Composer(c Composer) *Builder
- func (b *Builder) Error(err error) *Builder
- func (b *Builder) F(tmpl string, a ...any) *Builder
- func (b *Builder) Fields(f Fields) *Builder
- func (b *Builder) Future() *BuilderFuture
- func (b *Builder) Group() *Builder
- func (b *Builder) Level(l level.Priority) *Builder
- func (b *Builder) Leveler(fn fun.Future[level.Priority]) *Builder
- func (b *Builder) Ln(args ...any) *Builder
- func (b *Builder) Message() Composer
- func (b *Builder) P() *BuilderP
- func (b *Builder) Pair(k string, v any) *Builder
- func (b *Builder) PairBuilder() *BuilderP
- func (b *Builder) Pairs(kvs ...dt.Pair[string, any]) *Builder
- func (b *Builder) Send()
- func (b *Builder) SetGroup(sendAsGroup bool) *Builder
- func (b *Builder) SetOption(opts ...Option) *Builder
- func (b *Builder) String(str string) *Builder
- func (b *Builder) StringMap(f map[string]string) *Builder
- func (b *Builder) Strings(ss []string) *Builder
- func (b *Builder) Ungroup() *Builder
- func (b *Builder) When(cond bool) *Builder
- type BuilderFuture
- func (b *BuilderFuture) Builder() *Builder
- func (b *BuilderFuture) Composer(f fun.Future[Composer]) *BuilderFuture
- func (b *BuilderFuture) Convert(f fun.Future[any]) *BuilderFuture
- func (b *BuilderFuture) Error(f fun.Future[error]) *BuilderFuture
- func (b *BuilderFuture) Fields(f fun.Future[Fields]) *BuilderFuture
- func (b *BuilderFuture) Map(f fun.Future[map[string]any]) *BuilderFuture
- func (b *BuilderFuture) Pairs(f fun.Future[dt.Pairs[string, any]]) *BuilderFuture
- func (b *BuilderFuture) Send()
- func (b *BuilderFuture) String(f fun.Future[string]) *BuilderFuture
- type BuilderP
- type Composer
- func Convert[T any](input T) Composer
- func MakeBytes(b []byte) Composer
- func MakeError(err error) Composer
- func MakeFields(f Fields) Composer
- func MakeFormat(base string, args ...any) Composer
- func MakeFuture[T any](fp fun.Future[T]) Composer
- func MakeKV(kvs ...dt.Pair[string, any]) Composer
- func MakeLines(args ...any) Composer
- func MakePairs(kvs *dt.Pairs[string, any]) Composer
- func MakeStack(skip int, message string) Composer
- func MakeString(m string) Composer
- func Unwind(comp Composer) []Composer
- func When(cond bool, m any) Composer
- func WhenMsg(cond bool, m string) Composer
- func Whenf(cond bool, m string, args ...any) Composer
- func Whenln(cond bool, args ...any) Composer
- func Wrap(parent Composer, msg any) Composer
- func WrapError(err error, m any) Composer
- func WrapErrorf(err error, msg string, args ...any) Composer
- func WrapStack(skip int, msg any) Composer
- type Converter
- type ConverterFunc
- type Fields
- type GroupComposer
- func (g *GroupComposer) Add(msg Composer)
- func (g *GroupComposer) Annotate(k string, v any)
- func (g *GroupComposer) Append(msgs ...Composer)
- func (g *GroupComposer) Extend(msg []Composer)
- func (g *GroupComposer) Loggable() bool
- func (g *GroupComposer) Messages() []Composer
- func (g *GroupComposer) Priority() level.Priority
- func (g *GroupComposer) Raw() any
- func (g *GroupComposer) SetOption(opts ...Option)
- func (g *GroupComposer) SetPriority(l level.Priority)
- func (g *GroupComposer) String() string
- func (g *GroupComposer) Structured() bool
- func (g *GroupComposer) Unwrap() Composer
- type Marshaler
- type Option
- type PairBuilder
- func (p *PairBuilder) AddPair(in dt.Pair[string, any]) *PairBuilder
- func (p *PairBuilder) Annotate(key string, value any)
- func (p *PairBuilder) Append(in ...dt.Pair[string, any]) *PairBuilder
- func (p *PairBuilder) Composer() Composer
- func (p *PairBuilder) Extend(in *dt.Pairs[string, any]) *PairBuilder
- func (p *PairBuilder) Fields(f Fields) *PairBuilder
- func (p *PairBuilder) Iterator(ctx context.Context, iter *fun.Iterator[dt.Pair[string, any]]) *PairBuilder
- func (p *PairBuilder) Level(l level.Priority) *PairBuilder
- func (p *PairBuilder) Loggable() bool
- func (p *PairBuilder) Option(f Option) *PairBuilder
- func (p *PairBuilder) Pair(key string, value any) *PairBuilder
- func (p *PairBuilder) PairWhen(cond bool, k string, v any) *PairBuilder
- func (p *PairBuilder) Raw() any
- func (p *PairBuilder) String() string
- func (p *PairBuilder) Structured() bool
- type StackFrame
- type StackFrames
- type StackTrace
Constants ¶
const FieldsMsgName = "msg"
FieldsMsgName is the name of the default "message" field in the fields structure.
Variables ¶
This section is empty.
Functions ¶
func GetDefaultFieldsMessage ¶
GetDefaultFieldsMessage returns a "short" message form, to avoid needing to call .String() on the type, which produces a string form of the message. If the message has a short form (either in the map, or separate), it's returned, otherwise the "val" is returned.
For composers not that don't wrap Fields, this function will always return the input value.
Types ¶
type Base ¶
type Base struct { Level level.Priority `bson:"level,omitempty" json:"level,omitempty" yaml:"level,omitempty"` Pid int `bson:"pid,omitempty" json:"pid,omitempty" yaml:"pid,omitempty"` Process string `bson:"proc,omitempty" json:"proc,omitempty" yaml:"proc,omitempty"` Host string `bson:"host,omitempty" json:"host,omitempty" yaml:"host,omitempty"` Time time.Time `bson:"ts,omitempty" json:"ts,omitempty" yaml:"ts,omitempty"` Context Fields `bson:"data,omitempty" json:"data,omitempty" yaml:"data,omitempty"` CollectInfo bool `bson:"-" json:"-" yaml:"-"` IncludeMetadata bool `bson:"-" json:"-" yaml:"-"` MessageIsSpecial bool `bson:"-" json:"-" yaml:"-"` }
Base provides a simple embedable implementation of some common aspects of a message.Composer. Additionally the Collect() method collects some simple metadata, that may be useful for some more structured logging applications.
func (*Base) Annotate ¶
Annotate makes it possible for callers and senders to add structured data to a message. This may be overridden for some implementations.
func (*Base) Collect ¶
func (b *Base) Collect()
Collect records the time, process name, and hostname. Useful in the context of a Raw() method.
func (*Base) IsZero ¶
IsZero returns true when Base is nil or it is non-nil and none of its fields are set.
func (*Base) SetPriority ¶
SetPriority allows you to configure the priority of the message. Returns an error if the priority is not valid.
func (*Base) Structured ¶
false. Most Composer implementations should override.
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder provides a chainable message building interface.
Builders can produce multiple messages. If the SetGroup value is true (also controlled via the Group/Ungroup methods,) then the Send operation is called once for the group of messages, and otherwise the send operation is called once for every constituent message (which is the default.)
Callers must call Send() at the end of the builder chain to send the message.
func NewBuilder ¶
NewBuilder constructs the chainable builder type, and initializes the error tracking and establishes a connection to the sender.
func (*Builder) Fields ¶
Fields, creates a new fields message if no message has been defined, and otherwise annotates the existing message with the content of the input map. This is the same semantics as StringMap and AnyMap methods
func (*Builder) Future ¶ added in v0.3.5
func (b *Builder) Future() *BuilderFuture
func (*Builder) Level ¶
Level sets the priority of the message. Call this after creating a message via another method, otherwise an error is generated and added to the builder. Additionally an error is added to the builder if the level is not valid.
func (*Builder) Message ¶
Message resolves the message built by the builder, flattening (if needed,) multiple messages into a single grouped message, and wrapping the message with an error if any were produced while building the message.
If no message is built and no errors are registered, then Message resolves a non-loggable error message.
If multiple messages are added to the logger they are stored in a wrapped form, so that modifications to the message (annotations, levels, etc.) affect the most recent message, and then later converted to a group.
func (*Builder) PairBuilder ¶ added in v0.3.3
PairBuilder creates a new PairBuilder, in a special builder wrapper, that makes it possible to access the original builder and send the message, as needed.
func (*Builder) Pairs ¶ added in v0.3.3
Pairs, creates a new key-value message if no message has been defined, and otherwise annotates the existing message with the content of the input set. This is the same semantics as the Fields method.
func (*Builder) Send ¶
func (b *Builder) Send()
Send finalizes the chain and delivers the message. Send resolves the built message using the Message method.
If there are multiple messages captured in the builder, and the Group() is set to true, then the GroupComposer's default behavior is used, otherwise, each message is sent individually.
func (*Builder) SetOption ¶ added in v0.3.0
Option sets options on the builder which are applied to the message(s) as they are sent with Send(), or exported with Message().
type BuilderFuture ¶ added in v0.3.5
type BuilderFuture struct {
// contains filtered or unexported fields
}
func (*BuilderFuture) Builder ¶ added in v0.3.5
func (b *BuilderFuture) Builder() *Builder
func (*BuilderFuture) Composer ¶ added in v0.3.5
func (b *BuilderFuture) Composer(f fun.Future[Composer]) *BuilderFuture
func (*BuilderFuture) Convert ¶ added in v0.3.5
func (b *BuilderFuture) Convert(f fun.Future[any]) *BuilderFuture
func (*BuilderFuture) Error ¶ added in v0.3.5
func (b *BuilderFuture) Error(f fun.Future[error]) *BuilderFuture
func (*BuilderFuture) Fields ¶ added in v0.3.5
func (b *BuilderFuture) Fields(f fun.Future[Fields]) *BuilderFuture
func (*BuilderFuture) Map ¶ added in v0.3.5
func (b *BuilderFuture) Map(f fun.Future[map[string]any]) *BuilderFuture
func (*BuilderFuture) Pairs ¶ added in v0.3.5
func (b *BuilderFuture) Pairs(f fun.Future[dt.Pairs[string, any]]) *BuilderFuture
func (*BuilderFuture) Send ¶ added in v0.3.5
func (b *BuilderFuture) Send()
func (*BuilderFuture) String ¶ added in v0.3.5
func (b *BuilderFuture) String(f fun.Future[string]) *BuilderFuture
type BuilderP ¶ added in v0.3.4
type BuilderP struct { *PairBuilder // contains filtered or unexported fields }
type Composer ¶
type Composer interface { // Returns the content of the message as a string for use in // line-printing logging engines. String() string // A "raw" format of the logging output for use by some Sender // implementations that write logged items to interfaces that // accept JSON or another structured format. Raw() any // Returns "true" when the message has content and should be // logged, and false otherwise. When false, the sender can // (and should!) ignore messages even if they are otherwise // above the logging threshold. Loggable() bool // Returns "true" when the underlying message type has // substantial structured data and should be handled by the // sender as structured data. Structured() bool // Annotate makes it possible for users (including internally) // to add structured data to a log message. Implementations may // choose to override key/value pairs that already exist. Annotate(string, any) // Priority returns the priority of the message. Priority() level.Priority // SetPriority sets the messaages' log level. The high level // logging interfaces set this before sending the // message. If you send a message to a sender directly without // setting the level, or set the level to an invalid level, // the message is not loggable. SetPriority(level.Priority) // AttachMetadata is used by send.Sender implementations and // send.Formater implementations to control the output format // and processing of messages. These options may be defined in // other packages, and implementations are under no obligation // to respect them. In the case where two options that // contradict eachother, the last one should win. SetOption(...Option) }
Composer defines an interface with a String() method that returns the message in string format, as well as a Raw() method that may provide a structured form of the message. Objects that implement this interface, the String() method is only caled if the priority of the method is greater than the threshold priority. This makes it possible to defer building log messages (that may be somewhat expensive to generate) until it's certain that they will be consumed.
Most implementations will only implement String() and Raw() and rely on the message.Base type which can be composed and provides basic implementations for types.
func Convert ¶
Convert produces a composer interface for arbitrary input.
The result is almost never (typed nil values may pass through) Convert.
Use this directly in your implementation of the Converter interface. The DefaultConverter implementation provides a wrapper around this implementation. The ConverterFunc-based implementations fall back to this implementation
func MakeError ¶
MakeError returns a Composer, that wraps an error, and is only loggable for non-nil errors. The message also implements error methods (e.g. Error() string, Is() bool, and Unwrap() error).
func MakeFields ¶
MakeFields creates a composer interface from *just* a Fields instance.
func MakeFormat ¶
MakeFormat returns a message.Composer roughly equivalent to an fmt.Sprintf().
func MakeFuture ¶ added in v0.3.5
MakeFuture constructs a compuser build around a fun.Future[T] which a function object that will resolve a message lazily. Use this to construct a function that will produce a message or a type that can be trivally converted to a message at call time.
The future is resolved functions are only called when the outer composers Loggable, String, Raw, or Annotate methods are called. Changing the priority does not resolve the future. In practice, if the priority of the message is below the logging threshold, then the function will never be called.
func MakeStack ¶
MakeStack builds a Composer implementation that captures the current stack trace with a single string message. Use the skip argument to skip frames if your embedding this in your own wrapper or wrappers.
func MakeString ¶
MakeString provides a basic message consisting of a single line.
func Unwind ¶ added in v0.2.1
Unwind takes a composer and, if it has been wrapped, unwraps it and produces a group composer of all the constituent messages. If there are group messages in the stack, they are added (flattened) in the new output group.
func When ¶
When returns a conditional message that is only logged if the condition is bool. Converts the second argument to a composer, if needed, using the same rules that the logging methods use.
func WhenMsg ¶
WhenMsg returns a conditional message that is only logged if the condition is bool, and creates a string message that will only log when the message content is not the empty string. Use this for a more strongly-typed conditional logging message.
func Whenf ¶
Whenf returns a conditional message that is only logged if the condition is bool, and creates a sprintf-style message, which will itself only log if the base expression is not the empty string.
func Whenln ¶
Whenln returns a conditional message that is only logged if the condition is bool, and creates a sprintf-style message, which will itself only log if the base expression is not the empty string.
func Wrap ¶
Wrap creates a new composer, converting the message to the appropriate Composer type, using the Convert() function, while preserving the parent composer. The Unwrap() function unwinds a stack of composers, flattening it into a single group composer.
func WrapError ¶
WrapError wraps an error and creates a composer converting the argument into a composer in the same manner as the front end logging methods.
func WrapErrorf ¶
WrapErrorf wraps an error and creates a composer using a Sprintf-style formated composer.
type Converter ¶ added in v0.3.2
Converter is an interface for converting arbitrary types to Composers. Like the http.Handler interface, the primary form of implementing the interface is by ConverterFunc itself, which implements Converter.
The DefaultConverter function produces a wrapper around the Convert function which produces all logging messages.
func DefaultConverter ¶ added in v0.3.2
func DefaultConverter() Converter
DefaultConverter is a Converter implementation around the Convert function.
type ConverterFunc ¶ added in v0.3.2
ConverterFunc is a function that users can inject into their sender that the grip.Logger will use to convert arbitrary input types into message objects. If the second value is false, the output message will not be used and the logger will fall back to using message.Convert.
func (ConverterFunc) Convert ¶ added in v0.3.2
func (cf ConverterFunc) Convert(m any) Composer
type Fields ¶
Fields is a convince type that wraps map[string]any and is used for attaching structured metadata to a build request. For example:
message.Fields{"key0", <value>, "key1", <value>}
func FieldsFromMap ¶ added in v0.2.0
type GroupComposer ¶
type GroupComposer struct {
// contains filtered or unexported fields
}
GroupComposer handles groups of composers as a single message, joining messages with a new line for the string format and returning a slice of interfaces for the Raw() form.
Unlike most composer types, the GroupComposer is exported, and provides the additional Messages() method to access the composer objects as a slice.
func BuildGroupComposer ¶
func BuildGroupComposer(msgs ...Composer) *GroupComposer
BuildGroupComposer provides a variadic interface for creating a GroupComposer.
func MakeGroupComposer ¶
func MakeGroupComposer(msgs []Composer) *GroupComposer
MakeGroupComposer returns a GroupComposer object from a slice of Composers.
func (*GroupComposer) Add ¶
func (g *GroupComposer) Add(msg Composer)
Add supports adding messages to an existing group composer.
func (*GroupComposer) Annotate ¶
func (g *GroupComposer) Annotate(k string, v any)
Annotate calls the Annotate method of every non-nil component Composer.
func (*GroupComposer) Append ¶
func (g *GroupComposer) Append(msgs ...Composer)
Append provides a variadic alternative to the Extend method.
func (*GroupComposer) Extend ¶
func (g *GroupComposer) Extend(msg []Composer)
Extend makes it possible to add a group of messages to an existing group composer.
func (*GroupComposer) Loggable ¶
func (g *GroupComposer) Loggable() bool
Loggable returns true if at least one of the constituent Composers is loggable.
func (*GroupComposer) Messages ¶
func (g *GroupComposer) Messages() []Composer
Messages returns a the underlying collection of messages.
func (*GroupComposer) Priority ¶
func (g *GroupComposer) Priority() level.Priority
Priority returns the highest priority of the constituent Composers.
func (*GroupComposer) Raw ¶
func (g *GroupComposer) Raw() any
Raw returns a slice of interfaces containing the raw form of all the constituent composers.
func (*GroupComposer) SetOption ¶ added in v0.3.0
func (g *GroupComposer) SetOption(opts ...Option)
func (*GroupComposer) SetPriority ¶
func (g *GroupComposer) SetPriority(l level.Priority)
SetPriority sets the priority of all constituent Composers *only* if the existing level is unset (or otherwise invalid), and will *not* unset the level of a constituent composer.
func (*GroupComposer) String ¶
func (g *GroupComposer) String() string
String satisfies the fmt.Stringer interface, and returns a string of the string form of all constituent composers joined with a newline.
func (*GroupComposer) Structured ¶
func (g *GroupComposer) Structured() bool
func (*GroupComposer) Unwrap ¶ added in v0.2.9
func (g *GroupComposer) Unwrap() Composer
type Marshaler ¶ added in v0.2.5
type Marshaler interface {
MarshalComposer() Composer
}
Marshaler allows arbitrary types to control how they're converted (in the default converter) to a message.Composer, without requiring that the arbitrary type itself implement Composer, for a related level of functionality.
type Option ¶ added in v0.3.0
type Option string
Options control the behavior and output of a message, specifically the String and Raw methods. Implementations are responsible for compliance with the options. The `Base` type provides basic support for setting and exposing these options to implementations.
const ( // OptionIncludeMetadata tells the message to annotate itself // basic metadata to a message. OptionIncludeMetadata Option = "include-metadata" // OptionSkipMetadata disables the inclusion of metadata // in the output messaage. This is typically the default in // most implementations. OptionSkipMetadata Option = "skip-metadata" // OptionCollectInfo enables collecting extra data // (implemented by the Base type) including hostname, process // name, and time. While this information is cached and not // difficult to collect, it may increase the message payload // with unneeded data. OptionCollectInfo Option = "collect-info" // OptionSkipCollect tells the message, typically for Raw() // calls to *not* call the message/Base.Collect method which // annotates fields about the host system and level. This is // typically the default. OptionSkipCollectInfo Option = "skip-collect-info" // OptionMessageIsNotStructuredField indicates to the // implementor that the Message field name in Fields-typed // messages (defined by the message.FieldsMsgName constant) // should *not* be handdled specially. OptionMessageIsNotStructuredField Option = "message-is-not-structured" )
type PairBuilder ¶ added in v0.3.3
type PairBuilder struct { Base // contains filtered or unexported fields }
PairBuilder is a chainable interface for building a KV/dt.Pair message. These are very similar to Fields messages, however their keys are ordered, duplicate keys can be defined, and
func BuildPair ¶ added in v0.3.3
func BuildPair() *PairBuilder
BuildPair creates a wrapper around a composer that allows for a chainable pair message building interface.
func (*PairBuilder) AddPair ¶ added in v0.3.3
func (p *PairBuilder) AddPair(in dt.Pair[string, any]) *PairBuilder
func (*PairBuilder) Annotate ¶ added in v0.3.3
func (p *PairBuilder) Annotate(key string, value any)
func (*PairBuilder) Append ¶ added in v0.3.3
func (p *PairBuilder) Append(in ...dt.Pair[string, any]) *PairBuilder
func (*PairBuilder) Composer ¶ added in v0.3.3
func (p *PairBuilder) Composer() Composer
Composer returns the builder as a composer-type
func (*PairBuilder) Extend ¶ added in v0.3.3
func (p *PairBuilder) Extend(in *dt.Pairs[string, any]) *PairBuilder
func (*PairBuilder) Fields ¶ added in v0.3.3
func (p *PairBuilder) Fields(f Fields) *PairBuilder
func (*PairBuilder) Iterator ¶ added in v0.3.3
func (p *PairBuilder) Iterator(ctx context.Context, iter *fun.Iterator[dt.Pair[string, any]]) *PairBuilder
func (*PairBuilder) Level ¶ added in v0.3.3
func (p *PairBuilder) Level(l level.Priority) *PairBuilder
func (*PairBuilder) Loggable ¶ added in v0.3.3
func (p *PairBuilder) Loggable() bool
func (*PairBuilder) Option ¶ added in v0.3.3
func (p *PairBuilder) Option(f Option) *PairBuilder
func (*PairBuilder) Pair ¶ added in v0.3.3
func (p *PairBuilder) Pair(key string, value any) *PairBuilder
func (*PairBuilder) PairWhen ¶ added in v0.3.4
func (p *PairBuilder) PairWhen(cond bool, k string, v any) *PairBuilder
func (*PairBuilder) Raw ¶ added in v0.3.3
func (p *PairBuilder) Raw() any
func (*PairBuilder) String ¶ added in v0.3.3
func (p *PairBuilder) String() string
func (*PairBuilder) Structured ¶ added in v0.3.3
func (p *PairBuilder) Structured() bool
type StackFrame ¶
type StackFrame struct { Function string `bson:"function" json:"function" yaml:"function"` File string `bson:"file" json:"file" yaml:"file"` Line int `bson:"line" json:"line" yaml:"line"` }
StackFrame captures a single item in a stack trace, and is used internally and in the StackTrace output.
func (StackFrame) String ¶
func (f StackFrame) String() string
type StackFrames ¶
type StackFrames []StackFrame
StackFrames makes slices of stack traces printable.
func (StackFrames) String ¶
func (f StackFrames) String() string
type StackTrace ¶
type StackTrace struct { Context any `bson:"data,omitempty" json:"data,omitempty" yaml:"data,omitempty"` Frames StackFrames `bson:"frames" json:"frames" yaml:"frames"` }
StackTrace structs are returned by the Raw method for stack messages IF the message is not structured. For structured messages, the Raw() method annotates the underlying message with the "stack.frames" key, and a value of StackFrames type.
func (StackTrace) String ¶
func (s StackTrace) String() string