logger

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package logger writes structured JSON logs for AWS Lambda handlers.

New creates a reusable Logger with service, level, output and formatting options. Logger.Info and the other level methods accept additional fields. Use WithPersistentKeys for stable service metadata rather than request data.

Invocation lifecycle

WrapHandler establishes invocation state. Inside the handler, call Logger.WithContext with the supplied context to obtain request-scoped fields and correlation information. This prevents keys from leaking between invocations. Buffering, sampling and event logging are configurable; review their data and flush policies before enabling them for production payloads. WrapRawHandler retains incoming JSON members in event logs before decoding a typed business input. WrapHandler logs the input value it receives.

The package composes with OpenTelemetry tracing and optional JMESPath extraction. Applications own custom writers, formatters, clocks and error callbacks.

For usage and compatibility details, see the user guide.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrInvocationClosed = errors.New("logger invocation is closed")

ErrInvocationClosed prevents detached work from writing into a completed invocation.

Functions

func ExtractCorrelationID

func ExtractCorrelationID(source CorrelationSource, event any) (any, error)

ExtractCorrelationID supports maps and typed events with JSON field tags. Missing values return nil. Arbitrary query expressions belong to the JMESPath utility.

func WrapHandler

func WrapHandler[T, R any](l *Logger, handler func(context.Context, T) (R, error), options ...HandlerOptions) func(context.Context, T) (R, error)

WrapHandler enriches logs and isolates mutable state for each Lambda invocation. The handler must use l.WithContext(ctx); a root logger has process-scoped state. A panic is observed for cleanup and then rethrown unchanged to the Lambda runtime. Event logging serializes T, which may already omit original JSON members. Use WrapRawHandler at the runtime entry to log before typed decoding.

func WrapRawHandler added in v1.1.0

func WrapRawHandler[T, R any](l *Logger, handler func(context.Context, T) (R, error), options ...HandlerOptions) func(context.Context, jsonv1.RawMessage) (R, error)

WrapRawHandler logs the incoming JSON value before decoding it into T. Register the returned RawMessage function with the Lambda runtime to retain event members that are absent from T and values omitted by T's JSON tags. Decoding uses encoding/json/v2 defaults; decoding failures return without calling the business handler. Syntax rejected by the runtime never reaches this wrapper. Log formatting and replacers can still change the logged value. Correlation callbacks and extractors receive RawMessage, not the decoded T. Invocation state, logging options, and cleanup follow WrapHandler.

Example
package main

import (
	"bytes"
	"context"

	json "encoding/json/v2"
	"fmt"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/rambow-cloud/powertools-lambda-go/logger"
)

func main() {
	var output bytes.Buffer
	log := logger.New(logger.WithOutput(&output), logger.WithLevel(logger.InfoLevel))
	enabled := true
	handler := logger.WrapRawHandler(log, func(_ context.Context, event struct {
		Name string `json:"name"`
	}) (string, error) {
		return event.Name, nil
	}, logger.HandlerOptions{LogEvent: &enabled})
	response, err := lambda.NewHandler(handler).Invoke(context.Background(), []byte(`{"name":"Alice","age":30}`))
	if err != nil {
		panic(err)
	}
	var entry struct {
		Event map[string]any `json:"event"`
	}
	if err := json.Unmarshal(output.Bytes(), &entry); err != nil {
		panic(err)
	}
	fmt.Println(string(response), entry.Event["name"], entry.Event["age"])
}
Output:
"Alice" Alice 30

Types

type BufferOptions

type BufferOptions struct {
	MaxBytes            int
	BufferAt            Level
	DisableFlushOnError bool
}

BufferOptions enables buffering when supplied through WithBuffer. MaxBytes defaults to 20480, BufferAt defaults to DEBUG, and errors flush by default.

type CorrelationSource

type CorrelationSource string

CorrelationSource selects a built-in event location, not a JMESPath expression.

const (
	APIGatewayREST          CorrelationSource = "api_gateway_rest"
	APIGatewayHTTP          CorrelationSource = "api_gateway_http"
	AppSyncAuthorizer       CorrelationSource = "appsync_authorizer"
	AppSyncResolver         CorrelationSource = "appsync_resolver"
	ApplicationLoadBalancer CorrelationSource = "application_load_balancer"
	EventBridge             CorrelationSource = "event_bridge"
	LambdaFunctionURL       CorrelationSource = "lambda_function_url"
	S3ObjectLambda          CorrelationSource = "s3_object_lambda"
	VPCLattice              CorrelationSource = "vpc_lattice"
)

type Fields

type Fields map[string]any

type Formatter

type Formatter func(Fields) (any, error)

Formatter can replace the JSON document while retaining the configured sink. It must be safe for concurrent calls and must not retain or mutate caller data.

type HandlerOptions

type HandlerOptions struct {
	// LogEvent records the value received by the wrapper before its handler runs.
	// WrapRawHandler receives raw JSON; WrapHandler may receive a typed projection.
	LogEvent           *bool
	FlushBufferOnError bool
	CorrelationID      func(event any) any
	// CorrelationExtractor accepts compiled query expressions without a dependency
	// on a query engine. CorrelationID takes precedence when both are configured.
	CorrelationExtractor interface{ Search(any) (any, error) }
	CorrelationSource    CorrelationSource
}

HandlerOptions controls wrapper behavior. Per-invocation attributes always reset. CorrelationID supports custom extraction without imposing a query dependency.

type Level

