You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
3.4 KiB

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
  1. require_relative 'wrapper'
  2. require 'io/console'
  3. # Opinioned Rails custom formatter
  4. class BasicFormatter < SemanticLogger::Formatters::Color
  5. NAME_MAX_SIZE = 25
  6. TERMINAL_PREFIX = ENV['TERMINAL_PREFIX'].to_i || 0
  7. CONTENT_PREFIX = ' '.freeze
  8. WRAP_PREFIX = ' > '.freeze
  9. ANSI_DEBUG = "\e[90m".freeze
  10. ANSI_INFO = SemanticLogger::AnsiColors::GREEN
  11. ANSI_WARN = SemanticLogger::AnsiColors::YELLOW
  12. ANSI_ERROR = "\e[91m".freeze
  13. ANSI_NEUTRAL_INFO = SemanticLogger::AnsiColors::WHITE
  14. ANSI_REVERSED_WARNING = "\e[0;30;43m".freeze
  15. ANSI_REVERSED_ERROR = "\e[1;30;41m".freeze
  16. ANSI_REVERSED_FATAL = "\e[1;30;41m".freeze
  17. CONTENT_COLOR_MAP = ColorMap.new(
  18. debug: ANSI_DEBUG,
  19. info: ANSI_NEUTRAL_INFO,
  20. warn: ANSI_REVERSED_WARNING,
  21. error: ANSI_REVERSED_ERROR,
  22. fatal: ANSI_REVERSED_FATAL
  23. )
  24. EXCLUDE_LAMBDA = lambda { |log|
  25. if log.name == 'ActionView::Base'
  26. !log.message.starts_with?(' Rendering')
  27. elsif log.name == 'Rails' && !log.message.nil?
  28. log.message.exclude?('Started GET "/rails/live/reload')
  29. else
  30. true
  31. end
  32. }
  33. def initialize
  34. super(color_map: ColorMap.new(
  35. debug: ANSI_DEBUG,
  36. info: ANSI_INFO,
  37. warn: ANSI_WARN,
  38. error: ANSI_ERROR,
  39. fatal: ANSI_ERROR
  40. ))
  41. end
  42. def message
  43. return unless log.message
  44. message = log.message
  45. if log.name == 'Rails' && message.starts_with?('Completed')
  46. message.rstrip!
  47. message += "\n" unless message.starts_with?('Completed 5')
  48. end
  49. begin
  50. wrap_length = IO.console.winsize[1] - TERMINAL_PREFIX - before_message.length + CONTENT_PREFIX.length + 12
  51. rescue StandardError
  52. wrap_length = 100
  53. end
  54. space_prefix = message.match(/^\s*/)
  55. message = Wrapper.wrap("#{CONTENT_COLOR_MAP[log.level]}#{message}", before_message(true, space_prefix),
  56. wrap_length - space_prefix.length)
  57. "#{CONTENT_COLOR_MAP[log.level]}#{message}#{color_map.clear}"
  58. end
  59. def level
  60. level = log.level == :info ? ' ' : log.level.to_s.chr.upcase
  61. "#{color}#{level}#{color_map.clear}"
  62. end
  63. def name
  64. "#{ANSI_DEBUG}#{log.name.truncate(NAME_MAX_SIZE).center(NAME_MAX_SIZE)}#{color_map.clear}"
  65. end
  66. def exception # rubocop:disable Metrics/AbcSize
  67. return unless log.exception
  68. root_path = Rails.root.to_s
  69. stack = log.exception.backtrace.select { |line| line.starts_with?(root_path) }
  70. stack = stack.map { |line| line.delete_prefix("#{root_path}/") }
  71. "#{ANSI_REVERSED_WARNING}#{log.exception.class}#{color_map.clear} #{ANSI_REVERSED_ERROR}#{log.exception.message}#{color_map.clear}#{backtrace(stack)}" # rubocop:disable Layout/LineLength
  72. end
  73. def call(log, logger)
  74. self.color = color_map[log.level]
  75. self.log = log
  76. self.logger = logger
  77. [before_message, message, payload, exception].compact.join(' ')
  78. end
  79. private
  80. def before_message(wrapped = false, prefix = '')
  81. result = [name, level, tags, named_tags, duration, CONTENT_PREFIX].compact.join(' ')
  82. if wrapped
  83. [name, level, tags, named_tags, duration,
  84. "#{color}#{WRAP_PREFIX}#{color_map.clear}#{prefix}"].compact.join(' ')
  85. else
  86. [name, level, tags, named_tags, duration,
  87. CONTENT_PREFIX].compact.join(' ')
  88. end
  89. end
  90. def backtrace(stack)
  91. nil unless stack.count.positive?
  92. "\n#{before_message} #{ANSI_ERROR}#{stack.join("\n#{before_message} #{ANSI_ERROR}")}#{color_map.clear}"
  93. end
  94. def color_content
  95. color
  96. end
  97. end