module Semantic # My Custom colorized formatter class BasicFormatter < AbstractFormatter ANSI_REVERSED_WARNING = "\e[0;30;43m".freeze ANSI_REVERSED_ERROR = "\e[1;30;41m".freeze MAX_LENGTH_LINE = 255 PRIME = '▍'.freeze CONTINATION = '▕'.freeze def initialize super(color_map: ColorMap.new( debug: TEXT_GRAY_400, info: TEXT_GREEN, warn: TEXT_YELLOW, error: LIGHT_TEXT_RED, fatal: TEXT_MAGENTA )) @time_format = File.exist?(File.join(Rails.root, 'Procfile.dev')) ? nil : '%H:%M:%S' end def call(log, logger) self.color = color_map[log.level] self.log = log self.logger = logger wrap_level(MAX_LENGTH_LINE, duration, named_tags, message, payload, exception) rescue StandardError => e puts "Error during formatting: #{e.message}" puts e.backtrace.join("\n") end private def wrap_level(length, *items) prime = "#{build_prime} " continuation = "#{build_continuation} " items .map { |item| Semantic::AnsiWrapper.wrap(item, length, prime, continuation) } .compact.join("\n") end def message return unless log.message log.level == :info ? colorize(log.message, TEXT_WHITE) : colorize(log.message) end def process_info fname = file_name_and_line colorize fname if fname end def time = @time_format ? colorize(format_time(log.time), color) : nil def build_prefix(char) = [time, tags, origin, colorize(char)].compact.join ' ' def build_prime = build_prefix(PRIME) def build_continuation = build_prefix(CONTINATION) end end