Class: LogStruct::SemanticLogger::Logger
- Inherits:
-
SemanticLogger::Logger
- Object
- SemanticLogger::Logger
- LogStruct::SemanticLogger::Logger
- Extended by:
- T::Sig
- Includes:
- Concerns::LogMethods
- Defined in:
- lib/log_struct/semantic_logger/logger.rb
Overview
High-Performance Logger with LogStruct Integration
This logger extends SemanticLogger::Logger to provide optimal logging performance while seamlessly integrating with LogStruct's typed logging system.
Key Benefits Over Rails.logger:
Performance
- 10-100x faster than Rails' default logger for high-volume applications
- Non-blocking I/O: Uses background threads for actual log writes
- Minimal memory allocation: Efficient object reuse and zero-copy operations
- Batched writes: Reduces system calls by batching multiple log entries
Reliability
- Thread-safe operations: Safe for use in multi-threaded environments
- Error resilience: Logger failures don't crash your application
- Graceful fallbacks: Continues operating even if appenders fail
Features
- Structured logging: Native support for LogStruct types and hashes
- Rich metadata: Automatic inclusion of process ID, thread ID, timestamps
- Tagged context: Hierarchical tagging for request/job tracking
- Multiple destinations: Simultaneously log to files, STDOUT, cloud services
Development Experience
- Colorized output: Beautiful ANSI-colored logs in development
- Detailed timing: Built-in measurement of log processing time
- Context preservation: Maintains Rails.logger compatibility
Usage Examples
The logger automatically handles LogStruct types, hashes, and plain messages:
logger = LogStruct::SemanticLogger::Logger.new("MyApp")
# LogStruct typed logging (optimal performance)
log_entry = LogStruct::Log::Plain.new(
message: "User authenticated",
source: LogStruct::Source::App,
event: LogStruct::Event::Security
)
logger.info(log_entry)
# Hash logging (automatically structured)
logger.info({
action: "user_login",
user_id: 123,
ip_address: "192.168.1.1"
})
# Plain string logging (backward compatibility)
logger.info("User logged in successfully")
The logger is a drop-in replacement for Rails.logger and maintains full API compatibility while providing significantly enhanced performance.
Direct Known Subclasses
Integrations::GoodJob::Logger, Integrations::Sidekiq::Logger
Instance Attribute Summary collapse
-
#broadcasts ⇒ Object
readonly
Returns the value of attribute broadcasts.
-
#formatter ⇒ Object
readonly
Returns the value of attribute formatter.
Instance Method Summary collapse
- #<<(msg) ⇒ Object
- #broadcast_to(logger) ⇒ Object
- #clear_tags! ⇒ Object
- #current_tags ⇒ Object
-
#initialize(name = "Application", level: nil, filter: nil) ⇒ Logger
constructor
A new instance of Logger.
- #pop_tags(count = 1) ⇒ Object
- #push_tags(*tags) ⇒ Object
- #stop_broadcasting_to(logger) ⇒ Object
- #tagged(*tags, &block) ⇒ Object
Constructor Details
#initialize(name = "Application", level: nil, filter: nil) ⇒ Logger
Returns a new instance of Logger.
70 71 72 73 74 75 76 77 78 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 70 def initialize(name = "Application", level: nil, filter: nil) # SemanticLogger::Logger expects positional arguments, not named arguments super(name, level, filter) # T.untyped because users can pass any logger: ::Logger, ActiveSupport::Logger, # custom loggers (FakeLogger in tests), or third-party loggers @broadcasts = T.let([], T::Array[T.untyped]) # ActiveJob expects logger.formatter to exist and respond to current_tags @formatter = T.let(FormatterProxy.new, FormatterProxy) end |
Instance Attribute Details
#broadcasts ⇒ Object (readonly)
Returns the value of attribute broadcasts.
83 84 85 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 83 def broadcasts @broadcasts end |
#formatter ⇒ Object (readonly)
Returns the value of attribute formatter.
87 88 89 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 87 def formatter @formatter end |
Instance Method Details
#<<(msg) ⇒ Object
143 144 145 146 147 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 143 def <<(msg) info(msg) @broadcasts.each { |logger| logger << msg if logger.respond_to?(:<<) } self end |
#broadcast_to(logger) ⇒ Object
92 93 94 95 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 92 def broadcast_to(logger) @broadcasts << logger logger end |
#clear_tags! ⇒ Object
123 124 125 126 127 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 123 def # SemanticLogger doesn't have clear_tags!, use pop_tags instead count = ::SemanticLogger..length ::SemanticLogger.(count) if count > 0 end |
#current_tags ⇒ Object
118 119 120 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 118 def ::SemanticLogger. end |
#pop_tags(count = 1) ⇒ Object
137 138 139 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 137 def (count = 1) ::SemanticLogger.(count) end |
#push_tags(*tags) ⇒ Object
130 131 132 133 134 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 130 def (*) flat = .flatten.compact flat.each { |tag| ::SemanticLogger.(tag) } flat end |
#stop_broadcasting_to(logger) ⇒ Object
98 99 100 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 98 def stop_broadcasting_to(logger) @broadcasts.delete(logger) end |
#tagged(*tags, &block) ⇒ Object
106 107 108 109 110 111 112 113 114 |
# File 'lib/log_struct/semantic_logger/logger.rb', line 106 def tagged(*, &block) # Convert tags to array and pass individually to avoid splat issues tag_array = .flatten if tag_array.empty? super(&block) else super(*T.unsafe(tag_array), &block) end end |