-
-
Save agile/660311 to your computer and use it in GitHub Desktop.
Revisions
-
gravis revised this gist
Nov 2, 2010 . 1 changed file with 2 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -86,8 +86,7 @@ def #{severity.downcase}? # def debug? # ** +auto_flushing+ : number of messages to buffer before flushing # def initialize(options = {}) @level = LOGGER_LEVEL_MAP[options[:level]] || Logger::DEBUG @host = options[:host] || 'localhost' @port = options[:port] = '514' @facility = options[:facility] || Syslog::LOG_USER @@ -182,4 +181,4 @@ def log(severity, msg) def write_on_socket(severity, msg) socket.write("<#{@facility + LEVEL_LOGGER_MAP[severity]}>#{Time.now.strftime("%b %e %H:%M:%S")} #{@local_ip} [#{@progname}]: #{msg}\n") end end -
gravis revised this gist
Sep 28, 2010 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,7 +16,7 @@ # For more info about Syslog protocol, please refer to the RFC: # http://www.faqs.org/rfcs/rfc3164.html # # Parts taken from SyslogLogger gem and ActiveSupport # class TcpSyslog < ActiveSupport::BufferedLogger include Logger::Severity @@ -166,8 +166,8 @@ def local_ip # This method is private, use the +add+ method instead def log(severity, msg) begin if @progname.length + msg.length > 996 # see RFC, max size for a message is 1024 bytes msg.scan(/.{#{996 - @progname.length}}/).each do |chunck| write_on_socket(severity, chunck) end else -
gravis revised this gist
Sep 26, 2010 . 2 changed files with 15 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,7 +16,7 @@ # For more info about Syslog protocol, please refer to the RFC: # http://www.faqs.org/rfcs/rfc3164.html # # Parts taken frm SyslogLogger gem and ActiveSupport # class TcpSyslog < ActiveSupport::BufferedLogger include Logger::Severity @@ -93,7 +93,9 @@ def initialize(options = {}) @facility = options[:facility] || Syslog::LOG_USER @progname = options[:progname] || 'rails' @buffer = {} @socket = {} @auto_flushing = options[:auto_flushing] || 1 @local_ip = local_ip return if defined? SYSLOG self.class.const_set :SYSLOG, true end @@ -121,6 +123,7 @@ def <<(message) def close flush socket.close end # Flush buffered logs to Syslog @@ -131,6 +134,10 @@ def flush clear_buffer end def socket @socket[Thread.current] ||= TCPSocket.new(@host, @port) end protected # Clean up messages so they're nice and pretty. @@ -173,8 +180,6 @@ def log(severity, msg) # actually write on the tcp socket def write_on_socket(severity, msg) socket.write("<#{@facility + LEVEL_LOGGER_MAP[severity]}>#{Time.now.strftime("%b %e %H:%M:%S")} #{@local_ip} [#{@progname}]: #{msg}\n") end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -28,8 +28,8 @@ end # => # user system total real # File 0.000000 0.010000 0.010000 ( 0.002294) # TCP 0.010000 0.000000 0.010000 ( 0.011050) # File (buffer = 20) 0.000000 0.000000 0.000000 ( 0.000841) # TCP (buffer = 20) 0.000000 0.000000 0.000000 ( 0.009806) -
gravis revised this gist
Sep 26, 2010 . 1 changed file with 35 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,35 @@ #!/usr/bin/env ruby require 'benchmark' require 'rubygems' require 'active_support' require 'lib/tcp_syslog' logger_tcp = TcpSyslog.new logger_file = ActiveSupport::BufferedLogger.new("/tmp/logfile") Benchmark.bm do |b| b.report("File") do 100.times { logger_file.info("benchmark") } end b.report("TCP") do 100.times { logger_tcp.info("benchmark") } end logger_file.auto_flushing = 20 b.report("File (buffer = 20)") do 100.times { logger_file.info("benchmark") } end logger_tcp.auto_flushing = 20 b.report("TCP (buffer = 20)") do 100.times { logger_tcp.info("benchmark") } end end # => # user system total real # File 0.000000 0.000000 0.000000 ( 0.002300) # TCP 0.010000 0.020000 0.030000 ( 0.032847) # File (buffer = 20) 0.000000 0.000000 0.000000 ( 0.000848) # TCP (buffer = 20) 0.010000 0.010000 0.020000 ( 0.031231) -
gravis created this gist
Sep 26, 2010 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,180 @@ require 'socket' require 'syslog' require 'logger' require 'hoptoad_notifier' # TcpSyslog is used are a dead-simple replacement for # syslog ruby libs. None of them is able to send logs # to a remote server, and even less in TCP. # # Example: # # For rails (2.X) : # # config.logger = TcpSyslog.new(host => 'localhost') # # For more info about Syslog protocol, please refer to the RFC: # http://www.faqs.org/rfcs/rfc3164.html # # Parts taken from SyslogLogger gem and ActiveSupport # class TcpSyslog < ActiveSupport::BufferedLogger include Logger::Severity # From 'man syslog.h': # LOG_EMERG A panic condition was reported to all processes. # LOG_ALERT A condition that should be corrected immediately. # LOG_CRIT A critical condition. # LOG_ERR An error message. # LOG_WARNING A warning message. # LOG_NOTICE A condition requiring special handling. # LOG_INFO A general information message. # LOG_DEBUG A message useful for debugging programs. # From logger rdoc: # FATAL: an unhandleable error that results in a program crash # ERROR: a handleable error condition # WARN: a warning # INFO: generic (useful) information about system operation # DEBUG: low-level information for developers # Maps Logger warning types to syslog(3) warning types. LOGGER_MAP = { :unknown => Syslog::LOG_ALERT, :fatal => Syslog::LOG_CRIT, :error => Syslog::LOG_ERR, :warn => Syslog::LOG_WARNING, :info => Syslog::LOG_INFO, :debug => Syslog::LOG_DEBUG } # Maps Logger log levels to their values so we can silence. LOGGER_LEVEL_MAP = {} LOGGER_MAP.each_key do |key| LOGGER_LEVEL_MAP[key] = Logger.const_get key.to_s.upcase end # Maps Logger log level values to syslog log levels. LEVEL_LOGGER_MAP = {} LOGGER_LEVEL_MAP.invert.each do |level, severity| LEVEL_LOGGER_MAP[level] = LOGGER_MAP[severity] end MAX_BUFFER_SIZE = 1000 # Builds a methods for level +meth+. for severity in Logger::Severity.constants class_eval <<-EOT, __FILE__, __LINE__ def #{severity.downcase}(message = nil, progname = nil, &block) # def debug(message = nil, progname = nil, &block) add(#{severity}, message, progname, &block) # add(DEBUG, message, &block) end # end # def #{severity.downcase}? # def debug? #{severity} >= @level # DEBUG >= @level end # end EOT end # Usage : # * +options+ : A hash with the following options # ** +host+ : defaults to 'localhost' # ** +port+ : defaults to '514' # ** +facility+ : defaults to user # ** +progname+ : defaults to 'rails' # ** +auto_flushing+ : number of messages to buffer before flushing # def initialize(options = {}) @level = Logger::DEBUG @host = options[:host] || 'localhost' @port = options[:port] = '514' @facility = options[:facility] || Syslog::LOG_USER @progname = options[:progname] || 'rails' @buffer = {} @auto_flushing = options[:auto_flushing] || 1 return if defined? SYSLOG self.class.const_set :SYSLOG, true end # Log level for Logger compatibility. attr_reader :host, :port, :facility, :auto_flushing, :progname # Check ActiveSupport::BufferedLogger for other attributes # Almost duplicates Logger#add. def add(severity, message, progname = nil, &block) severity ||= Logger::UNKNOWN return if @level > severity message = clean(message || block.call) buffer << {:severity => severity, :body => clean(message)} auto_flush message end # In Logger, this dumps the raw message; the closest equivalent # would be Logger::UNKNOWN def <<(message) add(Logger::UNKNOWN, message) end def close flush end # Flush buffered logs to Syslog def flush buffer.each do |message| log(message[:severity], message[:body]) end clear_buffer end protected # Clean up messages so they're nice and pretty. def clean(message) message = message.to_s.dup message.strip! message.gsub!(/%/, '%%') # syslog(3) freaks on % (printf) message.gsub!(/\e\[[^m]*m/, '') # remove useless ansi color codes return message end # Returns current ip # (taken from http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/) def local_ip orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily UDPSocket.open do |s| s.connect '64.233.187.99', 1 s.addr.last end ensure Socket.do_not_reverse_lookup = orig end # Log the message to syslog # This method is private, use the +add+ method instead def log(severity, msg) begin if LOGGER_LEVEL_MAP.invert[severity].to_s.length + @progname.length + msg.length > 996 # see RFC, max size for a message is 1024 bytes msg.scan(/.{#{996- @progname.length - LOGGER_LEVEL_MAP.invert[severity].to_s.length}}/).each do |chunck| write_on_socket(severity, chunck) end else write_on_socket(severity, msg) end rescue Errno::ECONNREFUSED, Errno::EPIPE => e HoptoadNotifier.notify e # can't log, how would we know ?? end end # actually write on the tcp socket def write_on_socket(severity, msg) socket = TCPSocket.new(@host, @port) socket.write("<#{@facility + LEVEL_LOGGER_MAP[severity]}>#{Time.now.strftime("%b %e %H:%M:%S")} #{local_ip} [#{@progname}] [#{LOGGER_LEVEL_MAP.invert[severity].to_s.upcase}] #{msg}\n") socket.close end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,79 @@ # Using test-unit, should and RR for tests require 'test_helper.rb' require 'syslog' class TcpSyslogTest < ActiveSupport::TestCase context "A TcpSyslogger" do setup do @logger = TcpSyslog.new end should "have set defaults correctly" do assert_equal 'localhost', @logger.host assert_equal '514', @logger.port assert_equal Syslog::LOG_USER, @logger.facility assert_equal 'rails', @logger.progname assert_equal 1, @logger.auto_flushing assert_equal Logger::DEBUG, @logger.level end should "have defined debug, info, warn, error, fatal methods" do assert @logger.respond_to?(:debug) assert @logger.respond_to?(:info) assert @logger.respond_to?(:warn) assert @logger.respond_to?(:error) assert @logger.respond_to?(:fatal) end context "on add message" do setup do message = "This message to be sent to syslog" mock.proxy(@logger).flush mock.proxy(@logger).log(Logger::INFO, message) mock.proxy(@logger).write_on_socket(Logger::INFO, message) @logger.add(Logger::INFO, message) end should "have sent the message to syslog" do RR.verify end end end context "A TcpSyslogger with auto_flushing set to 2" do setup do @logger = TcpSyslog.new(:auto_flushing => 2) end should "have set auto_flushing to 2" do assert_equal 2, @logger.auto_flushing end context "when adding a message" do setup do message = "info message" dont_allow(@logger).write_on_socket(Logger::INFO, message) @logger.info(message) end should "not send the message to syslog now" do RR.verify end context "and adding another message" do setup do message2 = "info message 2" RR.reset mock.proxy(@logger).write_on_socket(Logger::INFO, anything).twice @logger.info(message2) end should "have sent the messages to syslog" do RR.verify end end end end end