Class: SemanticLogger::Appender::Syslog
- Defined in:
- lib/semantic_logger/appender/syslog.rb
Constant Summary collapse
- DEFAULT_LEVEL_MAP =
Default mapping of ruby log levels to syslog log levels
::Syslog::LOG_EMERG - “System is unusable” ::Syslog::LOG_ALERT - “Action needs to be taken immediately” ::Syslog::LOG_CRIT - “A critical condition has occurred” ::Syslog::LOG_ERR - “An error occurred” ::Syslog::LOG_WARNING - “Warning of a possible problem” ::Syslog::LOG_NOTICE - “A normal but significant condition occurred” ::Syslog::LOG_INFO - “Informational message” ::Syslog::LOG_DEBUG - “Debugging information”
{ fatal: ::Syslog::LOG_CRIT, error: ::Syslog::LOG_ERR, warn: ::Syslog::LOG_WARNING, info: ::Syslog::LOG_NOTICE, debug: ::Syslog::LOG_INFO, trace: ::Syslog::LOG_DEBUG }
Instance Attribute Summary collapse
-
#facility ⇒ Object
readonly
Returns the value of attribute facility.
-
#host ⇒ Object
readonly
Returns the value of attribute host.
-
#local_hostname ⇒ Object
readonly
Returns the value of attribute local_hostname.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
-
#protocol ⇒ Object
readonly
Returns the value of attribute protocol.
-
#remote_syslog ⇒ Object
readonly
Returns the value of attribute remote_syslog.
-
#server ⇒ Object
readonly
Returns the value of attribute server.
Attributes inherited from Base
Attributes inherited from Base
Instance Method Summary collapse
-
#default_formatter ⇒ Object
Custom log formatter for syslog.
-
#flush ⇒ Object
Flush is called by the semantic_logger during shutdown.
-
#initialize(params = {}, &block) ⇒ Syslog
constructor
For more information on the Syslog constants used below see ruby-doc.org/stdlib-2.0.0/libdoc/syslog/rdoc/Syslog.html Parameters.
-
#log(log) ⇒ Object
Write the log using the specified protocol and host.
-
#reopen ⇒ Object
After forking an active process call #reopen to re-open open the handles to resources.
-
#syslog_packet_formatter(log) ⇒ Object
Format the syslog packet so it can be sent over TCP or UDP.
Methods inherited from Base
Methods inherited from Base
#benchmark, default_level, default_level=, #level, #level=, #payload, #pop_tags, #push_tags, #silence, #tagged, #tags, #with_payload
Constructor Details
#initialize(params = {}, &block) ⇒ Syslog
For more information on the Syslog constants used below see ruby-doc.org/stdlib-2.0.0/libdoc/syslog/rdoc/Syslog.html Parameters
:ident [String]
Identity of the program
Default: 'ruby'
:options [Integer]
Default: ::Syslog::LOG_PID | ::Syslog::LOG_CONS
Any of the following (options can be logically OR'd together)
::Syslog::LOG_CONS
::Syslog::LOG_NDELAY
::Syslog::LOG_NOWAIT
::Syslog::LOG_ODELAY
::Syslog::LOG_PERROR
::Syslog::LOG_PID
:facility [Integer]
Default: ::Syslog::LOG_USER
Type of program (can be logically OR'd together)
::Syslog::LOG_AUTH
::Syslog::LOG_AUTHPRIV
::Syslog::LOG_CONSOLE
::Syslog::LOG_CRON
::Syslog::LOG_DAEMON
::Syslog::LOG_FTP
::Syslog::LOG_KERN
::Syslog::LOG_LRP
::Syslog::LOG_MAIL
::Syslog::LOG_NEWS
::Syslog::LOG_NTP
::Syslog::LOG_SECURITY
::Syslog::LOG_SYSLOG
::Syslog::LOG_USER
::Syslog::LOG_UUCP
::Syslog::LOG_LOCAL0
::Syslog::LOG_LOCAL1
::Syslog::LOG_LOCAL2
::Syslog::LOG_LOCAL3
::Syslog::LOG_LOCAL4
::Syslog::LOG_LOCAL5
::Syslog::LOG_LOCAL6
::Syslog::LOG_LOCAL7
:level [Symbol]
Default: SemanticLogger's log level.
The minimum level at which this appender will write logs. Any log messages below this level will be ignored.
:level_map [Hash]
Supply a custom map of SemanticLogger levels to syslog levels.
For example, passing in { warn: ::Syslog::LOG_NOTICE }
would result in a log mapping that matches the default level map,
except for :warn, which ends up with a LOG_NOTICE level instead of a
LOG_WARNING one.
Without overriding any parameters, the level map will be
LEVEL_MAP = {
fatal: ::Syslog::LOG_CRIT,
error: ::Syslog::LOG_ERR,
warn: ::Syslog::LOG_WARNING,
info: ::Syslog::LOG_NOTICE,
debug: ::Syslog::LOG_INFO,
trace: ::Syslog::LOG_DEBUG
}
:local_hostname [String]
Default: Socket.gethostname || `hostname`.strip
Hostname to provide to the remote syslog.
:server [String]
Default: 'syslog://localhost'
For writing logs to a remote syslog server
URI of server: protocol://host:port
Uses port 514 by default for TCP and UDP.
local syslog example: 'syslog://localhost'
TCP example with default port: 'tcp://logger'
TCP example with custom port: 'tcp://logger:8514'
UDP example with default port: 'udp://logger'
UDP example with custom port: 'udp://logger:8514'
When using the :syslog protocol, logs will always be sent to the localhost syslog
:tcp_client [Hash]
Default: {}
Only used with the TCP protocol.
Specify custom parameters to pass into Net::TCPClient.new
For a list of options see the net_tcp_client documentation:
https://www.omniref.com/ruby/gems/net_tcp_client/1.0.0/symbols/Net::TCPClient/initialize
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/semantic_logger/appender/syslog.rb', line 145 def initialize(params = {}, &block) params = params.dup @ident = params.delete(:ident) || 'ruby' @options = params.delete(:options) || (::Syslog::LOG_PID | ::Syslog::LOG_CONS) @facility = params.delete(:facility) || ::Syslog::LOG_USER filter = params.delete(:filter) level = params.delete(:level) level_map = params.delete(:level_map) @level_map = DEFAULT_LEVEL_MAP.dup @level_map.update(level_map) if level_map @server = params.delete(:server) || 'syslog://localhost' uri = URI(@server) @host = uri.host || 'localhost' @protocol = (uri.scheme || :syslog).to_sym raise "Unknown protocol #{@protocol}!" unless [:syslog, :tcp, :udp].include?(@protocol) @host = 'localhost' if @protocol == :syslog @port = URI(@server).port || 514 @local_hostname = params.delete(:local_hostname) || Socket.gethostname || `hostname`.strip @tcp_client_options = params.delete(:tcp_client) # Warn about any unknown configuration options. params.each_pair { |key, val| SemanticLogger::Logger.logger.warn "Ignoring unknown configuration option: #{key.inspect} => #{val.inspect}" } # The syslog_protocol gem is required when logging over TCP or UDP. if [:tcp, :udp].include?(@protocol) begin require 'syslog_protocol' rescue LoadError raise 'Missing gem: syslog_protocol. This gem is required when logging over TCP or UDP. To fix this error: gem install syslog_protocol' end # The net_tcp_client gem is required when logging over TCP. if protocol == :tcp @tcp_client_options ||= {} @tcp_client_options[:server] = "#{@host}:#{@port}" begin require 'net/tcp_client' rescue LoadError raise 'Missing gem: net_tcp_client. This gem is required when logging over TCP. To fix this error: gem install net_tcp_client' end end end reopen super(level, filter, &block) end |
Instance Attribute Details
#facility ⇒ Object (readonly)
Returns the value of attribute facility.
38 39 40 |
# File 'lib/semantic_logger/appender/syslog.rb', line 38 def facility @facility end |
#host ⇒ Object (readonly)
Returns the value of attribute host.
38 39 40 |
# File 'lib/semantic_logger/appender/syslog.rb', line 38 def host @host end |
#local_hostname ⇒ Object (readonly)
Returns the value of attribute local_hostname.
38 39 40 |
# File 'lib/semantic_logger/appender/syslog.rb', line 38 def local_hostname @local_hostname end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
38 39 40 |
# File 'lib/semantic_logger/appender/syslog.rb', line 38 def port @port end |
#protocol ⇒ Object (readonly)
Returns the value of attribute protocol.
38 39 40 |
# File 'lib/semantic_logger/appender/syslog.rb', line 38 def protocol @protocol end |
#remote_syslog ⇒ Object (readonly)
Returns the value of attribute remote_syslog.
38 39 40 |
# File 'lib/semantic_logger/appender/syslog.rb', line 38 def remote_syslog @remote_syslog end |
#server ⇒ Object (readonly)
Returns the value of attribute server.
38 39 40 |
# File 'lib/semantic_logger/appender/syslog.rb', line 38 def server @server end |
Instance Method Details
#default_formatter ⇒ Object
Custom log formatter for syslog
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/semantic_logger/appender/syslog.rb', line 236 def default_formatter Proc.new do |log| = log..collect { |tag| "[#{tag}]" }.join(" ") + " " if log. && (log..size > 0) = log..to_s << ' -- ' << log.payload.inspect if log.payload log.each_exception do |exception, i| if i == 0 << ' -- ' else << "\nCause: " end << "#{exception.class}: #{exception.}\n#{(exception.backtrace || []).join("\n")}" end duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : '' "#{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{}#{duration_str}#{log.name} -- #{}" end end |
#flush ⇒ Object
Flush is called by the semantic_logger during shutdown.
231 232 233 |
# File 'lib/semantic_logger/appender/syslog.rb', line 231 def flush @remote_syslog.flush if @remote_syslog && @remote_syslog.respond_to?(:flush) end |
#log(log) ⇒ Object
Write the log using the specified protocol and host.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/semantic_logger/appender/syslog.rb', line 211 def log(log) # Ensure minimum log level is met, and check filter return false if (level_index > (log.level_index || 0)) || !(log) case @protocol when :syslog # Since the Ruby Syslog API supports sprintf format strings, double up all existing '%' = formatter.call(log).gsub '%', '%%' ::Syslog.log @level_map[log.level], when :tcp @remote_syslog.retry_on_connection_failure { @remote_syslog.write("#{syslog_packet_formatter(log)}\r\n") } when :udp @remote_syslog.send syslog_packet_formatter(log), 0, @host, @port else raise "Unsupported protocol: #{protocol}" end true end |
#reopen ⇒ Object
After forking an active process call #reopen to re-open open the handles to resources
195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/semantic_logger/appender/syslog.rb', line 195 def reopen case @protocol when :syslog ::Syslog.open(@ident, @options, @facility) when :tcp # Use the local logger for @remote_syslog so errors with the remote logger can be recorded locally. @tcp_client_options[:logger] = SemanticLogger::Logger.logger @remote_syslog = Net::TCPClient.new(@tcp_client_options) when :udp @remote_syslog = UDPSocket.new else raise "Unsupported protocol: #{@protocol}" end end |
#syslog_packet_formatter(log) ⇒ Object
Format the syslog packet so it can be sent over TCP or UDP
258 259 260 261 262 263 264 265 266 |
# File 'lib/semantic_logger/appender/syslog.rb', line 258 def syslog_packet_formatter(log) packet = SyslogProtocol::Packet.new packet.hostname = @local_hostname packet.facility = @facility packet.severity = @level_map[log.level] packet.tag = @ident packet.content = default_formatter.call(log) packet.to_s end |