module Logging # The +Layout+ class provides methods for formatting log events into a # string representation. Layouts are used by Appenders to format log # events before writing them to the logging destination. # # All other Layouts inherit from this class which provides stub methods. # Each subclass should provide a +format+ method. A layout can be used by # more than one +Appender+ so all the methods need to be thread safe. # class Layout # call-seq: # Layout.new( :format_as => :string ) # # Creates a new layout that will format objects as strings using the # given :format_as style. This can be one of :string, # :inspect, or :yaml. These formatting commands map to # the following object methods: # # * :string => to_s # * :inspect => inspect # * :yaml => to_yaml # * :json => MultiJson.encode(obj) # # If the format is not specified then the global object format is used # (see Logging#format_as). If the global object format is not specified # then :string is used. # def initialize( opts = {} ) ::Logging.init unless ::Logging.initialized? default = ::Logging.const_defined?('OBJ_FORMAT') ? ::Logging::OBJ_FORMAT : nil f = opts.fetch(:format_as, default) f = f.intern if f.instance_of? String @obj_format = case f when :inspect, :yaml, :json; f else :string end b = opts.fetch(:backtrace, ::Logging.backtrace) @backtrace = case b when :on, 'on', true; true when :off, 'off', false; false else raise ArgumentError, "backtrace must be true or false" end end # call-seq: # format( event ) # # Returns a string representation of the given logging _event_. It is # up to subclasses to implement this method. # def format( event ) nil end # call-seq: # header # # Returns a header string to be used at the beginning of a logging # appender. # def header( ) '' end # call-seq: # footer # # Returns a footer string to be used at the end of a logging appender. # def footer( ) '' end # call-seq: # format_obj( obj ) # # Return a string representation of the given object. Depending upon # the configuration of the logger system the format will be an +inspect+ # based representation or a +yaml+ based representation. # def format_obj( obj ) case obj when String; obj when Exception str = "<#{obj.class.name}> #{obj.message}" if @backtrace && !obj.backtrace.nil? str << "\n\t" << obj.backtrace.join("\n\t") end str when nil; "<#{obj.class.name}> nil" else str = "<#{obj.class.name}> " str << case @obj_format when :inspect; obj.inspect when :yaml; try_yaml(obj) when :json; try_json(obj) else obj.to_s end str end end # Attempt to format the _obj_ using yaml, but fall back to inspect style # formatting if yaml fails. # # obj - The Object to format. # # Returns a String representation of the object. # def try_yaml( obj ) "\n#{obj.to_yaml}" rescue TypeError obj.inspect end # Attempt to format the given object as a JSON string, but fall back to # inspect formatting if JSON encoding fails. # # obj - The Object to format. # # Returns a String representation of the object. # def try_json( obj ) MultiJson.encode(obj) rescue StandardError obj.inspect end end # class Layout end # module Logging