Custom Appender
To write your own log appender it should meet the following requirements:
- Inherit from
SemanticLogger::Subscriber
- In the initializer connect to the resource being logged to
- Implement #log(log) which needs to write to the relevant resource
- Implement #flush if the resource can be flushed
- Write a test for the new appender
The #log method takes the Log Struct
as a parameter.
For the format of the Log Struct
, see Log Struct
Basic outline for an Appender:
require "semantic_logger"
class SimpleAppender < SemanticLogger::Subscriber
def initialize(level=nil, &block)
# Set the log level and formatter if supplied
super(level, &block)
end
# Display the log struct and the text formatted output
def log(log)
# Ensure minimum log level is met, and check filter
return false if (level_index > (log.level_index || 0)) || !include_message?(log)
# Display the raw log structure
p log
# Display the formatted output
puts formatter.call(log)
end
# Optional
def flush
puts "Flush :)"
end
end
Sample program calling the above appender:
SemanticLogger.default_level = :trace
# Log to file dev.log
SemanticLogger.add_appender(file_name: "dev.log")
# Also log the above sample appender
SemanticLogger.add_appender(appender: SimpleAppender.new)
logger = SemanticLogger["Hello"]
logger.info "Hello World"
Look at the existing appenders for good examples
Tests
To have your custom appender included in the standard list of appenders, submit it along with complete working tests. See the Graylog Appender Test for an example.
Design
This section introduces the internal design of Semantic Logger, which will be helpful for anyone that wants to contribute changes for others in the community to take advantage of.
Log message flow diagram
Shows how log messages events are emitted from the various log instances, placed in the in-memory queue, and then written to one or more appenders on a separate thread.