Documentation
¶
Index ¶
- Variables
- func ArgFields[E any, R interface{ ... }](r R, f func(key E) (string, bool), l ...E) R
- func MapFields[K ~string, V any, R interface{ ... }](r R, m map[K]V) R
- type Builder
- func (x *Builder[E]) Any(key string, val any) *Builder[E]
- func (x *Builder[E]) Base64(key string, b []byte, enc *base64.Encoding) *Builder[E]
- func (x *Builder[E]) Call(fn func(b *Builder[E])) *Builder[E]
- func (x *Builder[E]) Dur(key string, d time.Duration) *Builder[E]
- func (x *Builder[E]) Enabled() bool
- func (x *Builder[E]) Err(err error) *Builder[E]
- func (x *Builder[E]) Field(key string, val any) *Builder[E]
- func (x *Builder[E]) Float32(key string, val float32) *Builder[E]
- func (x *Builder[E]) Int(key string, val int) *Builder[E]
- func (x *Builder[E]) Interface(key string, val any) *Builder[E]
- func (x *Builder[E]) Log(msg string)
- func (x *Builder[E]) LogFunc(fn func() string)
- func (x *Builder[E]) Logf(format string, args ...any)
- func (x *Builder[E]) Release()
- func (x *Builder[E]) Str(key string, val string) *Builder[E]
- func (x *Builder[E]) Time(key string, t time.Time) *Builder[E]
- type Context
- func (x *Context[E]) Any(key string, val any) *Context[E]
- func (x *Context[E]) Base64(key string, b []byte, enc *base64.Encoding) *Context[E]
- func (x *Context[E]) Dur(key string, d time.Duration) *Context[E]
- func (x *Context[E]) Enabled() bool
- func (x *Context[E]) Err(err error) *Context[E]
- func (x *Context[E]) Field(key string, val any) *Context[E]
- func (x *Context[E]) Float32(key string, val float32) *Context[E]
- func (x *Context[E]) Int(key string, val int) *Context[E]
- func (x *Context[E]) Interface(key string, val any) *Context[E]
- func (x *Context[E]) Logger() *Logger[E]
- func (x *Context[E]) Str(key string, val string) *Context[E]
- func (x *Context[E]) Time(key string, t time.Time) *Context[E]
- type Event
- type EventFactory
- type EventFactoryFunc
- type EventReleaser
- type EventReleaserFunc
- type Level
- type Logger
- func (x *Logger[E]) Alert() *Builder[E]
- func (x *Logger[E]) Build(level Level) *Builder[E]
- func (x *Logger[E]) Clone() *Context[E]
- func (x *Logger[E]) Crit() *Builder[E]
- func (x *Logger[E]) Debug() *Builder[E]
- func (x *Logger[E]) Emerg() *Builder[E]
- func (x *Logger[E]) Err() *Builder[E]
- func (x *Logger[E]) Info() *Builder[E]
- func (x *Logger[E]) Log(level Level, modifier Modifier[E]) error
- func (x *Logger[E]) Logger() *Logger[Event]
- func (x *Logger[E]) Notice() *Builder[E]
- func (x *Logger[E]) Trace() *Builder[E]
- func (x *Logger[E]) Warning() *Builder[E]
- type LoggerFactory
- func (LoggerFactory[E]) LevelAlert() Level
- func (LoggerFactory[E]) LevelCritical() Level
- func (LoggerFactory[E]) LevelDebug() Level
- func (LoggerFactory[E]) LevelDisabled() Level
- func (LoggerFactory[E]) LevelEmergency() Level
- func (LoggerFactory[E]) LevelError() Level
- func (LoggerFactory[E]) LevelInformational() Level
- func (LoggerFactory[E]) LevelNotice() Level
- func (LoggerFactory[E]) LevelTrace() Level
- func (LoggerFactory[E]) LevelWarning() Level
- func (LoggerFactory[E]) New(options ...Option[E]) *Logger[E]
- func (LoggerFactory[E]) NewEventFactoryFunc(f func(level Level) E) EventFactoryFunc[E]
- func (LoggerFactory[E]) NewEventReleaserFunc(f func(event E)) EventReleaserFunc[E]
- func (LoggerFactory[E]) NewModifierFunc(f func(event E) error) ModifierFunc[E]
- func (LoggerFactory[E]) NewModifierSlice(s ...Modifier[E]) ModifierSlice[E]
- func (LoggerFactory[E]) NewWriterFunc(f func(event E) error) WriterFunc[E]
- func (LoggerFactory[E]) NewWriterSlice(s ...Writer[E]) WriterSlice[E]
- func (LoggerFactory[E]) WithEventFactory(factory EventFactory[E]) Option[E]
- func (LoggerFactory[E]) WithEventReleaser(releaser EventReleaser[E]) Option[E]
- func (LoggerFactory[E]) WithLevel(level Level) Option[E]
- func (LoggerFactory[E]) WithModifier(modifier Modifier[E]) Option[E]
- func (LoggerFactory[E]) WithOptions(options ...Option[E]) Option[E]
- func (LoggerFactory[E]) WithWriter(writer Writer[E]) Option[E]
- type Modifier
- type ModifierFunc
- type ModifierSlice
- type Option
- func WithEventFactory[E Event](factory EventFactory[E]) Option[E]
- func WithEventReleaser[E Event](releaser EventReleaser[E]) Option[E]
- func WithLevel[E Event](level Level) Option[E]
- func WithModifier[E Event](modifier Modifier[E]) Option[E]
- func WithOptions[E Event](options ...Option[E]) Option[E]
- func WithWriter[E Event](writer Writer[E]) Option[E]
- type UnimplementedEvent
- func (UnimplementedEvent) AddBase64Bytes(string, []byte, *base64.Encoding) bool
- func (UnimplementedEvent) AddDuration(string, time.Duration) bool
- func (UnimplementedEvent) AddError(error) bool
- func (UnimplementedEvent) AddFloat32(string, float32) bool
- func (UnimplementedEvent) AddInt(string, int) bool
- func (UnimplementedEvent) AddMessage(string) bool
- func (UnimplementedEvent) AddString(string, string) bool
- func (UnimplementedEvent) AddTime(string, time.Time) bool
- type Writer
- type WriterFunc
- type WriterSlice
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrDisabled is a sentinel value that can be returned by a Modifier to // disable logging of the event, or by a Writer to indicate that the event // was not written. // // It may also return from Logger.Log. ErrDisabled = errors.New(`logger disabled`) )
var ( // L exposes New and it's Option functions (e.g. WithWriter) as // methods, using the generic Event type. // // It's provided as a convenience. L = LoggerFactory[Event]{} )
Functions ¶
func ArgFields ¶
func ArgFields[E any, R interface { Enabled() bool Field(key string, val any) R }](r R, f func(key E) (string, bool), l ...E) R
ArgFields is a helper function that calls Builder.Field or Context.Field, for every element of a (varargs) slice. If provided, f will be used to ensure that each key is a string, otherwise, if not provided, each key will be converted to a string, using fmt.Sprint. Passing an odd number of keys will set the last value to any(nil).
WARNING: The behavior of the Context.Field and Builder.Field methods may change without notice, to facilitate the addition of new field types.
Example ¶
// note that the order of keys is not stable (sorted only to make the test pass) w, out := sortedLineWriterSplitOnSpace(os.Stdout) defer func() { _ = w.Close() <-out }() // l is an instance of logiface.Logger l := simpleLoggerFactory.New( simpleLoggerFactory.WithEventFactory(NewEventFactoryFunc(mockSimpleEventFactory)), simpleLoggerFactory.WithWriter(&mockSimpleWriter{Writer: w}), simpleLoggerFactory.WithLevel(LevelDebug), ) // supports logiface.Builder ArgFields(l.Notice(), nil, "a", "A", "b", "B").Log(``) // supports logiface.Context ArgFields(l.Clone(), nil, "a", "A", "b", "B").Logger().Alert(). Log(``) // supports fluent chaining ArgFields(l.Crit(). Str(`a`, `A1`). Str(`b`, `B`), nil, "a", "A2", "c", "C1", "d", "D", "c", "C2", "e", "E"). Log(``) // supports conversion function ArgFields(l.Debug(), func(key any) (string, bool) { if k, ok := key.(string); ok { return k + "_converted", true } return "", false }, "a", "A", "b", "B", 123, "C"). Log(``) // passing an odd number of keys sets the last value to any(nil) ArgFields(l.Info(), nil, "a", "A", "b").Log(``) _ = w.Close() if err := <-out; err != nil { panic(err) }
Output: [notice] a=A b=B [alert] a=A b=B [crit] a=A1 a=A2 b=B c=C1 c=C2 d=D e=E [debug] a_converted=A b_converted=B [info] a=A b=<nil>
func MapFields ¶
func MapFields[K ~string, V any, R interface { Enabled() bool Field(key string, val any) R }](r R, m map[K]V) R
MapFields is a helper function that calls Builder.Field or Context.Field, for every element of a map, which must have keys with an underlying type of string. The field order is not stable, as it iterates on the map, without sorting the keys.
WARNING: The behavior of the Context.Field and Builder.Field methods may change without notice, to facilitate the addition of new field types.
Example ¶
// note that the order of keys is not stable (sorted only to make the test pass) w, out := sortedLineWriterSplitOnSpace(os.Stdout) defer func() { _ = w.Close() <-out }() // l is an instance of logiface.Logger l := newSimpleLogger(w, false) // supports logiface.Builder MapFields(l.Notice(), map[string]interface{}{ `a`: `A`, `b`: `B`, }).Log(``) // supports logiface.Context MapFields(l.Clone(), map[string]interface{}{ `a`: `A`, `b`: `B`, }).Logger().Alert(). Log(``) // supports fluent chaining MapFields(l.Crit(). Str(`a`, `A1`). Str(`b`, `B`), map[string]interface{}{ `a`: `A2`, `c`: `C1`, `d`: `D`}). Str(`c`, `C2`). Str(`e`, `E`). Log(``) // supports any map with string as the underlying key type type Stringish string type Mappy map[Stringish]int m := Mappy{ `a`: 1, `b`: 2, } MapFields(l.Build(99), m).Log(``) _ = w.Close() if err := <-out; err != nil { panic(err) }
Output: [notice] a=A b=B [alert] a=A b=B [crit] a=A1 a=A2 b=B c=C1 c=C2 d=D e=E [99] a=1 b=2
Types ¶
type Builder ¶
type Builder[E Event] struct { Event E // contains filtered or unexported fields }
Builder is used to build a log event, see Logger.Build, Logger.Info, etc.
All methods are safe to call on a nil receiver.
See also Context, which implements a common (sub)set of methods, for building structured log events, including Field ("smarter" than Interface), Interface (Event.AddField pass-through), and strongly-typed implementations such as Err and Str, that utilize the other Event.Add* methods (if implemented), with well-defined fallback behavior.
func (*Builder[E]) Any ¶
Any is an alias for Builder.Interface.
func (*Builder[E]) Base64 ¶
Base64 adds a []byte as a structured log field, using [Event.AddBase64Bytes] if available, otherwise falling back to directly encoding the []byte as a base64 string. The fallback behavior is intended to be the core behavior, with the [Event.AddBase64Bytes] method being an optimization.
If enc is nil or base64.StdEncoding, the behavior is the same as the JSON encoding of Protobuf's bytes scalar. See also [https://protobuf.dev/programming-guides/proto3/#json].
func (*Builder[E]) Call ¶
func (x *Builder[E]) Call(fn func(b *Builder[E])) *Builder[E]
Call is provided as a convenience, to facilitate code which uses the receiver explicitly, without breaking out of the fluent-style API.
Example use cases include access of the underlying Event implementation (to utilize functionality not mapped by logiface), or to skip building / formatting certain fields, based on if `b.Event.Level().Enabled()`.
This method is not implemented by Context.
func (*Builder[E]) Dur ¶
Dur adds a time.Duration as a structured log field, using Event.AddDuration if available, otherwise falling back to formatting the time.Duration as a string, formatted as a decimal in seconds (with unit), using the same semantics as the JSON encoding of Protobuf's "well known type", google.protobuf.Duration. In this fallback case, the behavior of Builder.Str is used, to add the field.
func (*Builder[E]) Enabled ¶
func (x *Builder[E]) Enabled() bool
Enabled indicates that this Builder was initialized by a Logger, using a writable Level, given the logger's configuration.
func (*Builder[E]) Err ¶
func (x *Builder[E]) Err(err error) *Builder[E]
Err adds an error as a structured log field, the key for which will either be determined by the Event.AddError method, or will be "err" if not implemented.
func (*Builder[E]) Field ¶
Field adds a field to the log event, making an effort to choose the most appropriate handler for the value.
WARNING: The behavior of this method may change without notice, to facilitate the addition of new field types.
Use the Interface method if you want a direct pass-through to the Event.AddField implementation.
func (*Builder[E]) Float32 ¶
Float32 adds a float32 as a structured log field, using Event.AddFloat32 if available, otherwise falling back to Event.AddField.
func (*Builder[E]) Int ¶
Int adds an int as a structured log field, using Event.AddInt if available, otherwise falling back to Event.AddField.
func (*Builder[E]) Interface ¶
Interface adds a structured log field, which will pass through to Event.AddField.
func (*Builder[E]) Log ¶
func (x *Builder[E]) Log(msg string)
Log logs an event, with the given message, using the provided level and modifier, if the relevant conditions are met (e.g. configured log level).
The field for the message will either be determined by the implementation, if Event.AddMessage is implemented, or the default field name "msg" will be used.
This method calls Builder.Release. This method is not implemented by Context.
func (*Builder[E]) LogFunc ¶
func (x *Builder[E]) LogFunc(fn func() string)
LogFunc logs an event, with the message returned by the given function, using the provided level and modifier, if the relevant conditions are met (e.g. configured log level).
The field for the message will either be determined by the implementation, if Event.AddMessage is implemented, or the default field name "msg" will be used.
Note that the function will not be called if, for example, the given log level is not enabled.
This method calls Builder.Release. This method is not implemented by Context.
func (*Builder[E]) Logf ¶
Logf logs an event, with the given message, using the provided level and modifier, if the relevant conditions are met (e.g. configured log level).
The field for the message will either be determined by the implementation, if Event.AddMessage is implemented, or the default field name "msg" will be used.
This method calls Builder.Release. This method is not implemented by Context.
func (*Builder[E]) Release ¶ added in v0.2.0
func (x *Builder[E]) Release()
Release returns the Builder to the pool, calling any user-defined EventReleaser to reset or release [Builder.Event] (e.g. if the concrete event implementation also uses a pool).
In most cases, it should not be necessary to call this directly. This method is exported to allow for more advanced use cases, such as when the Builder is used to build an event that is not logged, or when the Builder is used to build an event that is logged by a different logger implementation.
This method is called by other "terminal" methods, such as Builder.Log. This method is not implemented by Context.
func (*Builder[E]) Str ¶
Str adds a string as a structured log field, using Event.AddString if available, otherwise falling back to Event.AddField.
func (*Builder[E]) Time ¶
Time adds a time.Time as a structured log field, using Event.AddTime if available, otherwise falling back to formatting the time.Time as a string in the RFC 3339 format, using the same semantics as the JSON encoding of Protobuf's "well known type", google.protobuf.Timestamp. In this fallback case, the behavior of Builder.Str is used, to add the field.
type Context ¶
type Context[E Event] struct { Modifiers ModifierSlice[E] // contains filtered or unexported fields }
Context is used to build a sub-logger, see Logger.Clone.
All methods are safe to call on a nil receiver.
See also Builder, which implements a common (sub)set of methods, for building structured log events, including Field ("smarter" than Interface), Interface (Event.AddField pass-through), and strongly-typed implementations that utilize the other Event.Add* methods (if implemented), with well-defined fallback behavior.
func (*Context[E]) Any ¶
Any is an alias for Context.Interface.
func (*Context[E]) Base64 ¶
Base64 adds a []byte as a structured log field, using [Event.AddBase64Bytes] if available, otherwise falling back to directly encoding the []byte as a base64 string. The fallback behavior is intended to be the core behavior, with the [Event.AddBase64Bytes] method being an optimization.
If enc is nil or base64.StdEncoding, the behavior is the same as the JSON encoding of Protobuf's bytes scalar. See also [https://protobuf.dev/programming-guides/proto3/#json].
func (*Context[E]) Dur ¶
Dur adds a time.Duration as a structured log field, using Event.AddDuration if available, otherwise falling back to formatting the time.Duration as a string, formatted as a decimal in seconds (with unit), using the same semantics as the JSON encoding of Protobuf's "well known type", google.protobuf.Duration. In this fallback case, the behavior of Context.Str is used, to add the field.
func (*Context[E]) Enabled ¶
Enabled indicates that this Context was initialized from a writable Logger, via Logger.Clone.
func (*Context[E]) Err ¶
Err adds an error as a structured log field, the key for which will either be determined by the Event.AddError method, or will be "err" if not implemented.
func (*Context[E]) Field ¶
Field adds a field to the log context, making an effort to choose the most appropriate handler for the value.
WARNING: The behavior of this method may change without notice, to facilitate the addition of new field types.
Use the Interface method if you want a direct pass-through to the Event.AddField implementation.
func (*Context[E]) Float32 ¶
Float32 adds a float32 as a structured log field, using Event.AddFloat32 if available, otherwise falling back to Event.AddField.
func (*Context[E]) Int ¶
Int adds an int as a structured log field, using Event.AddInt if available, otherwise falling back to Event.AddField.
func (*Context[E]) Interface ¶
Interface adds a structured log field, which will pass through to Event.AddField.
func (*Context[E]) Logger ¶
Logger returns the underlying (sub)logger, or nil.
Note that the returned logger will apply all parent modifiers, including [Context.Modifiers]. This method is intended to be used to get the actual sub-logger, after building the context that sub-logger is to apply.
This method is not implemented by Builder.
func (*Context[E]) Str ¶
Str adds a string as a structured log field, using Event.AddString if available, otherwise falling back to Event.AddField.
func (*Context[E]) Time ¶
Time adds a time.Time as a structured log field, using Event.AddTime if available, otherwise falling back to formatting the time.Time as a string in the RFC 3339 format, using the same semantics as the JSON encoding of Protobuf's "well known type", google.protobuf.Timestamp. In this fallback case, the behavior of Context.Str is used, to add the field.
type Event ¶
type Event interface { // Level returns the level of the event. // It must be the same as originally provided to the factory. Level() Level // AddField adds a field to the event, for structured logging. // How fields are handled is implementation specific. AddField(key string, val any) // AddMessage sets the log message for the event, returning false if unimplemented. // The field or output structure of the log message is implementation specific. AddMessage(msg string) bool // AddError adds an error to the event, returning false if unimplemented. // The field or output structure of the log message is implementation specific. AddError(err error) bool // AddString adds a field of type string. It's an optional optimisation. AddString(key string, val string) bool // AddInt adds a field of type int. It's an optional optimisation. AddInt(key string, val int) bool // AddFloat32 adds a field of type float32. It's an optional optimisation. AddFloat32(key string, val float32) bool // AddTime adds a field of type time.Time. It's an optional optimisation. AddTime(key string, val time.Time) bool // AddDuration adds a field of type time.Duration. It's an optional optimisation. AddDuration(key string, val time.Duration) bool // AddBase64Bytes adds bytes as a field, to be base64 encoded. // The enc param will always be non-nil, and is the encoding to use. // This abstraction is provided to allow implementations to use the // most appropriate method, of the enc param. // It's an optional optimisation. AddBase64Bytes(key string, val []byte, enc *base64.Encoding) bool // contains filtered or unexported methods }
Event models the integration with the logging framework.
The methods Level and AddField are mandatory.
Implementations must have a zero value that doesn't panic when calling Level, in which instance it must return LevelDisabled.
All implementations must embed UnimplementedEvent, as it provides support for optional methods (and facilitates additional optional methods being added, without breaking changes).
Adding a new log field type ¶
In general, types of log fields are added via the implementation of new methods, which should be present in all of Builder, Context, and Event, though the Event method will differ.
The method name and arguments, for Builder and Context, are typically styled after the equivalent provided by zerolog, though they need not be. The arguments for Event are typically identical, returning a bool (to indicate support), with the method name being somewhat arbitrary, but ideally descriptive and consistent, e.g. Add<full type name>. The Event interface isn't used directly, by end users, making brevity unimportant.
These are common development tasks, when a new field type is added:
- Add the new field type method to the Event interface (e.g. AddDuration)
- Add the new field type method to the UnimplementedEvent struct (return false)
- Add the calling/fallback behavior as a new unexported method of the internal modifierMethods struct (e.g. dur)
- Update the (internal) modifierMethods.Field method, with type case(s) using 3., for the new field type
- Add a new (internal) method to the modifierMethods struct, using 3., named per Builder and Context (e.g. Dur)
- Add to each of Builder and Context a method named the same as and using 5. (e.g. Dur)
- Add the Event method to mockComplexEvent in mock_test.go
- Run make in the root of the git repository, fix any issues
- Add appropriate Field and specific method calls (e.g. Dur) to fluentCallerTemplate in mock_test.go (note: update the T generic interface)
- Fix all test cases that fail
- Update the testsuite module to include the new field type (e.g. throw it on eventTemplate1 in templates.go)
- Run make in the root of the git repository, everything should still pass
- Implement new field type in all relevant implementation modules (e.g. logiface/zerolog)
- Fix any issues with the test harness implementations, which may require adding additional functionality to logiface/testsuite, see also normalizeEvent
- Consider adding or updating benchmarks, e.g. the comparison (vs direct use) benchmarks in logiface/zerolog
type EventFactory ¶
EventFactory initializes a new Event, for Logger instances.
As Builder instances are pooled, implementations may need to implement EventReleaser as a way to clear references to objects that should be garbage collected.
Note that it may be desirable to use a pool of events, to reduce unnecessary allocations. In this case, EventReleaser should be implemented, to return the event to the pool.
type EventFactoryFunc ¶
EventFactoryFunc implements EventFactory.
func NewEventFactoryFunc ¶
NewEventFactoryFunc is an alias provided as a convenience, to make it easier to cast a function to an EventFactoryFunc.
It's equivalent to EventFactoryFunc[E](f), which is more verbose, as it cannot infer the type.
See also LoggerFactory.NewEventFactoryFunc.
type EventReleaser ¶
type EventReleaser[E Event] interface { ReleaseEvent(event E) }
EventReleaser is an optional implementation that may be used to either "reset" or "release" concrete implementations of Event.
Use this interface to, for example, clear references to which should be garbage collected, or return references to pool(s).
type EventReleaserFunc ¶
type EventReleaserFunc[E Event] func(event E)
EventReleaserFunc implements EventReleaser.
func NewEventReleaserFunc ¶
func NewEventReleaserFunc[E Event](f func(event E)) EventReleaserFunc[E]
NewEventReleaserFunc is an alias provided as a convenience, to make it easier to cast a function to an EventReleaserFunc.
It's equivalent to EventReleaserFunc[E](f), which is more verbose, as it cannot infer the type.
See also LoggerFactory.NewEventFactoryFunc.
func (EventReleaserFunc[E]) ReleaseEvent ¶
func (x EventReleaserFunc[E]) ReleaseEvent(event E)
type Level ¶
type Level int8
Level models the severity level of a log message.
Valid Level values include all the syslog log levels, as defined in RFC 5424, with the addition of a "trace" level (LevelTrace), which is expected to use abnormal output mechanisms (e.g. a separate log file). Negative values are treated as disabled, see also LevelDisabled.
Also supported are "custom levels" which are positive integer values, from 9 to 127, inclusive. Custom levels are handled differently than regular levels, in that they are not affected by the log level set on the Logger.
Syslog severity levels ¶
Value Severity Keyword Deprecated keywords Description Condition 0 Emergency emerg panic[9] System is unusable A panic condition.[10] 1 Alert alert Action must be taken immediately A condition that should be corrected immediately, such as a corrupted system database.[10] 2 Critical crit Critical conditions Hard device errors.[10] 3 Error err error[9] Error conditions 4 Warning warning warn[9] Warning conditions 5 Notice notice Normal but significant conditions Conditions that are not error conditions, but that may require special handling.[10] 6 Informational info Informational messages Confirmation that the program is working as expected. 7 Debug debug Debug-level messages Messages that contain information normally of use only when debugging a program.[10] [9] https://linux.die.net/man/5/syslog.conf [10] https://pubs.opengroup.org/onlinepubs/009695399/functions/syslog.html
Mapping levels to logger implementations ¶
Regarding mapping, to log levels in other systems, the recommended approach is:
- LevelEmergency => PANIC
- LevelAlert => FATAL
- LevelCritical => ERROR
- LevelError => ERROR
- LevelWarning => WARN
- LevelNotice => WARN
- LevelInformational => INFO
- LevelDebug => DEBUG
- LevelTrace => TRACE (or disabled)
const ( // LevelDisabled is a special value that disables logging. LevelDisabled Level = iota - 1 // LevelEmergency is a syslog level. // Indicates that the system is unusable, a panic condition. // // This log level should be used with caution, as it tends to be mapped to // "panic", which, in at least several logger implementations, will call // panic(). See also the recommended mappings, documented under Level. LevelEmergency // LevelAlert is a syslog level. // Indicates that action must be taken immediately, or a condition that // should be corrected immediately, such as a corrupted system database. // // This log level should be used with caution, as it tends to be mapped to // "fatal", which, in at least several logger implementations, will call // os.Exit(1). See also the recommended mappings, documented under Level. LevelAlert // LevelCritical is a syslog level. // Indicates critical conditions, such as hard device errors. LevelCritical // LevelError is a syslog level. // Indicates error conditions. LevelError // LevelWarning is a syslog level. // Indicates warning conditions. LevelWarning // LevelNotice is a syslog level. // Indicates normal but significant conditions, which may require special // handling or attention, such as startup messages. LevelNotice // LevelInformational is a syslog level. // Indicates informational messages, which confirm that the program is // working as expected. LevelInformational // LevelDebug is a syslog level. // Indicates a message contains information normally of use only when // debugging a program. LevelDebug // LevelTrace is not a syslog level, and is intended to be used only when // running using abnormal output mechanisms (e.g. a dedicated log file, as // part of a debugging session). // It is expected to be more verbose than LevelDebug, but serves a similar // purpose. LevelTrace )
func (Level) Custom ¶
Custom returns true if the Level is a custom level (greater than LevelTrace).
Example ¶
p := func(level Level) { fmt.Printf("%q (%d): %v\n", level, level, level.Custom()) } p(math.MinInt8) p(-2) p(LevelDisabled) p(LevelEmergency) p(LevelAlert) p(LevelCritical) p(LevelError) p(LevelWarning) p(LevelNotice) p(LevelInformational) p(LevelDebug) p(LevelTrace) p(9) p(math.MaxInt8)
Output: "-128" (-128): false "-2" (-2): false "disabled" (-1): false "emerg" (0): false "alert" (1): false "crit" (2): false "err" (3): false "warning" (4): false "notice" (5): false "info" (6): false "debug" (7): false "trace" (8): false "9" (9): true "127" (127): true
func (Level) Enabled ¶
Enabled returns true if the Level is enabled (greater than or equal to 0).
Example ¶
p := func(level Level) { fmt.Printf("%q (%d): %v\n", level, level, level.Enabled()) } p(math.MinInt8) p(-2) p(LevelDisabled) p(LevelEmergency) p(LevelAlert) p(LevelCritical) p(LevelError) p(LevelWarning) p(LevelNotice) p(LevelInformational) p(LevelDebug) p(LevelTrace) p(9) p(math.MaxInt8)
Output: "-128" (-128): false "-2" (-2): false "disabled" (-1): false "emerg" (0): true "alert" (1): true "crit" (2): true "err" (3): true "warning" (4): true "notice" (5): true "info" (6): true "debug" (7): true "trace" (8): true "9" (9): true "127" (127): true
func (Level) String ¶
String implements fmt.Stringer, note that it uses the short keyword (for the actual syslog levels).
func (Level) Syslog ¶
Syslog returns true if the Level is a syslog level.
Example ¶
p := func(level Level) { fmt.Printf("%q (%d): %v\n", level, level, level.Syslog()) } p(math.MinInt8) p(-2) p(LevelDisabled) p(LevelEmergency) p(LevelAlert) p(LevelCritical) p(LevelError) p(LevelWarning) p(LevelNotice) p(LevelInformational) p(LevelDebug) p(LevelTrace) p(9) p(math.MaxInt8)
Output: "-128" (-128): false "-2" (-2): false "disabled" (-1): false "emerg" (0): true "alert" (1): true "crit" (2): true "err" (3): true "warning" (4): true "notice" (5): true "info" (6): true "debug" (7): true "trace" (8): false "9" (9): false "127" (127): false
type Logger ¶
type Logger[E Event] struct { // contains filtered or unexported fields }
Logger is the core logger implementation, and constitutes the core functionality, provided by this package.
func New ¶
New constructs a new Logger instance.
Configure the logger using either the With* prefixed functions (or methods of LoggerFactory, e.g. accessible via the L global), or via composite options, implemented in external packages, e.g. logger integrations.
See also LoggerFactory.New and L (an instance of LoggerFactory[Event]{}).
func (*Logger[E]) Alert ¶
func (x *Logger[E]) Alert() *Builder[E]
Alert is an alias for Logger.Build(LevelAlert).
func (*Logger[E]) Build ¶
Build returns a new Builder for the given level, note that it may return nil (e.g. if the level is disabled).
See also the methods Info, Debug, etc.
func (*Logger[E]) Clone ¶
Clone returns a new Context, which is a mechanism to configure a sub-logger, which will be available via Context.Logger, note that it may return nil.
func (*Logger[E]) Crit ¶
func (x *Logger[E]) Crit() *Builder[E]
Crit is an alias for Logger.Build(LevelCritical).
func (*Logger[E]) Debug ¶
func (x *Logger[E]) Debug() *Builder[E]
Debug is an alias for Logger.Build(LevelDebug).
func (*Logger[E]) Emerg ¶
func (x *Logger[E]) Emerg() *Builder[E]
Emerg is an alias for Logger.Build(LevelEmergency).
func (*Logger[E]) Err ¶
func (x *Logger[E]) Err() *Builder[E]
Err is an alias for Logger.Build(LevelError).
func (*Logger[E]) Info ¶
func (x *Logger[E]) Info() *Builder[E]
Info is an alias for Logger.Build(LevelInformational).
func (*Logger[E]) Log ¶
Log directly performs a Log operation, without the "fluent builder" pattern.
Example ¶
An example of how to use the non-fluent Log method.
l := newSimpleLogger(os.Stdout, false).Logger() if err := l.Log(LevelDisabled, nil); err != ErrDisabled { panic(err) } else { fmt.Printf("disabled level wont log: %v\n", err) } // note: the method under test is intended for external log integrations // (this isn't a real use case) with := func(fields ...any) ModifierFunc[Event] { return func(e Event) error { if len(fields)%2 != 0 { return fmt.Errorf("invalid number of fields: %d", len(fields)) } for i := 0; i < len(fields); i += 2 { e.AddField(fmt.Sprint(fields[i]), fields[i+1]) } return nil } } fmt.Print(`single modifier provided in the call: `) if err := l.Log(LevelNotice, with( `a`, `A`, `b`, `B`, )); err != nil { panic(err) } fmt.Print(`cloned logger modifier + modifier in the call: `) if err := l.Clone().Str(`a`, `A1`).Logger().Log(LevelNotice, with(`a`, `A2`)); err != nil { panic(err) } fmt.Print(`just cloned logger modifier: `) if err := l.Clone().Str(`a`, `A1`).Logger().Log(LevelNotice, nil); err != nil { panic(err) } fmt.Print(`no logger modifier: `) if err := l.Log(LevelNotice, nil); err != nil { panic(err) } fmt.Printf("modifier error: %v\n", l.Log(LevelNotice, with(`willerror`))) fmt.Printf("internal modifier error guards provided modifier: %v\n", New( simpleLoggerFactory.WithEventFactory(NewEventFactoryFunc(mockSimpleEventFactory)), simpleLoggerFactory.WithWriter(&mockSimpleWriter{Writer: os.Stdout}), simpleLoggerFactory.WithModifier(NewModifierFunc(func(e *mockSimpleEvent) error { return fmt.Errorf(`some internal modifier error`) })), ).Log(LevelNotice, ModifierFunc[*mockSimpleEvent](func(e *mockSimpleEvent) error { panic(`should not be called`) })))
Output: disabled level wont log: logger disabled single modifier provided in the call: [notice] a=A b=B cloned logger modifier + modifier in the call: [notice] a=A1 a=A2 just cloned logger modifier: [notice] a=A1 no logger modifier: [notice] modifier error: invalid number of fields: 1 internal modifier error guards provided modifier: some internal modifier error
func (*Logger[E]) Logger ¶
Logger returns a new generified logger.
Use this for greater compatibility, but sacrificing ease of using the underlying library directly.
func (*Logger[E]) Notice ¶
func (x *Logger[E]) Notice() *Builder[E]
Notice is an alias for Logger.Build(LevelNotice).
type LoggerFactory ¶
type LoggerFactory[E Event] struct{}
LoggerFactory provides aliases for package functions including New, as well as the functions returning Option values. This allows the Event type to be omitted from all but one location.
See also L, an instance of LoggerFactory[Event]{}.
func (LoggerFactory[E]) LevelAlert ¶
func (LoggerFactory[E]) LevelAlert() Level
LevelAlert returns LevelAlert, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) LevelCritical ¶
func (LoggerFactory[E]) LevelCritical() Level
LevelCritical returns LevelCritical, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) LevelDebug ¶
func (LoggerFactory[E]) LevelDebug() Level
LevelDebug returns LevelDebug, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) LevelDisabled ¶
func (LoggerFactory[E]) LevelDisabled() Level
LevelDisabled returns LevelDisabled, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) LevelEmergency ¶
func (LoggerFactory[E]) LevelEmergency() Level
LevelEmergency returns LevelEmergency, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) LevelError ¶
func (LoggerFactory[E]) LevelError() Level
LevelError returns LevelError, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) LevelInformational ¶
func (LoggerFactory[E]) LevelInformational() Level
LevelInformational returns LevelInformational, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) LevelNotice ¶
func (LoggerFactory[E]) LevelNotice() Level
LevelNotice returns LevelNotice, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) LevelTrace ¶
func (LoggerFactory[E]) LevelTrace() Level
LevelTrace returns LevelTrace, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) LevelWarning ¶
func (LoggerFactory[E]) LevelWarning() Level
LevelWarning returns LevelWarning, and is provided as a convenience for implementation packages, so end users don't have to import logiface.
func (LoggerFactory[E]) New ¶
func (LoggerFactory[E]) New(options ...Option[E]) *Logger[E]
New is an alias of the package function of the same name.
See also LoggerFactory.New and L (an instance of LoggerFactory[Event]{}).
func (LoggerFactory[E]) NewEventFactoryFunc ¶
func (LoggerFactory[E]) NewEventFactoryFunc(f func(level Level) E) EventFactoryFunc[E]
NewEventFactoryFunc is an alias provided as a convenience, to make it easier to cast a function to an EventFactoryFunc.
It's equivalent to EventFactoryFunc[E](f), which is more verbose, as it requires specifying the type, which, for this method, comes from the receiver.
See also logiface.NewEventFactoryFunc.
func (LoggerFactory[E]) NewEventReleaserFunc ¶
func (LoggerFactory[E]) NewEventReleaserFunc(f func(event E)) EventReleaserFunc[E]
NewEventReleaserFunc is an alias provided as a convenience, to make it easier to cast a function to an EventReleaserFunc.
It's equivalent to EventReleaserFunc[E](f), which is more verbose, as it requires specifying the type, which, for this method, comes from the receiver.
See also logiface.NewEventReleaserFunc.
func (LoggerFactory[E]) NewModifierFunc ¶
func (LoggerFactory[E]) NewModifierFunc(f func(event E) error) ModifierFunc[E]
NewModifierFunc is an alias provided as a convenience, to make it easier to cast a function to a ModifierFunc.
It's equivalent to ModifierFunc[E](f), which is more verbose, as it requires specifying the type, which, for this method, comes from the receiver.
See also logiface.NewModifierFunc.
func (LoggerFactory[E]) NewModifierSlice ¶
func (LoggerFactory[E]) NewModifierSlice(s ...Modifier[E]) ModifierSlice[E]
NewModifierSlice is an alias provided as a convenience, to make it easier to initialize a ModifierSlice.
See also logiface.NewModifierSlice.
func (LoggerFactory[E]) NewWriterFunc ¶
func (LoggerFactory[E]) NewWriterFunc(f func(event E) error) WriterFunc[E]
NewWriterFunc is an alias provided as a convenience, to make it easier to cast a function to a WriterFunc.
It's equivalent to WriterFunc[E](f), which is more verbose, as it requires specifying the type, which, for this method, comes from the receiver.
See also logiface.NewWriterFunc.
func (LoggerFactory[E]) NewWriterSlice ¶
func (LoggerFactory[E]) NewWriterSlice(s ...Writer[E]) WriterSlice[E]
NewWriterSlice is an alias provided as a convenience, to make it easier to initialize a WriterSlice.
See also logiface.NewWriterSlice.
func (LoggerFactory[E]) WithEventFactory ¶
func (LoggerFactory[E]) WithEventFactory(factory EventFactory[E]) Option[E]
WithEventFactory is an alias of the package function of the same name.
func (LoggerFactory[E]) WithEventReleaser ¶
func (LoggerFactory[E]) WithEventReleaser(releaser EventReleaser[E]) Option[E]
WithEventReleaser is an alias of the package function of the same name.
func (LoggerFactory[E]) WithLevel ¶
func (LoggerFactory[E]) WithLevel(level Level) Option[E]
WithLevel is an alias of the package function of the same name.
func (LoggerFactory[E]) WithModifier ¶
func (LoggerFactory[E]) WithModifier(modifier Modifier[E]) Option[E]
WithModifier is an alias of the package function of the same name.
func (LoggerFactory[E]) WithOptions ¶
func (LoggerFactory[E]) WithOptions(options ...Option[E]) Option[E]
WithOptions is an alias of the package function of the same name.
func (LoggerFactory[E]) WithWriter ¶
func (LoggerFactory[E]) WithWriter(writer Writer[E]) Option[E]
WithWriter is an alias of the package function of the same name.
type Modifier ¶
Modifier is used to model the configuration of a log event, e.g. adding fields, including the message.
type ModifierFunc ¶
ModifierFunc implements Modifier.
func NewModifierFunc ¶
NewModifierFunc is an alias provided as a convenience, to make it easier to cast a function to a ModifierFunc.
It's equivalent to ModifierFunc[E](f), which is more verbose, as it cannot infer the type.
See also LoggerFactory.NewModifierFunc.
type ModifierSlice ¶
ModifierSlice combines Modifier values, calling each in turn, returning the first non-nil error.
func NewModifierSlice ¶
func NewModifierSlice[E Event](s ...Modifier[E]) ModifierSlice[E]
NewModifierSlice is an alias provided as a convenience, to make it easier to initialize a ModifierSlice.
See also LoggerFactory.NewModifierSlice.
type Option ¶
type Option[E Event] func(c *loggerConfig[E])
Option is a configuration option for constructing Logger instances, using the New function, or it's alias(es), e.g. LoggerFactory.New.
func WithEventFactory ¶
func WithEventFactory[E Event](factory EventFactory[E]) Option[E]
WithEventFactory configures the logger's EventFactory.
See also LoggerFactory.WithEventFactory and L (an instance of LoggerFactory[Event]{}).
func WithEventReleaser ¶
func WithEventReleaser[E Event](releaser EventReleaser[E]) Option[E]
WithEventReleaser configures the logger's EventReleaser.
See also LoggerFactory.WithEventReleaser and L (an instance of LoggerFactory[Event]{}).
func WithLevel ¶
WithLevel configures the logger's Level.
Level will be used to filter events that are mapped to a syslog-defined level. Events with a custom level will always be logged.
See also LoggerFactory.WithLevel and L (an instance of LoggerFactory[Event]{}).
func WithModifier ¶
func WithModifier[E Event](modifier Modifier[E]) Option[E]
WithModifier configures the logger's Modifier, appending it to an internal ModifierSlice.
See also LoggerFactory.WithModifier and L (an instance of LoggerFactory[Event]{}).
func WithOptions ¶
func WithOptions[E Event](options ...Option[E]) Option[E]
WithOptions combines multiple Option values into one.
See also LoggerFactory.WithOptions and L (an instance of LoggerFactory[Event]{}).
func WithWriter ¶
func WithWriter[E Event](writer Writer[E]) Option[E]
WithWriter configures the logger's Writer, prepending it to an internal WriterSlice.
See also LoggerFactory.WithWriter and L (an instance of LoggerFactory[Event]{}).
type UnimplementedEvent ¶
type UnimplementedEvent struct{}
UnimplementedEvent must be embedded in every Event implementation. It provides implementation of methods that are optional.
func (UnimplementedEvent) AddBase64Bytes ¶
func (UnimplementedEvent) AddDuration ¶
func (UnimplementedEvent) AddDuration(string, time.Duration) bool
func (UnimplementedEvent) AddError ¶
func (UnimplementedEvent) AddError(error) bool
func (UnimplementedEvent) AddFloat32 ¶
func (UnimplementedEvent) AddFloat32(string, float32) bool
func (UnimplementedEvent) AddMessage ¶
func (UnimplementedEvent) AddMessage(string) bool
type Writer ¶
Writer writes out / finalizes an event.
Event MUST NOT be retained or modified after the call.
type WriterFunc ¶
WriterFunc implements Writer.
func NewWriterFunc ¶
NewWriterFunc is an alias provided as a convenience, to make it easier to cast a function to a WriterFunc.
It's equivalent to WriterFunc[E](f), which is more verbose, as it cannot infer the type.
See also LoggerFactory.NewWriterFunc.
type WriterSlice ¶
WriterSlice combines writers, returning success on the first writer that succeeds, returning the first error that isn't ErrDisabled, or ErrDisabled if every writer returns ErrDisabled (or if empty).
WARNING: ErrDisabled must be returned directly (not wrapped).
func NewWriterSlice ¶
func NewWriterSlice[E Event](s ...Writer[E]) WriterSlice[E]
NewWriterSlice is an alias provided as a convenience, to make it easier to initialize a WriterSlice.
See also LoggerFactory.NewWriterSlice.