lib/semantic_logger/appender/syslog.rb in semantic_logger-3.0.1 vs lib/semantic_logger/appender/syslog.rb in semantic_logger-3.1.0
- old
+ new
@@ -3,31 +3,23 @@
require 'socket'
# Send log messages to local syslog, or remote syslog servers over TCP or UDP.
#
# Example: Log to a local Syslog daemon
-# SemanticLogger.add_appender(SemanticLogger::Appender::Syslog.new)
+# SemanticLogger.add_appender(appender: :syslog)
#
# Example: Log to a remote Syslog server using TCP:
-# appender = SemanticLogger::Appender::Syslog.new(
-# url: 'tcp://myloghost:514'
+# SemanticLogger.add_appender(
+# appender: :syslog,
+# url: 'tcp://myloghost:514'
# )
#
-# # Optional: Add filter to exclude health_check, or other log entries
-# appender.filter = Proc.new { |log| log.message !~ /(health_check|Not logged in)/ }
-#
-# SemanticLogger.add_appender(appender)
-#
# Example: Log to a remote Syslog server using UDP:
-# appender = SemanticLogger::Appender::Syslog.new(
-# url: 'udp://myloghost:514'
+# SemanticLogger.add_appender(
+# appender: :syslog,
+# url: 'udp://myloghost:514'
# )
-#
-# # Optional: Add filter to exclude health_check, or other log entries
-# appender.filter = Proc.new { |log| log.message !~ /(health_check|Not logged in)/ }
-#
-# SemanticLogger.add_appender(appender)
module SemanticLogger
module Appender
class Syslog < SemanticLogger::Appender::Base
attr_reader :remote_syslog, :url, :server, :port, :protocol, :facility, :host, :application
@@ -79,10 +71,15 @@
#
# level: [:trace | :debug | :info | :warn | :error | :fatal]
# Override the log level for this appender.
# Default: SemanticLogger.default_level
#
+ # formatter: [Object|Proc]
+ # An instance of a class that implements #call, or a Proc to be used to format
+ # the output from this appender
+ # Default: Use the built-in formatter (See: #call)
+ #
# filter: [Regexp|Proc]
# RegExp: Only include log messages where the class name matches the supplied.
# regular expression. All other messages will be ignored.
# Proc: Only include log messages where the supplied Proc returns true
# The Proc must return true or false.
@@ -141,14 +138,19 @@
# warn: ::Syslog::LOG_WARNING,
# info: ::Syslog::LOG_NOTICE,
# debug: ::Syslog::LOG_INFO,
# trace: ::Syslog::LOG_DEBUG
# }
+ #
+ # format: [Symbol]
+ # Format for the Syslog message
+ # :syslog uses the default syslog format
+ # :json uses the CEE JSON Syslog format
+ # Example: "@cee: #{JSON.dump(data)}"
+ # Default: :syslog
def initialize(options = {}, &block)
options = options.dup
- level = options.delete(:level)
- filter = options.delete(:filter)
@application = options.delete(:application) || options.delete(:ident) || 'ruby'
@options = options.delete(:options) || (::Syslog::LOG_PID | ::Syslog::LOG_CONS)
@facility = options.delete(:facility) || ::Syslog::LOG_USER
level_map = options.delete(:level_map)
@url = options.delete(:url) || options.delete(:server) || 'syslog://localhost'
@@ -159,11 +161,10 @@
@server = 'localhost' if @protocol == :syslog
@host = options.delete(:host) || options.delete(:local_hostname) || SemanticLogger.host
@tcp_client_options = options.delete(:tcp_client)
raise "Unknown protocol #{@protocol}!" unless [:syslog, :tcp, :udp].include?(@protocol)
- raise(ArgumentError, "Unknown options: #{options.inspect}") if options.size > 0
@level_map = DEFAULT_LEVEL_MAP.dup
@level_map.update(level_map) if level_map
# The syslog_protocol gem is required when logging over TCP or UDP.
@@ -186,11 +187,11 @@
end
end
reopen
- super(level, filter, &block)
+ super(options, &block)
end
# After forking an active process call #reopen to re-open
# open the handles to resources
def reopen
@@ -233,48 +234,46 @@
@remote_syslog.flush if @remote_syslog && @remote_syslog.respond_to?(:flush)
end
# Custom log formatter for syslog.
# Only difference is the removal of the timestamp string since it is in the syslog packet.
- def default_formatter
- Proc.new do |log|
- # Header with date, time, log level and process info
- entry = "#{log.level_to_s} [#{log.process_info}]"
+ def call(log, logger)
+ # Header with date, time, log level and process info
+ message = "#{log.level_to_s} [#{log.process_info}]"
- # Tags
- entry << ' ' << log.tags.collect { |tag| "[#{tag}]" }.join(' ') if log.tags && (log.tags.size > 0)
+ # Tags
+ message << ' ' << log.tags.collect { |tag| "[#{tag}]" }.join(' ') if log.tags && (log.tags.size > 0)
- # Duration
- entry << " (#{log.duration_human})" if log.duration
+ # Duration
+ message << " (#{log.duration_human})" if log.duration
- # Class / app name
- entry << " #{log.name}"
+ # Class / app name
+ message << " #{log.name}"
- # Log message
- entry << " -- #{log.message}" if log.message
+ # Log message
+ message << " -- #{log.message}" if log.message
- # Payload
- if payload = log.payload_to_s(false)
- entry << ' -- ' << payload
- end
+ # Payload
+ if payload = log.payload_to_s
+ message << ' -- ' << payload
+ end
- # Exceptions
- if log.exception
- entry << " -- Exception: #{log.exception.class}: #{log.exception.message}\n"
- entry << log.backtrace_to_s
- end
- entry
+ # Exceptions
+ if log.exception
+ message << " -- Exception: #{log.exception.class}: #{log.exception.message}\n"
+ message << log.backtrace_to_s
end
+ message
end
# Format the syslog packet so it can be sent over TCP or UDP
def syslog_packet_formatter(log)
packet = SyslogProtocol::Packet.new
packet.hostname = @host
packet.facility = @facility
packet.severity = @level_map[log.level]
packet.tag = @application
- packet.content = default_formatter.call(log, self)
+ packet.content = formatter.call(log, self)
packet.time = log.time
packet.to_s
end
end
end