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.

88 lines
2.6 KiB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
  1. # Opinioned Rails custom formatter
  2. class BasicFormatter < SemanticLogger::Formatters::Color
  3. NAME_MAX_SIZE = 25
  4. CONTENT_PREFIX = ' '.freeze
  5. ANSI_DEBUG = "\e[90m".freeze
  6. ANSI_INFO = SemanticLogger::AnsiColors::GREEN
  7. ANSI_WARN = SemanticLogger::AnsiColors::YELLOW
  8. ANSI_ERROR = "\e[91m".freeze
  9. ANSI_NEUTRAL_INFO = SemanticLogger::AnsiColors::WHITE
  10. ANSI_REVERSED_WARNING = "\e[0;30;43m".freeze
  11. ANSI_REVERSED_ERROR = "\e[1;30;41m".freeze
  12. ANSI_REVERSED_FATAL = "\e[1;30;41m".freeze
  13. CONTENT_COLOR_MAP = ColorMap.new(
  14. debug: ANSI_DEBUG,
  15. info: ANSI_NEUTRAL_INFO,
  16. warn: ANSI_REVERSED_WARNING,
  17. error: ANSI_REVERSED_ERROR,
  18. fatal: ANSI_REVERSED_FATAL
  19. )
  20. EXCLUDE_LAMBDA = lambda { |log|
  21. if log.name == 'ActionView::Base'
  22. !log.message.starts_with?(' Rendering')
  23. elsif log.name == 'Rails' && !log.message.nil?
  24. log.message.exclude?('Started GET "/rails/live/reload')
  25. else
  26. true
  27. end
  28. }
  29. def initialize
  30. super(color_map: ColorMap.new(
  31. debug: ANSI_DEBUG,
  32. info: ANSI_INFO,
  33. warn: ANSI_WARN,
  34. error: ANSI_ERROR,
  35. fatal: ANSI_ERROR
  36. ))
  37. end
  38. def message
  39. return unless log.message
  40. message = log.message
  41. if log.name == 'Rails' && message.starts_with?('Completed')
  42. message.rstrip!
  43. message += "\n" unless message.starts_with?('Completed 5')
  44. end
  45. "#{CONTENT_PREFIX}#{CONTENT_COLOR_MAP[log.level]}#{message}#{color_map.clear}"
  46. end
  47. def level
  48. level = log.level == :info ? ' ' : log.level.to_s.chr.upcase
  49. "#{color}#{level}#{color_map.clear}"
  50. end
  51. def name
  52. "#{ANSI_DEBUG}#{log.name.truncate(NAME_MAX_SIZE).center(NAME_MAX_SIZE)}#{color_map.clear}"
  53. end
  54. def exception # rubocop:disable Metrics/AbcSize
  55. return unless log.exception
  56. root_path = Rails.root.to_s
  57. stack = log.exception.backtrace.select { |line| line.starts_with?(root_path) }
  58. stack = stack.map { |line| line.delete_prefix("#{root_path}/") }
  59. "#{CONTENT_PREFIX}#{ANSI_REVERSED_ERROR}#{log.exception.class}#{color_map.clear}: #{color}#{log.exception.message}#{color_map.clear}#{backtrace(stack)}" # rubocop:disable Layout/LineLength
  60. end
  61. def call(log, logger)
  62. self.color = color_map[log.level]
  63. self.log = log
  64. self.logger = logger
  65. [name, level, tags, named_tags, duration, message, payload, exception].compact.join(' ')
  66. end
  67. private
  68. def backtrace(stack)
  69. nil unless stack.count.positive?
  70. prefix = [name, level, tags, named_tags, duration, message, payload, CONTENT_PREFIX].compact.join(' ')
  71. "\n#{prefix}#{ANSI_ERROR}#{stack.join("\n#{prefix}#{ANSI_ERROR}")}#{color_map.clear}"
  72. end
  73. end