Loggability::

LogDevice class

An abstract base class for logging devices. A device manages the actual writing of messages to whatever destination logs are supposed to be shipped to, along with any buffering, encoding, or serialization that needs to be done.

Log devices are loadable by name via the ::create method if they are declared in a directory named ‘loggability/log_device/` in the gem path.

Concrete log devices are required to implement two methods: write and close.

write

Takes one argument, which is the message that needs to be written.

close

Close any open filehandles or connections established by the device.

Constants

DEVICE_TARGET_REGEX

Regexp used to split up logging devices in config lines

Public Class Methods

create( target, *target_args )

Requires the subclass and instantiates it with the passed-in arguments and then returns an instance of it.

# File lib/loggability/log_device.rb, line 53
def self::create( target, *target_args )
        modname = target.to_s.capitalize

        self.load_device_type( target ) unless self.const_defined?( modname, false )
        subclass = self.const_get( modname, false )

        return subclass.new( *target_args )
rescue NameError => err
        raise LoadError, "failed to load %s LogDevice: %s" % [ target, err.message ]
end
load_device_type( type )

Attempt to load a LogDevice of the given type.

# File lib/loggability/log_device.rb, line 66
def self::load_device_type( type )
        require_path = "loggability/log_device/%s" % [ type.to_s.downcase ]
        require( require_path )
end
parse_device_spec( target_spec )

Parses out the target class name and its arguments from the target_spec then requires the subclass and instantiates it by passing the arguments. The target_spec comes from a config file in the format of:

logging:
  datadog[data_dog_api_key]

In the above example:

  • “datadog” is the log device to send logs to

  • “data_dog_api_key” is the argument that will be passed onto the datadog log device’s constructor

# File lib/loggability/log_device.rb, line 40
def self::parse_device_spec( target_spec )
        targets = target_spec.split( ';' ).compact
        return targets.map do |t|
                target_subclass = t[ DEVICE_TARGET_REGEX, 1 ]&.strip.to_sym
                target_subclass_args = t[ DEVICE_TARGET_REGEX, 2 ]

                self.create( target_subclass, target_subclass_args )
        end
end

Public Instance Methods

close()

Close the device. This needs to be overridden by concrete subclasses; calling this implementation will raise an NotImplementedError.

# File lib/loggability/log_device.rb, line 81
def close
        raise NotImplementedError, "%s is not implemented by %s" % [ __callee__, self.class.name ]
end
write( message )

Write a message to the device. This needs to be overridden by concrete subclasses; calling this implementation will raise an NotImplementedError.

# File lib/loggability/log_device.rb, line 74
def write( message )
        raise NotImplementedError, "%s is not implemented by %s" % [ __callee__, self.class.name ]
end