Class: LambdaLoadout::Logger

Inherits:
Object
  • Object
show all
Defined in:
lib/lambda_loadout/logger.rb

Overview

Structured logger with Lambda context enrichment

Provides JSON structured logging with automatic Lambda context injection, correlation IDs, and support for custom fields.

Examples:

Basic usage

logger = LambdaLoadout::Logger.new(service: "payment")
logger.info("Processing payment", order_id: "12345")
# => {"level":"INFO","timestamp":"2025-01-01T12:00:00.000Z","message":"Processing payment","service":"payment","order_id":"12345"}

With Lambda context

def lambda_handler(event:, context:)
  logger = LambdaLoadout::Logger.new(service: "payment")
  logger.inject_lambda_context(context)
  logger.info("Handler invoked")
  # => Includes function_name, request_id, etc.
end

Constant Summary collapse

LOG_LEVELS =
{
  debug: 0,
  info: 1,
  warn: 2,
  error: 3,
  fatal: 4
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service: nil, level: :info, output: $stdout, sampling_rate: nil) ⇒ Logger

Initialize a new structured logger

Parameters:

  • service (String) (defaults to: nil)

    Service name (adds ‘service’ field to all logs)

  • level (Symbol, String) (defaults to: :info)

    Log level (:debug, :info, :warn, :error, :fatal)

  • output (IO) (defaults to: $stdout)

    Output stream (defaults to $stdout)

  • sampling_rate (Float) (defaults to: nil)

    Sampling rate for debug logs (0.0-1.0)



42
43
44
45
46
47
48
49
50
# File 'lib/lambda_loadout/logger.rb', line 42

def initialize(service: nil, level: :info, output: $stdout, sampling_rate: nil)
  @service = service || ENV.fetch('POWERTOOLS_SERVICE_NAME', nil)
  @level = LOG_LEVELS[level.to_sym] || LOG_LEVELS[:info]
  @output = output
  @sampling_rate = sampling_rate&.to_f
  @lambda_context = nil
  @persistent_fields = {}
  @persistent_fields['service'] = @service if @service
end

Instance Attribute Details

#lambda_contextObject

Returns the value of attribute lambda_context.



26
27
28
# File 'lib/lambda_loadout/logger.rb', line 26

def lambda_context
  @lambda_context
end

#levelObject (readonly)

Returns the value of attribute level.



25
26
27
# File 'lib/lambda_loadout/logger.rb', line 25

def level
  @level
end

#outputObject (readonly)

Returns the value of attribute output.



25
26
27
# File 'lib/lambda_loadout/logger.rb', line 25

def output
  @output
end

#serviceObject (readonly)

Returns the value of attribute service.



25
26
27
# File 'lib/lambda_loadout/logger.rb', line 25

def service
  @service
end

Instance Method Details

#append_keys(**fields) ⇒ void

This method returns an undefined value.

Add persistent fields that will be included in all log entries

Parameters:

  • fields (Hash)

    Fields to add to all logs



64
65
66
# File 'lib/lambda_loadout/logger.rb', line 64

def append_keys(**fields)
  @persistent_fields.merge!(fields.transform_keys(&:to_s))
end

#debug(message, exception = nil, **fields) ⇒ void

This method returns an undefined value.

Log debug message

Parameters:

  • message (String)

    Log message

  • exception (Exception, nil) (defaults to: nil)

    Optional exception object

  • fields (Hash)

    Additional fields



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/lambda_loadout/logger.rb', line 82

def debug(message, exception = nil, **fields)
  return unless should_log?(:debug)

  if exception.is_a?(Exception)
    fields[:error] = exception.message
    fields[:error_class] = exception.class.name
    fields[:backtrace] = exception.backtrace&.first(10)
  end

  log(:debug, message, **fields)
end

#error(message, exception = nil, **fields) ⇒ void

This method returns an undefined value.

Log error message

Parameters:

  • message (String)

    Log message

  • exception (Exception, nil) (defaults to: nil)

    Optional exception object

  • fields (Hash)

    Additional fields



136
137
138
139
140
141
142
143
144
145
146
# File 'lib/lambda_loadout/logger.rb', line 136

def error(message, exception = nil, **fields)
  return unless should_log?(:error)

  if exception.is_a?(Exception)
    fields[:error] = exception.message
    fields[:error_class] = exception.class.name
    fields[:backtrace] = exception.backtrace&.first(10)
  end

  log(:error, message, **fields)
end

#exception(exception, message: nil, **fields) ⇒ void

This method returns an undefined value.

Log an exception with full details

Parameters:

  • exception (Exception)

    Exception to log

  • message (String) (defaults to: nil)

    Additional message

  • fields (Hash)

    Additional fields



165
166
167
168
169
170
171
172
173
# File 'lib/lambda_loadout/logger.rb', line 165

def exception(exception, message: nil, **fields)
  error(
    message || exception.message,
    exception: exception.class.name,
    error_message: exception.message,
    backtrace: exception.backtrace&.first(10),
    **fields
  )
end

#fatal(message, **fields) ⇒ void

This method returns an undefined value.

Log fatal message

Parameters:

  • message (String)

    Log message

  • fields (Hash)

    Additional fields



153
154
155
156
157
# File 'lib/lambda_loadout/logger.rb', line 153

def fatal(message, **fields)
  return unless should_log?(:fatal)

  log(:fatal, message, **fields)
end

#info(message, exception = nil, **fields) ⇒ void

This method returns an undefined value.

Log info message

Parameters:

  • message (String)

    Log message

  • exception (Exception, nil) (defaults to: nil)

    Optional exception object

  • fields (Hash)

    Additional fields



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/lambda_loadout/logger.rb', line 100

def info(message, exception = nil, **fields)
  return unless should_log?(:info)

  if exception.is_a?(Exception)
    fields[:error] = exception.message
    fields[:error_class] = exception.class.name
    fields[:backtrace] = exception.backtrace&.first(10)
  end

  log(:info, message, **fields)
end

#inject_lambda_context(context) ⇒ void

This method returns an undefined value.

Inject Lambda context into logs

Parameters:

  • context (Object)

    Lambda context object



56
57
58
# File 'lib/lambda_loadout/logger.rb', line 56

def inject_lambda_context(context)
  @lambda_context = context
end

#remove_keys(*keys) ⇒ void

This method returns an undefined value.

Remove persistent fields

Parameters:

  • keys (Array<Symbol, String>)

    Keys to remove



72
73
74
# File 'lib/lambda_loadout/logger.rb', line 72

def remove_keys(*keys)
  keys.each { |key| @persistent_fields.delete(key.to_s) }
end

#warn(message, exception = nil, **fields) ⇒ void

This method returns an undefined value.

Log warning message

Parameters:

  • message (String)

    Log message

  • exception (Exception, nil) (defaults to: nil)

    Optional exception object

  • fields (Hash)

    Additional fields



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/lambda_loadout/logger.rb', line 118

def warn(message, exception = nil, **fields)
  return unless should_log?(:warn)

  if exception.is_a?(Exception)
    fields[:error] = exception.message
    fields[:error_class] = exception.class.name
    fields[:backtrace] = exception.backtrace&.first(10)
  end

  log(:warn, message, **fields)
end