Files
redux-scraper/app/lib/color_logger.rb
2025-02-14 08:13:21 +00:00

91 lines
2.2 KiB
Ruby

# typed: strict
class ColorLogger < Logger
extend T::Sig
include ActiveSupport::TaggedLogging
@quiet =
T.let(Concurrent::ThreadLocalVar.new { 0 }, Concurrent::ThreadLocalVar)
@log_line_accumulator =
T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
sig { params(sink: T.any(IO, StringIO)).returns(ColorLogger) }
def self.make(sink)
logger = ColorLogger.new(sink, @log_line_accumulator)
ActiveSupport::TaggedLogging.new(logger)
end
# @param log_line_accumulator a proc that is called with a String and returns void
sig do
params(
log_line_accumulator: T.nilable(T.proc.params(line: String).void),
).void
end
def self.log_line_accumulator=(log_line_accumulator)
@log_line_accumulator.value = log_line_accumulator
end
sig { params(blk: T.proc.void).void }
def self.quiet(&blk)
@quiet.value += 1
blk.call
ensure
@quiet.value -= 1
end
sig { params(blk: T.proc.void).void }
def self.unquiet(&blk)
saved = @quiet.value
@quiet.value = 0
blk.call
ensure
@quiet.value = saved
end
sig { returns(T::Boolean) }
def self.quiet?
@quiet.value > 0
end
sig { returns(T.nilable(T.any(String, T.proc.returns(String)))) }
attr_reader :prefix
sig { params(prefix: T.any(String, T.proc.returns(String))).void }
def prefix=(prefix)
@prefix = prefix
end
private
sig do
params(
sink: T.any(IO, StringIO),
log_line_accumulator: Concurrent::ThreadLocalVar,
).void
end
def initialize(sink, log_line_accumulator)
super(sink)
@prefix = T.let(nil, T.nilable(T.any(String, T.proc.returns(String))))
@log_lines = T.let([], T::Array[String])
this = self
this.define_singleton_method(:prefix=) do |prefix|
this.instance_variable_set(:@prefix, prefix)
end
self.formatter =
proc do |severity, datetime, progname, msg|
prefix = this.instance_variable_get(:@prefix)
prefix = prefix.call if prefix.is_a?(Proc)
line = [prefix, msg].reject(&:blank?).join(" ")
if (lla = log_line_accumulator.value)
lla.call(line)
end
line += "\n"
line = "" if ColorLogger.quiet?
line
end
end
end