Skip to content

PR back to optum#1

Merged
Esity merged 92 commits into
Optum:mainfrom
LegionIO:main
Jun 25, 2026
Merged

PR back to optum#1
Esity merged 92 commits into
Optum:mainfrom
LegionIO:main

Conversation

@Esity

@Esity Esity commented Apr 17, 2026

Copy link
Copy Markdown
Member

No description provided.

Esity and others added 30 commits March 12, 2026 21:45
- setup(format: :json) emits newline-delimited JSON logs
- each line: { timestamp, level, message, thread, pid }
- default remains :text with rainbow colorization
- json mode auto-disables color and strips ansi from messages
- Logger class also accepts format: parameter
Add MultiIO class that writes log output to multiple IO targets at once.
Update Builder and Logger to accept log_file option and wire up MultiIO.
Add spec coverage for MultiIO write, close, and flush behavior.
runs after ci passes on push to main. calls reusable release workflow
for version detection, github release, and rubygems publish.
Accepts lex_segments: array and formats as [seg][seg]. Falls back to
legacy lex: string for backward compatibility with existing callers.
Fixes spurious [] bracket when lex: nil is passed.
LEX namespace restructuring: bracketed segment tag support
- Legion::Logging::Redactor: scrubs SSN, email, phone, MRN, DOB, credit card from log events before shipping; always redacts password/secret/token/api_key/authorization fields; recursive traversal of nested hashes and arrays; custom patterns from settings
- Legion::Logging::Shipper: batch-buffered log forwarding with configurable level filter, flush interval, and transport selection; all features disabled by default
- Legion::Logging::Shipper::FileTransport: JSON-lines writer for Filebeat/Fluentd pickup
- Legion::Logging::Shipper::HttpTransport: HTTP POST to Splunk HEC or ELK Logstash endpoints
- 134 specs total, 0 failures; bump to v1.2.6
* add async_writer with SizedQueue-based non-blocking log writer

* integrate async_writer into builder and setup

* route non-fatal log methods through async writer

* fix existing specs for async logging timing

* add async support to Logger instance constructor

* bump version to 1.3.0, add changelog for async logging

* flush stale queue on start, include backtrace in writer errors

* update readme with async logging docs and version 1.3.0

* address review: non-blocking shutdown, atomic async flag, spec improvements

* capture writer to local for thread safety, fix changelog wording, bound spec timeout
Legion::Settings#[] only accepts 1 argument. All nested settings
lookups (shipper, redactor, async buffer) were passing 3-4 args,
causing ArgumentError on boot. Replace with Settings.dig().
provides a log method that LEX extensions can include directly without
requiring the full LegionIO framework. derives logger tags from
segments, lex_filename, or class name in priority order.
Esity added 7 commits April 2, 2026 15:37
- guard MethodTracer.attach against duplicate attachment (mutex + ATTACHED registry)
- add detach/detach_all cleanup paths to MethodTracer
- omit params segment when method has no parameters (no trailing comma)
- use EXCEPTION_BACKTRACE_LIMIT constant in Methods#log_exception instead of hardcoded 10
- add MethodTracer spec (attach idempotency, call/return output, params formatting, detach)
- add backtrace formatting specs to log_exception (frames, overflow count, no-backtrace fallback)
- fix CLAUDE.md MethodTracer description: remove inaccurate "timing" claim
…ace-formatting

add method tracer, backtrace formatting in log_exception, and helper lifecycle hooks
@Esity Esity self-assigned this Apr 17, 2026
@Esity Esity requested review from a team and tylerkastenschmidt April 17, 2026 15:37
Esity added 19 commits April 27, 2026 21:25
…ures

Callers can now pass `backtrace_limit: 0` to suppress frames entirely,
`backtrace_limit: N` to cap at N frames, or omit it (nil) to get the
full backtrace as before. A global default can also be set via
`Legion::Settings[:logging][:backtrace_limit]`. Extracted frame-building
into private helpers to keep `log_exception` within complexity limits.

Bumps to 1.5.3.
Add configurable backtrace_limit to log_exception and handle_exception
emit_tagged (used by every Helper-based extension) was writing directly
to the IO device, serializing all consumer threads on a shared IO mutex.
Now routes through the SizedQueue → single writer thread like the
module-level methods already did. Logger instances default to async: true.
route all logging through async writer
All log level methods now accept optional task_id:, conv_id:, and
request_id: kwargs. The text formatter renders conv_id (or task_id
fallback) as {id} in the prefix and request_id as a kv pair after
severity. JSON format adds conversation_id and request_id fields.
AsyncWriter propagates both via thread-locals.
exchange_id and chain_id are correlation-level IDs rendered as kv pairs
after severity (same treatment as request_id). All level methods now
accept **_ctx so unknown kwargs are silently ignored instead of raising.
TaggedLogger dispatch uses **ctx passthrough for the same reason.
derive_component_settings_keys now parses the class namespace to
extract gem-level segments (e.g. Legion::Extensions::Llm::Vllm →
[:llm, :vllm]) and digs through Settings[:extensions] with each
segment as a key. Previously log_name was flattened with _ joins
making nested extensions like lex-llm-vllm indistinguishable from
a single-segment extension, causing level overrides to never resolve.
Fixes CodeQL warning about potentially uninitialized local variable
if THREAD_KEYS.map raises before assignment completes.
- SIEMExporter: add open_timeout: 5, read_timeout: 10 to prevent
  60s hangs on unresponsive SIEM endpoints
- MultiIO: isolate write failures per target so one failing IO
  doesn't prevent others from receiving the message
- Hooks: dup the hook array before iteration to prevent concurrent
  modification crashes if hooks are registered mid-fire
…xtract HeaderBuilder

Helper#write_exception_to_log now goes through Legion::Logging.public_send
which routes through the async writer with full segment/context metadata.
Previously it called directly on the raw Logger, bypassing async and losing
all structured context (segments, method, conv_id, etc).

Shipper rewrite eliminates AB-BA deadlock:
- Removed @flush_mutex (single @Mutex, grab+clear atomically)
- stop uses @running flag + join(5) instead of Thread#kill
- start uses @start_mutex to prevent double-thread race
- Failed deliveries re-prepend batch to buffer

Extracted HeaderBuilder module to eliminate verbatim duplication of
build_exception_headers, build_exception_properties, append_identity_headers,
append_optional_header, append_legion_version_header, identity_hash,
identity_value, and redaction_enabled? between Methods and Helper.
Add task_id, conv_id, request_id context to log output
@Esity Esity merged commit 1cbfe34 into Optum:main Jun 25, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant