Class: IuguLogger::Buffer
- Inherits:
-
Object
- Object
- IuguLogger::Buffer
- 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
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#rails_runtime ⇒ Object
readonly
Returns the value of attribute rails_runtime.
Class Method Summary collapse
-
.current ⇒ Object
Returns the buffer for the current thread, creating one lazily.
-
.reset! ⇒ Object
Resets the current thread’s buffer (used by middleware between requests).
Instance Method Summary collapse
-
#add_context(**fields) ⇒ Object
Merge fields into the request-scoped context.
-
#drain ⇒ Object
Returns the array of entries collected so far and clears the buffer.
-
#initialize ⇒ Buffer
constructor
A new instance of Buffer.
-
#push(severity:, message:, **extras) ⇒ Object
Append a log entry.
- #reset_context! ⇒ Object
-
#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.
-
#size ⇒ Object
Number of entries currently buffered (without draining).
Constructor Details
#initialize ⇒ Buffer
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
#context ⇒ Object (readonly)
Returns the value of attribute context.
45 46 47 |
# File 'lib/iugu_logger/buffer.rb', line 45 def context @context end |
#rails_runtime ⇒ Object (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
.current ⇒ Object
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 |
#drain ⇒ Object
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' => } 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 |
#size ⇒ Object
Number of entries currently buffered (without draining).
84 85 86 |
# File 'lib/iugu_logger/buffer.rb', line 84 def size @entries.length end |