Class: AllStak::Integrations::Logger
- Inherits:
-
Logger
- Object
- Logger
- AllStak::Integrations::Logger
- Defined in:
- lib/allstak/integrations/logger.rb
Overview
Optional structured-log adapter.
A drop-in Logger-compatible sink that forwards every log record to AllStak’s ‘/ingest/v1/logs` endpoint (via AllStak.log). It is intended to be *broadcast alongside* your existing logger so app logs keep going to STDOUT/file unchanged while also flowing into AllStak — no per-call code.
ERROR PROMOTION: records at or above #error_promotion_level (default ERROR) are additionally captured as AllStak “message” error-group entries (via AllStak.capture_message) so error-level logs surface in the Errors list, not just the log stream. Set ‘error_promotion: false` to disable.
OPT-IN by design — adding this adapter is the only manual step; after that ‘Rails.logger.error(…)` / `logger.warn(…)` ship automatically.
# Rails 7.1+ (BroadcastLogger) — keep existing logging, add AllStak:
AllStak::Integrations::Logger.attach_to_rails!
# Or compose manually with any Ruby Logger:
sink = AllStak::Integrations::Logger.new
Rails.logger.broadcast_to(sink) # Rails 7.1+
# ...or wrap a single logger so both get every line:
Rails.logger = AllStak::Integrations::Logger.broadcast(Rails.logger)
Fully fail-open: a transport/SDK error never propagates into the host’s logging path, and the adapter is a graceful no-op when the SDK is not configured.
Defined Under Namespace
Classes: BroadcastLogger
Constant Summary collapse
- SEVERITY_TO_LEVEL =
Map Ruby Logger severities to AllStak log levels.
{ ::Logger::DEBUG => "debug", ::Logger::INFO => "info", ::Logger::WARN => "warn", ::Logger::ERROR => "error", ::Logger::FATAL => "fatal", ::Logger::UNKNOWN => "error" }.freeze
Instance Attribute Summary collapse
-
#error_promotion_level ⇒ Object
readonly
Returns the value of attribute error_promotion_level.
Class Method Summary collapse
-
.attach_to_rails!(**opts) ⇒ Object
Attach an AllStak sink to the current Rails.logger without replacing the existing logging destinations.
-
.broadcast(existing, **opts) ⇒ Object
Compose ‘existing` with an AllStak sink so both receive every record.
-
.reset_attached! ⇒ Object
Test seam.
Instance Method Summary collapse
-
#<<(msg) ⇒ Object
‘logger << “raw”` writes an UNKNOWN-severity record in Ruby Logger.
-
#add(severity, message = nil, progname = nil, &block) ⇒ Object
Core Logger entry point.
-
#initialize(level: ::Logger::DEBUG, error_promotion: true, error_promotion_level: ::Logger::ERROR) ⇒ Logger
constructor
A new instance of Logger.
Constructor Details
#initialize(level: ::Logger::DEBUG, error_promotion: true, error_promotion_level: ::Logger::ERROR) ⇒ Logger
Returns a new instance of Logger.
50 51 52 53 54 55 56 57 58 |
# File 'lib/allstak/integrations/logger.rb', line 50 def initialize(level: ::Logger::DEBUG, error_promotion: true, error_promotion_level: ::Logger::ERROR) # logdev=nil: this sink does not write to any device of its own; it only # forwards into AllStak. Composition (broadcast) keeps the real device. super(nil) self.level = level @error_promotion = error_promotion != false @error_promotion_level = error_promotion_level end |
Instance Attribute Details
#error_promotion_level ⇒ Object (readonly)
Returns the value of attribute error_promotion_level.
43 44 45 |
# File 'lib/allstak/integrations/logger.rb', line 43 def error_promotion_level @error_promotion_level end |
Class Method Details
.attach_to_rails!(**opts) ⇒ Object
Attach an AllStak sink to the current Rails.logger without replacing the existing logging destinations. Idempotent and fail-open. Returns true when (now) attached, false otherwise (no Rails / no logger).
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/allstak/integrations/logger.rb', line 99 def attach_to_rails!(**opts) return false unless defined?(::Rails) && ::Rails.respond_to?(:logger) current = ::Rails.logger return false if current.nil? return true if @attached_to_rails sink = new(**opts) if current.respond_to?(:broadcast_to) # Rails 7.1+ BroadcastLogger — add without disturbing existing sinks. current.broadcast_to(sink) else ::Rails.logger = broadcast(current, **opts) end @attached_to_rails = true true rescue StandardError false end |
.broadcast(existing, **opts) ⇒ Object
Compose ‘existing` with an AllStak sink so both receive every record. Prefers Rails’ BroadcastLogger when available; otherwise returns a BroadcastLogger shim. Returns ‘existing` unchanged on any failure.
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/allstak/integrations/logger.rb', line 85 def broadcast(existing, **opts) sink = new(**opts) if defined?(::ActiveSupport::BroadcastLogger) ::ActiveSupport::BroadcastLogger.new(existing, sink) else BroadcastLogger.new([existing, sink]) end rescue StandardError existing end |
.reset_attached! ⇒ Object
Test seam.
119 120 121 |
# File 'lib/allstak/integrations/logger.rb', line 119 def reset_attached! @attached_to_rails = false end |
Instance Method Details
#<<(msg) ⇒ Object
‘logger << “raw”` writes an UNKNOWN-severity record in Ruby Logger.
76 77 78 79 |
# File 'lib/allstak/integrations/logger.rb', line 76 def <<(msg) add(::Logger::UNKNOWN, msg.to_s) msg end |
#add(severity, message = nil, progname = nil, &block) ⇒ Object
Core Logger entry point. Every severity helper (#debug/#info/#warn/ #error/#fatal/#unknown) and ‘<<` funnel through #add, so overriding it captures the whole surface. Returns true (Logger#add contract) and never raises into the host.
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/allstak/integrations/logger.rb', line 64 def add(severity, = nil, progname = nil, &block) severity ||= ::Logger::UNKNOWN return true if severity < level text = (, progname, &block) forward(severity, text, progname) true rescue StandardError true end |