Class: IuguLogger::Buffer

Inherits:
Object
  • Object
show all
Defined in:
lib/iugu_logger/buffer.rb

Overview

Thread-local buffer for in-app log entries collected during a single request or job execution.

Pattern (per IUGU_LOGGING_STANDARD.md §2.1):

- Framework / app code calls IuguLogger::Buffer.current.push(...)
  instead of emitting one log per call.
- Middleware (RequestLogger / JobLogger) drains the buffer at end of
  execution and emits ONE consolidated event with `logs: [...]` array.
- Result: 1 log line per request, instead of N — aggregation is 10×
  simpler downstream (Loki/Splunk).

Also carries a ‘context` hash for request-scoped enrichment (trace, iugu, request) that downstream code can read or that middleware merges into the final emitted event.

Thread safety: each thread has its own buffer instance via Concurrent::ThreadLocalVar. Reset between requests by the middleware.

NOT used by IuguLogger.event(…) directly — that API still emits immediately. Buffer is the place where Rails.logger.X (post-Railtie, v0.5) accumulates entries.

Constant Summary collapse

THREAD_LOCAL =
Concurrent::ThreadLocalVar.new
MAX_ENTRIES =
100

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBuffer

Returns a new instance of Buffer.



47
48
49
50
51
# File 'lib/iugu_logger/buffer.rb', line 47

def initialize
  @entries       = []
  @context       = {}
  @rails_runtime = {} # view_ms / db_ms captured by Railtie subscriber
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



45
46
47
# File 'lib/iugu_logger/buffer.rb', line 45

def context
  @context
end

#rails_runtimeObject (readonly)

Returns the value of attribute rails_runtime.



45
46
47
# File 'lib/iugu_logger/buffer.rb', line 45

def rails_runtime
  @rails_runtime
end

Class Method Details

.currentObject

Returns the buffer for the current thread, creating one lazily.



32
33
34
# File 'lib/iugu_logger/buffer.rb', line 32

def current
  THREAD_LOCAL.value ||= new
end

.reset!Object

Resets the current thread’s buffer (used by middleware between requests). Safe to call when no buffer exists yet.



38
39
40
# File 'lib/iugu_logger/buffer.rb', line 38

def reset!
  THREAD_LOCAL.value = nil
end

Instance Method Details

#add_context(**fields) ⇒ Object

Merge fields into the request-scoped context. Existing keys overwritten.



89
90
91
# File 'lib/iugu_logger/buffer.rb', line 89

def add_context(**fields)
  fields.each { |k, v| @context[k] = v unless v.nil? }
end

#drainObject

Returns the array of entries collected so far and clears the buffer.



77
78
79
80
81
# File 'lib/iugu_logger/buffer.rb', line 77

def drain
  collected = @entries
  @entries = []
  collected
end

#push(severity:, message:, **extras) ⇒ Object

Append a log entry. Severity is a symbol or string; message is the human-readable summary; extras become extra keys on the entry.



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/iugu_logger/buffer.rb', line 64

def push(severity:, message:, **extras)
  return if @entries.length >= MAX_ENTRIES # cap to avoid unbounded growth

  entry = {
    'timestamp' => Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S.%6NZ'),
    'severity'  => severity.to_s,
    'message'   => message
  }
  extras.each { |k, v| entry[k.to_s] = v unless v.nil? }
  @entries << entry
end

#reset_context!Object



93
94
95
# File 'lib/iugu_logger/buffer.rb', line 93

def reset_context!
  @context = {}
end

#set_rails_runtime(view_ms: nil, db_ms: nil) ⇒ Object

Records the Rails view/db runtime captured at the end of action dispatch via ActiveSupport::Notifications. RequestLogger reads these when building the canonical ‘rails.*` block, since ActionController::API doesn’t populate the corresponding env keys.



57
58
59
60
# File 'lib/iugu_logger/buffer.rb', line 57

def set_rails_runtime(view_ms: nil, db_ms: nil)
  @rails_runtime['view_ms'] = view_ms unless view_ms.nil?
  @rails_runtime['db_ms']   = db_ms   unless db_ms.nil?
end

#sizeObject

Number of entries currently buffered (without draining).



84
85
86
# File 'lib/iugu_logger/buffer.rb', line 84

def size
  @entries.length
end