Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

17 Commits

Repository files navigation

logger

A structured logging package for Go, built on zap. Provides a global singleton logger with environment-aware defaults, common field support, context propagation, timed logging, and GCP Cloud Logging compatibility.

Install

go get github.com/packaged/logger/v3

Setup

Initialize the global logger with an environment. The log level and encoding are configured automatically based on the environment.

import (
"github.com/packaged/environment/environment""github.com/packaged/logger/v3/logger"
)
logger.Setup(environment.Production)
EnvironmentEncodingLevel
Production, SandboxJSON (GCP format)Info
Integration TestJSON (GCP format)Debug
Development, Local, Unit TestConsoleDebug

Debug logging can be forced in any environment by setting the PACKAGED__DEBUG_LOG=true environment variable.

Logging

log:=logger.I() // global instancelog.Debug("starting process")
log.Info("user logged in", zap.String("user-id", "abc"))
log.Warn("slow query", zap.Duration("elapsed", elapsed))
log.Error("request failed", zap.Error(err))

Conditional logging

Log only when an error is non-nil:

log.ErrorIf(err, "failed to save", zap.String("id", id))
log.WarnIf(err, "retrying request")
log.InfoIf(err, "completed with warning")
log.DebugIf(err, "optional detail")

Common Fields

Add fields that are included in every log entry from a logger instance. Use Clone() to create a scoped logger without mutating the global instance.

log:=logger.I().Clone()
log.AddCommon(
zap.String("request-id", reqID),
zap.String("service", "payments"),
)
log.Info("processing") // includes request-id and service automatically

Context Propagation

Store and retrieve a logger from context.Context, enabling request-scoped loggers to flow through call chains.

// At the request entry pointlog:=logger.I().Clone()
log.AddCommon(zap.String("request-id", reqID))
ctx=logger.NewContext(ctx, log)
// Anywhere downstreamlog:=logger.FromContext(ctx)
log.Info("handling step") // includes request-id

FromContext returns the global logger if none is set on the context, so it is always safe to call.

Timed Logging

Log at a severity level based on how long an operation took.

tl:=logger.DefaultTimedLogConfig().NewLog("db query", zap.String("table", "users"))
deferlogger.I().TimedLog(tl)
// ... do work ...tl.Complete()

Default thresholds:

DurationLevel
>= 1 minuteError
>= 30 secondsWarn
>= 2 secondsInfo
>= 500msDebug

Custom thresholds:

cfg:=&logger.TimedLogConfig{
ErrorDuration: 10*time.Second,
WarnDuration: 5*time.Second,
InfoDuration: time.Second,
DebugDuration: 100*time.Millisecond,
}
tl:=cfg.NewLog("api call")

Custom Configuration

Create a logger with a custom zap config and options:

l, err:=logger.InstanceWithConfig(
environment.Production,
zap.NewProductionConfig(),
logger.WithGoogleEncoding,
logger.DisableStacktrace,
logger.Info,
)

Available options: Debug, Info, Warn, Error, DPanic, Panic, Fatal, WithConsoleEncoding, WithGoogleEncoding, DisableStacktrace, DisableCaller.

Log Data Helpers (ld package)

Common zap fields for structured logging:

import"github.com/packaged/logger/v3/ld"log.Info("request",
ld.IP(remoteAddr),
ld.URL(requestURL),
ld.Method("POST"),
ld.UserAgent(ua),
ld.Port(8080),
ld.Error(err), // zap.Skip() if nilld.InterfaceType("handler", h), // logs the reflect typeld.Prefix("req", zap.String("id", id)), // "req:id"
)

Testing

Use ObserverForTest to capture log output in tests:

logger.Setup(environment.UnitTest)
logs:=logger.ObserverForTest()
logger.I().Info("hello")
assert.Equal(t, 1, logs.Len())
assert.Equal(t, "hello", logs.All()[0].Message)

About

Go Logger

Resources

Stars

0 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages