#require 'log4r-1.0.5/src/log4r' require 'log4r' require 'uri' require 'socket' require 'yaml' # TODO: # - lepszy rozdzial danych z trace na file/method/line # - konfigurowalne korzystanie z file zamiast kategorii albo uzywnie prawdziwych kateogrii vide (**) module Log4r class ChainsawOutputter < Outputter attr_reader :uri, :socket # uri = chainsaw://host:port def initialize(_name, hash={}) super(_name, hash) _uri = (hash[:uri] or hash['uri'] or 'chainsaw://127.0.0.1:4445') @uri = URI.parse(_uri) raise RuntimeError, "Correct URI is 'chainsaw://host:port'", caller if @uri.scheme != 'chainsaw' @retry_cnt =0 @silent = (hash[:silent] or hash['silent'] or true) end # Call flush to send any remaining LogEvents to the remote server. def flush socket.flush if socket && !socket.closed? end private def canonical_log(logevent) #synch { begin if socket.nil? || socket.closed? connect end # wersja do wykorzystania z przerobionym klientem chainsaw 1 # data = { # :date => Time.now.to_i, # :level => Log4r::LNAMES[logevent.level], # :category => logevent.fullname.to_s, # :message => logevent.data, # :location => (logevent.tracer && logevent.tracer[0])||'' # } # socket.puts(data.to_yaml.gsub(/\n/, '\\n')) # (**) Ekspertyment - zamiast uzywac kategoriue (nazwy loggerow) tak jak w log4r # tworze sztuczne kategorie z pliku - dzieki temu dostaje lepsza funckjonalnosci # dot. filtrowania w Chainsaw trace = (logevent.tracer && logevent.tracer[0])||'' location = trace.split('/') min = location.size>3 ? 3 : location.size #TODO: precyzyjniejsza ekstrakcja informacji o metodzie i numerze lini teraz wszsytko jest w jednym polu file_and_method = location[-min..-1].join('/').tr('\'"`', '') location[-1]=(location[-1].to_s.slice(/.*\.rb/)||'') location[-1].tr!('.','_') category = location[-min..-1].join('.') xml = %Q{} socket.puts(xml) flush rescue socket.close if socket @retry_cnt += 1 if @retry_cnt < 5 retry else raise unless @silent end end #} end def connect @socket = TCPSocket.new(uri.host, uri.port) end end end