type Level int

Level uses the same thresholds as Powertools for TypeScript.

const (
	TraceLevel    Level = 6
	DebugLevel    Level = 8
	InfoLevel     Level = 12
	WarnLevel     Level = 16
	ErrorLevel    Level = 20
	CriticalLevel Level = 24
	SilentLevel   Level = 28
)

func ParseLevel

func ParseLevel(value string) (Level, bool)

ParseLevel accepts case-insensitive Powertools level names.

func (Level) String

func (l Level) String() string

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

Logger is safe to share across goroutines. Treat values passed as attributes as immutable until the call completes; application-owned nested values are not locked. Use WithContext inside a wrapped handler to bind invocation-local mutable state.

func New

func New(options ...Option) *Logger

New creates a logger. Invalid environment values fall back to defaults.

Example
package main

import (
	"bytes"

	json "encoding/json/v2"
	"fmt"

	"github.com/rambow-cloud/powertools-lambda-go/logger"
)

func main() {
	var output bytes.Buffer
	log := logger.New(logger.WithServiceName("orders"),
		logger.WithLevel(logger.InfoLevel), logger.WithOutput(&output))
	if err := log.Info("Order accepted", logger.Fields{"order_id": "order-123"}); err != nil {
		panic(err)
	}
	var entry map[string]any
	if err := json.Unmarshal(output.Bytes(), &entry); err != nil {
		panic(err)
	}
	fmt.Println(entry["service"], entry["message"], entry["order_id"])
}
Output:
orders Order accepted order-123

func (*Logger) AppendKeys

func (l *Logger) AppendKeys(keys Fields)

func (*Logger) AppendPersistentKeys

func (l *Logger) AppendPersistentKeys(keys Fields)

func (*Logger) Child

func (l *Logger) Child(options ...Option) *Logger

Child creates an independent logger with separate snapshots of the parent's persistent and temporary attributes, retaining temporary-field precedence. Child loggers share the output lock and participate in the same wrapper cleanup.

func (*Logger) ClearBuffer

func (l *Logger) ClearBuffer()

ClearBuffer discards only the active trace's pending entries.

func (*Logger) Critical

func (l *Logger) Critical(message string, extra ...any) error

func (*Logger) Debug

func (l *Logger) Debug(message string, extra ...any) error

func (*Logger) Error

func (l *Logger) Error(message string, extra ...any) error

func (*Logger) FlushBuffer

func (l *Logger) FlushBuffer() error

FlushBuffer emits the active trace's entries without applying the level threshold. Without an active trace, or when another trace owns the buffer, it does nothing.

func (*Logger) GetCorrelationID

func (l *Logger) GetCorrelationID() any

GetCorrelationID returns the current temporary correlation ID, as in the reference. Treat returned application-owned values as immutable.

func (*Logger) GetLevel

func (l *Logger) GetLevel() Level

func (*Logger) GetLevelName

func (l *Logger) GetLevelName() string

GetLevelName returns the current invocation's effective log level name.

func (*Logger) GetLogEvent

func (l *Logger) GetLogEvent() bool

GetLogEvent returns the constructor's event logging setting.

func (*Logger) Info

func (l *Logger) Info(message string, extra ...any) error

func (*Logger) Log

func (l *Logger) Log(level Level, message string, extra ...any) error

Log writes or buffers one log document and returns serialization or output errors. Warning and error levels use stderr unless WithOutput supplies a common sink.

func (*Logger) PersistentKeys

func (l *Logger) PersistentKeys() Fields

func (*Logger) RemoveKeys

func (l *Logger) RemoveKeys(keys ...string)

func (*Logger) RemovePersistentKeys

func (l *Logger) RemovePersistentKeys(keys ...string)

func (*Logger) ResetKeys

func (l *Logger) ResetKeys()

func (*Logger) SetCorrelationID

func (l *Logger) SetCorrelationID(value any)

func (*Logger) SetLevel

func (l *Logger) SetLevel(level Level)

func (*Logger) Trace

func (l *Logger) Trace(message string, extra ...any) error

func (*Logger) Warn

func (l *Logger) Warn(message string, extra ...any) error

func (*Logger) WithContext

func (l *Logger) WithContext(ctx context.Context) *Logger

WithContext binds the logger to the current invocation without mutating the root.

type Option

type Option func(*config)

func WithBuffer

func WithBuffer(options BufferOptions) Option

func WithClock

func WithClock(clock func() time.Time) Option

func WithErrorHandler

func WithErrorHandler(handler func(error)) Option

WithErrorHandler receives wrapper logging errors without replacing handler results. The callback must not recursively call this logger.

func WithFormatter

func WithFormatter(formatter Formatter) Option

func WithLevel

func WithLevel(level Level) Option

func WithOutput

func WithOutput(w io.Writer) Option

func WithPersistentKeys

func WithPersistentKeys(keys Fields) Option

func WithRandom

func WithRandom(random func() int) Option

WithRandom supplies an integer in [0, 100), matching the reference sampling grid. The function must be safe for concurrent calls.

func WithRecordOrder

func WithRecordOrder(keys ...string) Option

func WithReplacer

func WithReplacer(replacer Replacer) Option

func WithSampleRate

func WithSampleRate(rate float64) Option

func WithServiceName

func WithServiceName(name string) Option

type Replacer

type Replacer func(key string, value any) any

Replacer transforms a value before built-in JSON conversions are applied.

Jump to

Keyboard shortcuts

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