Browse Source

ansi_dimensions

main
pvincent 4 months ago
parent
commit
a97b16b9d3
  1. 2
      app/controllers/scores_controller.rb
  2. 7
      config/environments/development.rb
  3. 6
      lib/formatters/ansi_dimensions.rb
  4. 21
      lib/formatters/ansi_filter.rb
  5. 83
      lib/formatters/ansi_formatter.rb
  6. 88
      lib/formatters/symbols.txt
  7. 0
      lib/monkey_patches/action_dispatch/debug_exceptions.rb
  8. 0
      lib/monkey_patches/rails_semantic_logger/base.rb

2
app/controllers/scores_controller.rb

@ -90,7 +90,7 @@ class ScoresController < ApplicationController
private private
def do_an_exception def do_an_exception
raise 'Unable to destroy this score' * 5
raise 'Unable to destroy this score. ' * 5
end end
# Use callbacks to share common setup or constraints between actions. # Use callbacks to share common setup or constraints between actions.

7
config/environments/development.rb

@ -81,12 +81,13 @@ Rails.application.configure do # rubocop:disable Metrics/BlockLength
config.rails_semantic_logger.rendered = true config.rails_semantic_logger.rendered = true
config.rails_semantic_logger.add_file_appender = false config.rails_semantic_logger.add_file_appender = false
require Rails.root.join('lib', 'formatters', 'basic_formatter')
require Rails.root.join('lib', 'formatters', 'ansi_formatter') require Rails.root.join('lib', 'formatters', 'ansi_formatter')
require Rails.root.join('lib', 'formatters', 'ansi_filter')
config.semantic_logger.add_appender(io: $stdout, config.semantic_logger.add_appender(io: $stdout,
formatter: AnsiFormatter.new)
formatter: AnsiFormatter.new,
filter: ->(log) { !AnsiFilter.reject(log) })
# require Rails.root.join('lib', 'formatters', 'basic_formatter')
# config.semantic_logger.add_appender(io: $stdout, # config.semantic_logger.add_appender(io: $stdout,
# formatter: BasicFormatter.new, # formatter: BasicFormatter.new,
# filter: BasicFormatter::EXCLUDE_LAMBDA) # filter: BasicFormatter::EXCLUDE_LAMBDA)

6
lib/formatters/ansi_dimensions.rb

@ -0,0 +1,6 @@
# extra dimensions to customize ansi_loggingg
module AnsiDimensions
def self.new(rails: '╣x╠', before: 0, after: 0)
OpenStruct.new(rails:, before:, after:)
end
end

21
lib/formatters/ansi_filter.rb

@ -0,0 +1,21 @@
require_relative 'ansi_dimensions'
# filter log message
module AnsiFilter
def self.reject(log)
# log.name == 'ScoresController' || false
false
end
def self.alter(log)
if log.name == 'Rails' && log.message
log.dimensions = AnsiDimensions.new(rails: '╓─╖', before: 1) if log.message.starts_with?('Started')
if log.message.starts_with?('Completed 200 OK')
log.dimensions = AnsiDimensions.new(rails: '╙─╜', after: 1)
log.message.chomp!('')
end
end
log
end
end

83
lib/formatters/ansi_formatter.rb

