Class: Logsy::JsonFormatter

Inherits:
Logger::Formatter
  • Object
show all
Defined in:
lib/logsy/json_formatter.rb

Overview

Logger formatter that emits one JSON object per log call.

Each line includes:

- ts:    UTC ISO-8601 timestamp with millis
- level: severity ('INFO', 'ERROR', ...)
- msg:   the log message (when message is a String or Exception)
- file:  "path:line" of the nearest app frame (when
         include_caller_location). Gem, stdlib, and ignored frames
         are skipped, so an ActiveRecord SQL line points at the
         controller/model code that ran the query — not at
         active_record/log_subscriber.rb. Omitted entirely for
         framework-only lines (e.g. "Started GET ..."), which have
         no app frame.
- any non-nil tags from Logsy[]

String messages are cleaned before emission: ANSI color codes (e.g. ActiveRecord’s SQL highlighting) are stripped and surrounding whitespace removed, so log stores get plain searchable text.

When the message is a Hash, its keys are merged directly into the top-level payload (useful for “wide event” emissions like a request summary). Symbols and strings are accepted as keys.

Example output:

{"ts":"2026-05-02T10:00:00.123Z","level":"INFO","msg":"hello",
 "file":"app/controllers/orders_controller.rb:34",
 "request_id":"abc-123","user_id":"u-1"}

Constant Summary collapse

ANSI_ESCAPE =
/\e\[[0-9;]*m/
FRAME_BATCH_SIZE =
16

Instance Method Summary collapse

Instance Method Details

#call(severity, time, _progname, message) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/logsy/json_formatter.rb', line 39

def call(severity, time, _progname, message)
  payload = {
    ts: time.utc.iso8601(3),
    level: severity
  }

  add_caller_location!(payload) if Logsy.configuration.include_caller_location
  merge_context!(payload)
  merge_message!(payload, message)

  "#{JSON.dump(payload)}\n"
rescue StandardError => e
  fallback_line(severity, time, e)
end