<commit_before>require 'logger'

module ZTK

  # Standard Logging Class
  #
  # Allows chaining standard Ruby loggers as well as adding extra spice to your
  # log messages.  This includes uSec timestamping, PIDs and caller tree
  # details.
  #
  # This class accepts the same initialize arguments as the Ruby logger class.
  # You can chain multiple loggers together, for example to get an effect of
  # logging to STDOUT and a file simultaneously without having to modify your
  # existing logging statements.
  #
  # One can override the logging level on the command line with programs that
  # use this library like so:
  #     LOG_LEVEL=DEBUG bin/cucumber-chef ssh
  #
  # = Typical usage:
  #
  #     $logger = ZTK::Logger.new("/dev/null")
  #
  #     $logger.debug { "This is a debug message!" }
  #     $logger.info { "This is a info message!" }
  #     $logger.warn { "This is a warn message!" }
  #     $logger.error { "This is a error message!" }
  #     $logger.fatal { "This is a fatal message!" }
  #
  # = Simple logger chain:
  #
  #     logger = ZTK::Logger.new
  #     logger.loggers << ::Logger.new(STDOUT)
  #     logger.loggers << ::Logger.new('test.log')
  #
  #     logger.debug { "This will be written to STDOUT as well as test.log!" }
  #
  # = Alternate logger chaining:
  #
  #     logger = ZTK::Logger.new(STDOUT)
  #     logger.loggers << ::Logger.new('test.log')
  #
  #     logger.debug { "This will be written to STDOUT as well as test.log!" }
  #
  # @author <NAME> <zachary AT jovelabs DOT com>
  class Logger < ::Logger

    # Log Levels
    SEVERITIES = Severity.constants.inject([]) {|arr,c| arr[Severity.const_get(c)] = c; arr}

    class LogDevice
      attr_reader   :dev
      attr_reader   :filename

      def initialize(chain)
        @chain    = chain
        @dev      = nil
        @filename = nil
      end

      def write(message)
        @chain.loggers.each do |logger|
          logger << message
        end
      end

      def close
        @chain.loggers.each do |logger|
          logger.instance_variable_get(:@logdev).close
        end
      end
    end


    attr_accessor :loggers

    def initialize(*args)
      super(StringIO.new)

      @loggers = Array.new
      if args.count > 0
        @loggers << ::Logger.new(*args)
      end

      @logdev = LogDevice.new(self)

      set_log_level
    end

    # Generates a human-readable string about the logger.
    def inspect
      loggers_inspect = @loggers.collect{|logger| logger.instance_variable_get(:@logdev).instance_variable_get(:@dev).inspect }.join(', ')
      "#<#{self.class} loggers=[#{loggers_inspect}]>"
    end

    # Specialized logging.  Logs messages in the same format, except has the
    # option to shift the caller_at position to exposed the proper calling
    # method.
    #<commit_msg>logger: ensure we namespace the proper StringIO<commit_after>require 'logger'

module ZTK

  # Standard Logging Class
  #
  # Allows chaining standard Ruby loggers as well as adding extra spice to your
  # log messages.  This includes uSec timestamping, PIDs and caller tree
  # details.
  #
  # This class accepts the same initialize arguments as the Ruby logger class.
  # You can chain multiple loggers together, for example to get an effect of
  # logging to STDOUT and a file simultaneously without having to modify your
  # existing logging statements.
  #
  # One can override the logging level on the command line with programs that
  # use this library like so:
  #     LOG_LEVEL=DEBUG bin/cucumber-chef ssh
  #
  # = Typical usage:
  #
  #     $logger = ZTK::Logger.new("/dev/null")
  #
  #     $logger.debug { "This is a debug message!" }
  #     $logger.info { "This is a info message!" }
  #     $logger.warn { "This is a warn message!" }
  #     $logger.error { "This is a error message!" }
  #     $logger.fatal { "This is a fatal message!" }
  #
  # = Simple logger chain:
  #
  #     logger = ZTK::Logger.new
  #     logger.loggers << ::Logger.new(STDOUT)
  #     logger.loggers << ::Logger.new('test.log')
  #
  #     logger.debug { "This will be written to STDOUT as well as test.log!" }
  #
  # = Alternate logger chaining:
  #
  #     logger = ZTK::Logger.new(STDOUT)
  #     logger.loggers << ::Logger.new('test.log')
  #
  #     logger.debug { "This will be written to STDOUT as well as test.log!" }
  #
  # @author <NAME> <<EMAIL> AT jo<EMAIL> DOT <EMAIL>>
  class Logger < ::Logger

    # Log Levels
    SEVERITIES = Severity.constants.inject([]) {|arr,c| arr[Severity.const_get(c)] = c; arr}

    class LogDevice
      attr_reader   :dev
      attr_reader   :filename

      def initialize(chain)
        @chain    = chain
        @dev      = nil
        @filename = nil
      end

      def write(message)
        @chain.loggers.each do |logger|
          logger << message
        end
      end

      def close
        @chain.loggers.each do |logger|
          logger.instance_variable_get(:@logdev).close
        end
      end
    end


    attr_accessor :loggers

    def initialize(*args)
      super(::StringIO.new)

      @loggers = Array.new
      if args.count > 0
        @loggers << ::Logger.new(*args)
      end

      @logdev = LogDevice.new(self)

      set_log_level
    end

    # Generates a human-readable string about the logger.
    def inspect
      loggers_inspect = @loggers.collect{|logger| logger.instance_variable_get(:@logdev).instance_variable_get(:@dev).inspect }.join(', ')
      "#<#{self.class} loggers=[#{loggers_inspect}]>"
    end

    # Specialized logging.  Logs messages in the same format, except has the
    # option to shift the caller_at position to exposed the proper calling
    # method.
    #
{'fraction_non_alphanumeric': 0.1052909122868694, 'fraction_numerical': 0.0003515556336790297, 'mean_word_length': 2.4972341733251384, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1308350', 'n_tokens_mistral': 1809, 'n_tokens_neox': 1757, 'n_words': 548}