91 lines
2.2 KiB
Ruby
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
|