dwbutler / logstash-logger

Ruby logger that writes logstash events
MIT License
454 stars 118 forks source link

When using ::Logger::Formatter, config.log_tags are not prepended #140

Open arianf opened 6 years ago

arianf commented 6 years ago

When you use the formatter: ::Logger::Formatter the output does not prepend the config.log_tags.

What's interesting is the LogStashLogger::Formatter::* all include "tags":["127.0.0.1"] in the output.

arianf commented 6 years ago

I figured out why this is the case.

When logger is of type LogStashLogger::Formatter it doesn't need to print the log_tags because it is already included in the event hash.

So the current self.build_default_logger(opts) function will create a logger_class with ::Logger so the config.log_tags will not be prepended to every message. But if you think about it, that's the wrong behavior for when setting the format to Logger::Formatter or Logger::SimpleFormatter, because you expect that the tags should show here.

  def self.build_default_logger(opts)
    device = Device.new(opts)
    ::Logger.new(device).tap do |logger|
      logger.instance_variable_set(:@device, device)
      extend_logger(logger)
    end
  end

So the solution could be, to check if the formatter's ancestors include LogStashLogger::Formatter::Base, and if it doesn't we can pass the logger into ActiveSupport::TaggedLogging.new(logger). Like so:

logger = ActiveSupport::TaggedLogging.new(logger) if logger.formatter.class.ancestors.exclude?(LogStashLogger::Formatter::Base)

finally this is what the self.build_logger(opts) method could look like:

def self.build_logger(opts)
  formatter = Formatter.new(opts.delete(:formatter), customize_event: opts.delete(:customize_event))
  logger = case opts[:type]
  when :multi_logger
    build_multi_logger(opts)
  when :syslog
    build_syslog_logger(opts)
  else
    build_default_logger(opts)
  end
  logger.formatter = formatter if formatter

  logger = ActiveSupport::TaggedLogging.new(logger) if logger.formatter.class.ancestors.exclude?(LogStashLogger::Formatter::Base)

  logger
end
dwbutler commented 6 years ago

Hi,

Tagged logging isn't something that exists in Ruby's standard library. It's available in ActiveSupport, and LogStashLogger has a compatible implementation. So naturally Logger::Formatter, which is in the Ruby standard library, doesn't include log tags in the output.

If you are using ActiveSupport, you can try the following:

logger.formatter.extend ActiveSupport::TaggedLogging::Formatter