golflog

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 15, 2022 License: Apache-2.0 Imports: 11 Imported by: 0

README

golflog GoDoc Build Status

golflog is a logging utility package built around go-logr. It's main use is a higher level api for building context based logging iteratively and stored in context.Context.

Installation

go get -u github.com/floatme-corp/golflog

Use

As close to your application entrypoint or initial context creation, create a Configurator and logr.Logger, then set that logger in the context.Context:

import (
    "context"
    "fmt"

    "github.com/floatme-corp/golflog"
)

func main() {
    configurator := golflog.NewZapProductionConfigurator()
    verbosity := 0

    logger, err := golflog.NewLogger(configurator, "RootLoggerName", verbosity)
    if err != nil {
        panic(fmt.Sprintf("runtime error: failed to setup logging: %s", err))
    }

    ctx := golflog.NewContext(context.Background(), logger)

    ...
}

Later if your application has another section, such as a Queue handler, you can set that in the logger name:

func HandleQueue(ctx context.Context) {
    ctx = golflog.ContextWithName(ctx, "Queue")
}

All messages logged from that point forware will have the name added to the existing name: RootLoggerName.Queue.

Additional values can be setup as well for future logging:

func HandleUser(ctx context.Context, userID string) {
    ctx = golflog.ContextWithValues(ctx, "user_id", userID)
}

Funcitons are guaranteed to be able to get a logger from any context:

func randoFunc(ctx context.Context) {
    log := golflog.AlwaysFromContext(ctx)
    log.Info("my log message")
}

If the context does not have a logger associated with it golflog will create a fallback logger with the default configuration. If that fails it will fallback to logging via fmt.Fprintln to os.Stdout

golflog provides helpers to create a log and a context with a name, values, or both:

func randoFunc(ctx context.Context) {
    // for tracing logs from this function
    ctx, log := golflog.WithName(ctx, "randoFunc")
    log.Info("my log message") // logs `randoFunc "msg"="my log message"`
}

// assume you have the important value `foo`
func randoFunc(ctx context.Context, importantValue string) {
    // for always seeing important value in future logs with this context
    ctx, log := golflog.WithValues(ctx, "important-value", importantValue)
    log.Info("my log message")
    // logs `"msg"="my log message" "important-value"="foo"`
}

func randoFunc(ctx context.Context, importantValue string) {
    ctx, log := golflog.WithNameAndValues(
        ctx,
        "randoFunc",
        "important-value", importantValue,
    )
    log.Info("my log message")
    // logs `randoFunc "msg"="my log message" "important-value"="foo"`
}
Logging Convenience Helpers

Info and Error convenience helpers are provided to log or report an error to the logger in the context.

func randoFunc(ctx context.Context) {
    golflog.Info(ctx, "message", "key", "value")

    ...

    golflog.Error(ctx, err, "message", "key, "value")
}

A Wrap helper will log the message at the info level and return a new error wrapping the err with message.

func randoFunc(ctx context.Context) {
    ...

    if err != nil {
        // Same as:
        // golflog.Error(ctx, err, "message", "key, "value")
        // return fmt.Errorf("%s: %w", message, err)
        return golflog.Wrap(ctx, err, "message", "key, "value")
    }
}
Env setup

An alternative to calling golflog.NewLogger with the parameters, is to call NewLoggerFromEnv and give it only the root name:

import (
    "context"
    "fmt"

    "github.com/floatme-corp/golflog
)

func main() {
    logger, err := golflog.NewLoggerFromEnv("RootLoggerName")
    if err != nil {
        panic(fmt.Sprintf("runtime error: failed to setup logging: %s", err))
    }

    ctx := golflog.NewContext(context.Background(), logger)

    ...
}

NewLoggerFromEnv uses the environment variables LOG_PRODUCTION, LOG_IMPLEMENTATION, and LOG_VERBOSITY to configure the logger. If they do not exist, it will default to configuring a production logger, with a zap Configurator at 0 verbosity (normal / info level).


Released under the Apache 2.0 License.

Documentation

Index

Constants

View Source
const (
	LogProduction     = "LOG_PRODUCTION"
	LogImplementation = "LOG_IMPLEMENTATION"
	LogVerbosity      = "LOG_VERBOSITY"
)
View Source
const (
	// MaxLevel is the maximum logging level supported. All verbosity values higher will be
	// clamped to this value.
	MaxLevel = 127

	// MinLevel is the minimum logging level supported. All verbosity values lower will be
	// clamped to this value.
	MinLevel = 0
)

Variables

View Source
var DefaultFallbackOutput io.Writer = os.Stdout

DefaultFallbackOutput is the default io stream jfor fallback logging. nolint: gochecknoglobals // Allow for testing

View Source
var ErrUnknownImplementation = errors.New("unknown implementation")

Functions

func AlwaysFromContext

func AlwaysFromContext(ctx context.Context) logr.Logger

AlwaysFromContext retrieves the logger from the context, if it is not found a new production logger at `MaxLevel` will be returned. If that fails a `fmt.Println` based logger is returned. nolint:contextcheck // ALWAYS!

func ContextWithName

func ContextWithName(ctx context.Context, name string) context.Context

ContextWithName returns a context with the name set in its logger.

func ContextWithValues

func ContextWithValues(ctx context.Context, keysAndValues ...interface{}) context.Context

ContextWithValues returns a context with the values set in its logger.

func Error added in v1.2.0

func Error(
	ctx context.Context,
	err error,
	message string,
	keysAndValues ...interface{},
)

Error gets a logger from the given context and logs the error and message and optional values.

func Info added in v1.1.0

func Info(
	ctx context.Context,
	message string,
	keysAndValues ...interface{},
)

Info gets a logger from the given context and logs message and optional values.

func NewContext

func NewContext(ctx context.Context, log logr.Logger) context.Context

NewContext returns a context with the specified logger set in it.

func NewLogger

func NewLogger(
	configurator Configurator,
	rootName string,
	verbosity int,
) (logr.Logger, error)

NewLogger sets the log verbosity, configures a new logger from `configurator`, and sets the initial name of the logger.

func NewLoggerFromEnv

func NewLoggerFromEnv(rootname string) (logr.Logger, error)

NewLoggerFromEnv uses the environment variables `LOG_PRODUCTION`, `LOG_IMPLEMENTATION`, and `LOG_VERBOSITY` to configure the logger. If they do not exist, it will default to configuring a production logger, with a `zap` `Configurator` at `0` verbosity (normal / info level).

func NewLoggerWithBuildInfo

func NewLoggerWithBuildInfo(
	configurator Configurator,
	buildInfo BuildInfo,
	rootName string,
	verbosity int,
) (logr.Logger, error)

NewLogger sets the log verbosity, configures a new logger from `configurator`, and sets the initial name of the logger. If `buildInfo` is not `nil`, non-empty values from the interface will be set as values on the resulting `logr.Logger`.

func WithName added in v1.2.0

func WithName(ctx context.Context, name string) (context.Context, logr.Logger)

WithName returns a context and logger with the given `name` set in the context.

func WithNameAndValues added in v1.2.0

func WithNameAndValues(ctx context.Context, name string, keysAndValues ...interface{}) (context.Context, logr.Logger)

WithNameAndValues returns a context and logger with the given `name` and `values` set in the context.

func WithValues added in v1.2.0

func WithValues(ctx context.Context, keysAndValues ...interface{}) (context.Context, logr.Logger)

WithValues returns a context and logger with the given `values` set in the context.

func Wrap added in v1.1.0

func Wrap(
	ctx context.Context,
	err error,
	message string,
	keysAndValues ...interface{},
) error

Wrap logs the error on the given logger and returns it wrapped by message.

Types

type BuildInfo

type BuildInfo interface {
	Version() string
	Commit() string
	Date() string
	Time() string
}

BuildInfo allows the application to add build info to the logger by default. Any non empty value returned will be set in the logger when calling `NewLoggerWithBuildInfo`.

type Configurator

type Configurator interface {
	// Build and return a `logr.Logger` instance.
	Build() (logr.Logger, error)

	// Verbosity sets the desired verbosity level. NOTE this will be called prior to `Build`.
	Verbosity(verbosity int) error
}

Configurator allows a pluggable logging implementation.

var DefaultConfigurator Configurator = NewZapProductionConfigurator()

DefaultConfigurator is the default configurator for fallback logging. nolint: gochecknoglobals // Allow for testing

type ZapConfigurator

type ZapConfigurator struct {
	Zap zap.Config
}

func NewZapDevelopmentConfigurator

func NewZapDevelopmentConfigurator() *ZapConfigurator

func NewZapProductionConfigurator

func NewZapProductionConfigurator() *ZapConfigurator

func (*ZapConfigurator) Build

func (config *ZapConfigurator) Build() (logr.Logger, error)

Build a new `zap` `logr.Logger`.

func (*ZapConfigurator) Verbosity

func (config *ZapConfigurator) Verbosity(verbosity int) error

Verbosity sets the desirect log verbosity in the `zap` config.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL