Class: Dinie::Internal::RuntimeLogger

Inherits:
Object
  • Object
show all
Defined in:
lib/dinie/runtime/logger.rb,
sig/dinie/runtime/logger.rbs

Overview

Leveled logging facade with PII redaction. Constructed by Middleware::Logging.

Constant Summary collapse

LEVELS =

Level ordering for gating: a call at level emits when level <= configured (so :off emits nothing, :debug emits everything).

Returns:

  • (Hash[Symbol, Integer])
{ off: 0, error: 1, warn: 2, info: 3, debug: 4 }.freeze
ENV_VAR =

Environment variable read when no explicit level: is given.

Returns:

  • (String)
"DINIE_LOG"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(level: nil, logger: nil, env: ENV.fetch(ENV_VAR, nil)) ⇒ RuntimeLogger

Returns a new instance of RuntimeLogger.

Parameters:

  • level (Symbol, String, nil) (defaults to: nil) —

    explicit level; a valid one wins over the env var

  • logger (Object, nil) (defaults to: nil) —

    custom sink responding to #debug/#info/#warn/#error (default ::Logger.new($stdout))

  • env (String, nil) (defaults to: ENV.fetch(ENV_VAR, nil)) —

    DINIE_LOG override (injectable for tests)

  • level: (Symbol, String, nil) (defaults to: nil)
  • logger: (Object) (defaults to: nil)
  • env: (String, nil) (defaults to: ENV.fetch(ENV_VAR, nil))


162
163
164
165
# File 'lib/dinie/runtime/logger.rb', line 162

def initialize(level: nil, logger: nil, env: ENV.fetch(ENV_VAR, nil))
  @level = resolve_level(level, env)
  @sink = logger || ::Logger.new($stdout)
end

Instance Attribute Details

#level ⇒ Symbol (readonly)

The effective level after level: + DINIE_LOG resolution.

Returns:

  • (Symbol)


156
157
158
# File 'lib/dinie/runtime/logger.rb', line 156

def level
  @level
end

Instance Method Details

#debug(message) ⇒ void

This method returns an undefined value.

Parameters:

  • message (Object)


182
# File 'lib/dinie/runtime/logger.rb', line 182

def debug(message) = emit(:debug, message)

#emit(level, message) ⇒ void

This method returns an undefined value.

Parameters:

  • level (Symbol)
  • message (Object)


217
218
219
# File 'lib/dinie/runtime/logger.rb', line 217

def emit(level, message)
  @sink.public_send(level, message) if enabled?(level)
end

#emit_line(label, fields, headers, body) ⇒ void

This method returns an undefined value.

Render one debug line as [dinie] <label> k=v … headers={…} body=<json>. Scalar fields use k=v; headers are inspected (a small map); the body is appended RAW (the already-redacted, truncated JSON) so it is not double-escaped — readable in logs and grep-able in tests.

Parameters:

  • label (String)
  • fields (Hash[Symbol, untyped])
  • headers (Object)
  • body (Object)


224
225
226
227
228
229
230
231
# File 'lib/dinie/runtime/logger.rb', line 224

def emit_line(label, fields, headers, body)
  parts = ["[dinie] #{label}"]
  fields.compact.each { |key, value| parts << "#{key}=#{value}" }
  parts << "headers=#{LogRedaction.redact_headers(headers).inspect}" unless headers.nil?
  formatted = LogRedaction.format_body(body)
  parts << "body=#{formatted}" unless formatted.nil?
  @sink.debug(parts.join(" "))
end

#enabled?(level) ⇒ Boolean

Whether a call at level would emit under the configured level.

Parameters:

  • level (Symbol)

Returns:

  • (Boolean)


171
172
173
# File 'lib/dinie/runtime/logger.rb', line 171

def enabled?(level)
  LEVELS.fetch(level) <= LEVELS.fetch(@level)
end

#error(message) ⇒ void

This method returns an undefined value.

Parameters:

  • message (Object)


176
177
# File 'lib/dinie/runtime/logger.rb', line 176

def error(message) = emit(:error, message)
# @return [void]

#info(message) ⇒ void

This method returns an undefined value.

Parameters:

  • message (Object)


180
181
# File 'lib/dinie/runtime/logger.rb', line 180

def info(message) = emit(:info, message)
# @return [void]

#log_request(method:, url:, headers:, body:, correlation:) ⇒ void

This method returns an undefined value.

Log an outgoing request at debug with redacted headers + body and the correlation triple.

Parameters:

  • method: (Symbol, String)
  • url: (String)
  • headers: (Object)
  • body: (Object)
  • correlation: (Hash[Symbol, untyped])


192
193
194
195
196
# File 'lib/dinie/runtime/logger.rb', line 192

def log_request(method:, url:, headers:, body:, correlation:)
  return unless enabled?(:debug)

  emit_line("→ request", correlation.merge(method: method.to_s.upcase, url: url), headers, body)
end

#log_response(status:, url:, headers:, body:, duration_ms:, request_id:, correlation:) ⇒ void

This method returns an undefined value.

Log an incoming response at debug with redacted headers + body, duration, and request id.

Parameters:

  • status: (Integer)
  • url: (String)
  • headers: (Object)
  • body: (Object)
  • duration_ms: (Numeric)
  • request_id: (String, nil)
  • correlation: (Hash[Symbol, untyped])


208
209
210
211
212
213
# File 'lib/dinie/runtime/logger.rb', line 208

def log_response(status:, url:, headers:, body:, duration_ms:, request_id:, correlation:) # rubocop:disable Metrics/ParameterLists
  return unless enabled?(:debug)

  fields = correlation.merge(status: status, url: url, duration_ms: duration_ms, request_id: request_id)
  emit_line("← response", fields, headers, body)
end

#resolve_level(level, env) ⇒ Symbol

Explicit valid level: wins; else a valid DINIE_LOG; else :off. An unset/garbage value never raises — it degrades to :off.

Parameters:

  • level (Object)
  • env (Object)

Returns:

  • (Symbol)


235
236
237
238
239
240
# File 'lib/dinie/runtime/logger.rb', line 235

def resolve_level(level, env)
  return level.to_sym if valid_level?(level)
  return env.strip.to_sym if !env.nil? && valid_level?(env.strip)

  :off
end

#valid_level?(value) ⇒ Boolean

Parameters:

  • value (Object)

Returns:

  • (Boolean)


242
243
244
# File 'lib/dinie/runtime/logger.rb', line 242

def valid_level?(value)
  !value.nil? && LEVELS.key?(value.to_s.to_sym)
end

#warn(message) ⇒ void

This method returns an undefined value.

Parameters:

  • message (Object)


178
179
# File 'lib/dinie/runtime/logger.rb', line 178

def warn(message) = emit(:warn, message)
# @return [void]