@ -9,72 +9,68 @@ require 'json'
class AnsiFormatter < SemanticLogger::Formatters::Color class AnsiFormatter < SemanticLogger::Formatters::Color
include AnsiColors include AnsiColors
ANSI_DEBUG = CLEAR + TEXT_GRAY_400
ANSI_INFO = CLEAR + TEXT_GRAY_100
ANSI_WARN = CLEAR + BG_YELLOW + TEXT_BLACK
ANSI_ERROR = CLEAR + BG_RED + TEXT_WHITE
ANSI_FATAL = CLEAR + BG_MAGENTA + BOLD + TEXT_WHITE
NAME_MAX_SIZE = 20
CENTER_SIZE = 20
FOREMAN_PREFIX_LENGTH = 18 FOREMAN_PREFIX_LENGTH = 18
DEFAULT_UNDETECTED_WRAP = 80
FAILOVER_WRAP = 80
def initialize def initialize
super(color_map: ColorMap.new(
debug: ANSI_DEBUG,
info: ANSI_INFO,
warn: ANSI_WARN,
error: ANSI_ERROR,
fatal: ANSI_FATAL
super(color_map:
ColorMap.new(
debug: CLEAR + TEXT_GRAY_400,
info: CLEAR + TEXT_GRAY_100,
warn: CLEAR + BG_YELLOW + TEXT_BLACK,
error: CLEAR + BG_RED + TEXT_WHITE,
fatal: CLEAR + BG_MAGENTA + BOLD + TEXT_WHITE
)) ))
end end
def call(log, logger) def call(log, logger)
log = AnsiFilter.alter(log)
self.log = log self.log = log
self.logger = logger self.logger = logger
self.color = color_map[log.level] self.color = color_map[log.level]
wrap_length = compute_useful_length
wrap_level(wrap_length, message, payload, exception)
end
def origin
origin = log.name.truncate(NAME_MAX_SIZE).center(NAME_MAX_SIZE)
colorize(origin, AnsiColors::TEXT_CYAN)
wrap_level(compute_useful_length, message, payload, exception)
end end
def message
return unless log.message
private
colorize(log.message)
end
def origin = colorize(centerize(log.name), TEXT_CYAN)
def build_prefix(char) = "#{origin}#{colorize(char)}"
def centerize(text) = text.truncate(CENTER_SIZE).center(CENTER_SIZE)
def colorize(text, tint = color) = "#{tint}#{text}#{CLEAR}"
def stackisize(items) = items.length.positive? ? "\n#{items.join("\n")}" : ''
def exception
return unless log.exception
def build_dimensions(dimensions)
"#{origin} #{dimensions.rails} "
end
clazz = "#{log.exception.class}\n"
message = log.exception.message.chomp('')
backtrace = clean_backtrace(log.exception.backtrace)
def compute_useful_length
IO.console.winsize[1] - FOREMAN_PREFIX_LENGTH
rescue StandardError
FAILOVER_WRAP
end
"#{colorize(clazz, ANSI_FATAL)}#{colorize(message, ANSI_ERROR)}#{backtrace}"
def message
colorize(log.message) if log.message
end end
private
def exception
return unless log.exception
def colorize(text, tint = color) = "#{tint}#{text}#{AnsiColors::CLEAR}"
def build_prefix = "#{origin} #{colorize(draw_rails(level_char))} "
def build_continuation = "#{origin} #{colorize(draw_rails('┆'))} "
def draw_rails(char) = "#{char}"
exc = log.exception
clazz = colorize("#{exc.class}\n", color_map[:fatal])
message = colorize(exc.message.chomp(''), color_map[:error])
backtrace = stackisize(clean_backtrace(exc.backtrace))
def compute_useful_length
IO.console.winsize[1] - FOREMAN_PREFIX_LENGTH
rescue StandardError
DEFAULT_UNDETECTED_WRAP
"#{clazz}#{message}#{backtrace}"
end end
def clean_backtrace(backtrace) def clean_backtrace(backtrace)
root_path = Rails.root.to_s root_path = Rails.root.to_s
backtrace = backtrace.select { |line| line.starts_with?(root_path) } backtrace = backtrace.select { |line| line.starts_with?(root_path) }
backtrace = backtrace.map { |line| line.delete_prefix("#{root_path}/") }
backtrace.compact.join("\n")
backtrace.map { |line| line.delete_prefix("#{root_path}/") }
end end
def level_char def level_char
@ -85,8 +81,11 @@ class AnsiFormatter < SemanticLogger::Formatters::Color
end end
def wrap_level(length, *items) def wrap_level(length, *items)
prefix = build_prefix
continuation = build_continuation
prefix = log.dimensions ? build_dimensions(log.dimensions) : build_prefix(level_char)
continuation = build_prefix('┆')
log.dimensions&.before&.times { items.unshift('') }
log.dimensions&.after&.times { items << '' }
items.map do |item| items.map do |item|
AnsiWrapper.wrap(item, length, prefix, continuation) AnsiWrapper.wrap(item, length, prefix, continuation)
end.compact.join("\n") end.compact.join("\n")

88
lib/formatters/symbols.txt

@ -1,15 +1,16 @@
╣ ╠ ╣ ╠
╣ǁ╠ ╣ǁ╠
╣▹╠ ╣▹╠
╣▥╠
╣◉╠ ╣◉╠
╙─╜
╣◼╠
╙╨╜ ╙╨╜
╣☉╠
╙─╜
╙─╜ ╙─╜
╣◼╠
╣▥╠
╣☉╠
╙─╜ ╙─╜
╣☀╠ ╣☀╠
╙─╜ ╙─╜
🛑 🛑
@ -43,7 +44,35 @@
╙╨╜
╙─╜ 200 OK
╙ ╜ 300 redirect
╙⸾╜ 300 redirect
╙ǁ╜
╙⍑╜
╙─╜
╓─╖
╣⸾╠
╙─╜
╙╨╜ 400 client error
╙ǁ╜ 400 client error
╙⍑╜ 500 servererror
╙⯶╜ 500 servererror
╙ ╜ 500 servererror
╣ ╠
╣⍑╠
╣⍑╠
╣⯶╠
╣⸾╠
╙─╜
╣┻╠
╓─╖ ╓─╖
╣║╠ ╣║╠
╣║╠ ╣║╠
@ -51,22 +80,25 @@
╣┊╠ ╣┊╠
╣┆╠ ╣┆╠
╣│╠ ╣│╠
╣┻╠
╣⇰╠
╣⭪╠
╣⥱╠
╣⇴╠
╣⇲╠
╣⇥╠
╣⇄╠
╣⇣╠
╙╨╜ ╙╨╜
╙─╜ ╙─╜
╣⇰╠⭪⬸⥱⇴⇲⇥⇄⇣
╣⎇╠
╣⍾╠
╙─╜ ╙─╜
╣⍾╠
╣⬸╠
╣☐╠ ╣☐╠
╙─╜
╣☑╠ ╣☑╠
╙─╜ ╙─╜
╙─╜
╣☒╠ ╣☒╠
╙─╜ ╙─╜
@ -85,23 +117,31 @@
╣⦾╠ ╣⦾╠
╙─╜
╣ ╠
⦿ ⦿
ⵙⵞ⸾
ⵙⵞ
╣⫨╠
╣⤫╠
╣⫫╠ ╣⫫╠
⫫⫨⮓⮱⮾⇤
➾➟⬎
╙ ╜

0
lib/monkey_patches/rails_semantic_logger/debug_exceptions.rb → lib/monkey_patches/action_dispatch/debug_exceptions.rb

0
lib/formatters/base.rb → lib/monkey_patches/rails_semantic_logger/base.rb

Loading…
Cancel
Save