lib/semantic_logger/appender.rb in semantic_logger-4.1.1 vs lib/semantic_logger/appender.rb in semantic_logger-4.2.0

- old
+ new

@@ -1,8 +1,10 @@ module SemanticLogger module Appender # @formatter:off + autoload :Async, 'semantic_logger/appender/async' + autoload :AsyncBatch, 'semantic_logger/appender/async_batch' autoload :Bugsnag, 'semantic_logger/appender/bugsnag' autoload :Elasticsearch, 'semantic_logger/appender/elasticsearch' autoload :ElasticsearchHttp, 'semantic_logger/appender/elasticsearch_http' autoload :File, 'semantic_logger/appender/file' autoload :Graylog, 'semantic_logger/appender/graylog' @@ -32,47 +34,61 @@ def self.json_formatter SemanticLogger::Formatters::Json.new end # Returns [SemanticLogger::Subscriber] appender for the supplied options - def self.create(options, &block) + def self.factory(options, &block) + options = options.dup + async = options.delete(:async) + batch = options.delete(:batch) + + # Extract batch and async options + proxy_options = {} + ASYNC_OPTION_KEYS.each { |key| proxy_options[key] = options.delete(key) if options.key?(key) } + + appender = build(options, &block) + + # If appender implements #batch, then it should use the batch proxy by default. + batch = true if batch.nil? && appender.respond_to?(:batch) + + if batch == true + proxy_options[:appender] = appender + Appender::AsyncBatch.new(proxy_options) + elsif async == true + proxy_options[:appender] = appender + Appender::Async.new(proxy_options) + else + appender + end + end + + private + + ASYNC_OPTION_KEYS = [:max_queue_size, :lag_threshold_s, :batch_size, :batch_seconds, :lag_check_interval] + + # Returns [Subscriber] instance from the supplied options. + def self.build(options, &block) if options[:io] || options[:file_name] SemanticLogger::Appender::File.new(options, &block) elsif appender = options.delete(:appender) if appender.is_a?(Symbol) - constantize_symbol(appender).new(options) + SemanticLogger::Utils.constantize_symbol(appender).new(options) elsif appender.is_a?(Subscriber) appender else raise(ArgumentError, "Parameter :appender must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}") end + elsif appender = options.delete(:metric) + if appender.is_a?(Symbol) + SemanticLogger::Utils.constantize_symbol(appender, 'SemanticLogger::Metric').new(options) + elsif appender.is_a?(Subscriber) + appender + else + raise(ArgumentError, "Parameter :metric must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}") + end elsif options[:logger] SemanticLogger::Appender::Wrapper.new(options, &block) end - end - - def self.constantize_symbol(symbol, namespace = 'SemanticLogger::Appender') - klass = "#{namespace}::#{camelize(symbol.to_s)}" - begin - if RUBY_VERSION.to_i >= 2 - Object.const_get(klass) - else - klass.split('::').inject(Object) { |o, name| o.const_get(name) } - end - rescue NameError - raise(ArgumentError, "Could not convert symbol: #{symbol} to a class in: #{namespace}. Looking for: #{klass}") - end - end - - private - - # Borrow from Rails, when not running Rails - def self.camelize(term) - string = term.to_s - string = string.sub(/^[a-z\d]*/) { |match| match.capitalize } - string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" } - string.gsub!('/'.freeze, '::'.freeze) - string end end end