Documentation
¶
Overview ¶
Package logger provides tooling for structured logging. With logger, you can use context to add logging details to your call stack.
Index ¶
- func ContextWith(ctx context.Context, lds ...Detail) context.Context
- func RegisterFieldType[T any](mapping func(T) Detail) func()
- func Stub(tb testingTB) (*Logger, StubOutput)
- type Detail
- type Fields
- type HijackFunc
- type LazyDetail
- type Level
- type Logger
- func (l *Logger) AsyncLogging() func()
- func (l *Logger) Clone() *Logger
- func (l *Logger) Debug(ctx context.Context, msg string, ds ...Detail)
- func (l *Logger) Error(ctx context.Context, msg string, ds ...Detail)
- func (l *Logger) Fatal(ctx context.Context, msg string, ds ...Detail)
- func (l *Logger) Info(ctx context.Context, msg string, ds ...Detail)
- func (l *Logger) Warn(ctx context.Context, msg string, ds ...Detail)
- type StubOutput
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ContextWith ¶
Example ¶
package main import ( "context" "go.llib.dev/frameless/pkg/logging" ) func main() { ctx := context.Background() ctx = logging.ContextWith(ctx, logging.Fields{ "foo": "bar", "baz": "qux", }) l := &logging.Logger{} l.Info(ctx, "message") // will have details from the context }
Output:
func RegisterFieldType ¶
RegisterFieldType allows you to register T type and have it automatically conerted into a Detail value when it is passed as a Field value for logging.
Example (AsLoggingDetails) ¶
package main import ( "go.llib.dev/frameless/pkg/logging" ) func main() { type MyEntity struct { ID string NonSensitiveData string SensitiveData string } // at package level var _ = logging.RegisterFieldType(func(ent MyEntity) logging.Detail { return logging.Fields{ "id": ent.ID, "data": ent.NonSensitiveData, } }) }
Output:
func Stub ¶
func Stub(tb testingTB) (*Logger, StubOutput)
Stub the logger.Default and return the buffer where the logging output will be recorded. Stub will restore the logger.Default after the test.
Types ¶
type Detail ¶
type Detail interface {
// contains filtered or unexported methods
}
Detail is a logging detail that enrich the logging message with additional contextual detail.
func ErrField ¶
Example ¶
package main import ( "context" "errors" "go.llib.dev/frameless/pkg/logging" ) func main() { ctx := context.Background() err := errors.New("boom") var l logging.Logger l.Error(ctx, "task failed successfully", logging.ErrField(err)) }
Output:
func Field ¶
Field creates a single key value pair based logging detail. It will enrich the log entry with a value in the key you gave.
Example ¶
package main import ( "context" "go.llib.dev/frameless/pkg/logging" ) func main() { var l logging.Logger l.Error(context.Background(), "msg", logging.Field("key1", "value"), logging.Field("key2", "value")) }
Output:
type Fields ¶
Fields is a collection of field that you can add to your loggig record. It will enrich the log entry with a value in the key you gave.
Example ¶
package main import ( "context" "go.llib.dev/frameless/pkg/logging" ) func main() { var l logging.Logger l.Error(context.Background(), "msg", logging.Fields{ "key1": "value", "key2": "value", }) }
Output:
type HijackFunc ¶
type LazyDetail ¶ added in v0.239.0
type LazyDetail func() Detail
LazyDetail lets you add logging details that aren’t evaluated until the log is actually created. This is useful when you want to add fields to a debug log that take effort to calculate, but would be skipped in a production environment because of the logging level.
Example ¶
package main import ( "context" "go.llib.dev/frameless/pkg/logging" ) func main() { var l logging.Logger l.Debug(context.Background(), "msg", logging.LazyDetail(func() logging.Detail { // only runs if the logging level is enabled and the logging details are collected return logging.Field("key1", "value") })) }
Output:
type Logger ¶
type Logger struct { Out io.Writer // Level is the logging level. // The default Level is LevelInfo. Level Level Separator string MessageKey string LevelKey string TimestampKey string // MarshalFunc is used to serialise the logging message event. // When nil it defaults to JSON format. MarshalFunc func(any) ([]byte, error) // KeyFormatter will be used to format the logging field keys KeyFormatter func(string) string // Hijack will hijack the logging and instead of letting it logged out to the Out, // the logging will be done with the Hijack function. // This is useful if you want to use your own choice of logging, // but also packages that use this logging package. Hijack HijackFunc TestingTB testingTB // FlushTimeout is a deadline time for async logging to tell how much time it should wait with batching. // // Default: 1s FlushTimeout time.Duration // contains filtered or unexported fields }
func (*Logger) AsyncLogging ¶
func (l *Logger) AsyncLogging() func()
AsyncLogging will change the logging strategy from sync to async. This makes the log calls such as Logger.Info not wait on io operations. The AsyncLogging function call is where the async processing will happen, You should either run it in a separate goroutine, or use it with the tasker package. After the AsyncLogging returned, the logger returns to log synchronously.
Example ¶
package main import ( "context" "go.llib.dev/frameless/pkg/logging" ) func main() { ctx := context.Background() l := logging.Logger{} defer l.AsyncLogging()() l.Info(ctx, "this log message is written out asynchronously") }
Output: