lib/ztk/base.rb in ztk-0.2.4 vs lib/ztk/base.rb in ztk-0.2.5

- old
+ new

@@ -33,30 +33,74 @@ # # You should never interact with this class directly; you should inherit it # and extend functionality as appropriate. class Base + class << self + + # @param [Hash] config Configuration options hash. + # @option config [IO] :stdout Instance of IO to be used for STDOUT. + # @option config [IO] :stderr Instance of IO to be used for STDERR. + # @option config [IO] :stdin Instance of IO to be used for STDIN. + # @option config [Logger] :logger Instance of Logger to be used for logging. + def build_config(configuration={}) + if configuration.is_a?(OpenStruct) + configuration = configuration.send(:table) + end + + rails_logger = Rails.logger if defined?(Rails) + + config = OpenStruct.new({ + :stdout => $stdout, + :stderr => $stderr, + :stdin => $stdin, + :logger => ($logger || rails_logger || ZTK::Logger.new("/dev/null")) + }.merge(configuration)) + + (config.stdout && config.stdout.respond_to?(:sync=)) and config.stdout.sync = true + (config.stderr && config.stderr.respond_to?(:sync=)) and config.stderr.sync = true + (config.stdin && config.stdin.respond_to?(:sync=)) and config.stdin.sync = true + (config.logger && config.logger.respond_to?(:sync=)) and config.logger.sync = true + + config + end + + # Removes all key-value pairs which are not core so values do not bleed + # into classes they are not meant for. + # + # This method will leave :stdout, :stderr, :stdin and :logger key-values + # intact, while removing all other key-value pairs. + def sanitize_config(configuration={}) + if configuration.is_a?(OpenStruct) + configuration = configuration.send(:table) + end + + config = configuration.reject do |key,value| + !(%w(stdout stderr stdin logger).map(&:to_sym).include?(key)) + end + + config + end + + def log_and_raise(logger, exception, message, shift=1) + if logger.is_a?(ZTK::Logger) + logger.shift(:fatal, shift) { "EXCEPTION: #{exception.inspect} - #{message.inspect}" } + else + logger.fatal { "EXCEPTION: #{exception.inspect} - #{message.inspect}" } + end + raise exception, message + end + + end + # @param [Hash] config Configuration options hash. # @option config [IO] :stdout Instance of IO to be used for STDOUT. # @option config [IO] :stderr Instance of IO to be used for STDERR. # @option config [IO] :stdin Instance of IO to be used for STDIN. # @option config [Logger] :logger Instance of Logger to be used for logging. def initialize(config={}) - # defined?(Rails) and rails_logger = Rails.logger - @config = OpenStruct.new({ - :stdout => $stdout, - :stderr => $stderr, - :stdin => $stdin, - :logger => $logger - }.merge(config)) - - @config.stdout.respond_to?(:sync=) and @config.stdout.sync = true - @config.stderr.respond_to?(:sync=) and @config.stderr.sync = true - @config.stdin.respond_to?(:sync=) and @config.stdin.sync = true - @config.logger.respond_to?(:sync=) and @config.logger.sync = true - - log(:debug) { "config(#{@config.inspect})" } + @config = Base.build_config(config) end # Configuration OpenStruct accessor method. # # If no block is given, the method will return the configuration OpenStruct @@ -71,35 +115,37 @@ else @config end end - # Base logging method. + def log_and_raise(exception, message) + Base.log_and_raise(config.logger, exception, message, 2) + end + + # Direct logging method. # + # This method provides direct writing of data to the current log device. + # This is mainly used for pushing STDOUT and STDERR into the log file in + # ZTK::SSH and ZTK::Command, but could easily be used by other classes. + # # The value returned in the block is passed down to the logger specified in # the classes configuration. # # @param [Symbol] method_name This should be any one of [:debug, :info, :warn, :error, :fatal]. # @yield No value is passed to the block. # @yieldreturn [String] The message to log. - def log(method_name, &block) - if block_given? - @config.logger and @config.logger.method(method_name.to_sym).call { yield } - else - raise BaseError, "You must supply a block to the log method!" - end - end - def direct_log(log_level, &blocK) @config.logger.nil? and raise BaseError, "You must supply a logger for direct logging support!" if !block_given? - raise BaseError, "You must supply a block to the log method!" + log_and_raise(BaseError, "You must supply a block to the log method!") elsif (@config.logger.level <= ZTK::Logger.const_get(log_level.to_s.upcase)) if @config.logger.respond_to?(:logdev) @config.logger.logdev.write(yield) + @config.logger.logdev.respond_to?(:flush) and @config.logger.logdev.flush else @config.logger.instance_variable_get(:@logdev).instance_variable_get(:@dev).write(yield) + @config.logger.instance_variable_get(:@logdev).instance_variable_get(:@dev).respond_to?(:flush) and @config.logger.instance_variable_get(:@logdev).instance_variable_get(:@dev).flush end end end end