require 'active_support/core_ext/module/delegation' require 'bigdecimal' require 'bigdecimal/util' module WebsocketRails module Logging # Logging module heavily influenced by Travis-Support library ANSI = { :red => 31, :green => 32, :yellow => 33, :cyan => 36 } class << self def configure(logger) logger.tap do logger.formatter = proc { |*args| Format.format(*args) } logger.level = Logger.const_get(log_level.to_s.upcase) end end def log_level WebsocketRails.config.log_level || :debug end end delegate :logger, :to => WebsocketRails [:fatal, :error, :warn, :info, :debug].each do |level| define_method(level) do |*args| message, options = *args log(level, message, options) end end def log(level, message, options = {}) message.chomp.split("\n").each do |line| logger.send(level, wrap(level, self, line, options || {})) end logger << "\n" end def log_event_start(event) message = "Started Event: #{event.encoded_name}\n" message << "#{colorize(:cyan, "Name:")} #{event.encoded_name}\n" message << "#{colorize(:cyan, "Data:")} #{event.data.inspect}\n" message << "#{colorize(:cyan, "Connection:")} #{event.connection}\n\n" info message end def log_event_end(event, time) info "Event #{event.encoded_name} Finished in #{time.to_f.to_d.to_s} seconds\n\n" end def log_event(event, &block) log_event_start(event) if log_event?(event) start_time = Time.now block.call total_time = Time.now - start_time log_event_end(event, total_time) if log_event?(event) rescue Exception => ex log_exception(ex) raise end def log_event?(event) if event.is_internal? WebsocketRails.config.log_internal_events? else true end end def log_exception(exception) logger.error(wrap(:error, self, "#{exception.class.name}: #{exception.message}")) exception.backtrace.each { |line| logger.error(wrap(:error, self, line)) } if exception.backtrace logger << "\n" rescue Exception => ex puts '--- FATAL ---' puts 'an exception occured while logging an exception' puts ex.message, ex.backtrace puts exception.message, exception.backtrace end def wrap(level, object, message, options = {}) header = options[:header] || object.log_header color = color_for_level(level) "[#{colorize(color, header)}] #{message.chomp}" end def colorize(color, text) "\e[#{ANSI[color]}m#{text}\e[0m" end def color_for_level(level) case level when :info then :green when :debug then :yellow else :red end end def log_header self.class.name.split('::').last end module Format class << self def format(severity, time, progname, msg) "#{severity[0, 1]} [#{format_time(time)}] #{msg}\n" end def format_time(time) time.strftime("%Y-%m-%d %H:%M:%S.") << time.usec.to_s[0, 3] end end end end end