<commit_before>require 'thread'

module DLogger
  class Logger
    def initialize(name = "_default")
      @name = name
      @mutex = Mutex.new
      @outputs = []
      
      # initialize context
      context
    end
    
    ##
    # Main entry point, log a message with
    # its metadata.
    # 
    # @param [String] msg the message
    # @param [Hash] metadata Additional data
    # 
    def log(msg, metadata = {})
      @mutex.synchronize do
        # clearing a small hash is slightly faster than creating a new
        # one each time.
        merged_metadata.clear
      
        # first load context data
        context.each do |ctx_data|
          case ctx_data
          when Hash
            merged_metadata.merge!(ctx_data)
          
          when Extension
            ctx_data.class.properties.each do |attr_name|
              merged_metadata[attr_name] = ctx_data.send(attr_name)
            end
          
          end
        end
      
        # then add our data
        merged_metadata.merge!(metadata)
        
        # and dispatch the result
        dispatch(msg, merged_metadata)
      end
    end
    
    # Helper methods to mimic the standard ruby logger interface.
    %w(debug info error warn).each do |level|
      define_method(level) do |msg, metadata = {}|
        log(msg, metadata.merge(:severity => level.to_sym))
      end
    end
    
    ##
    # Register a new output, the only requirement is that
    # the object passed reponds to the "dispatch" method.
    # 
    # @param [Object] handler the handler
    # 
    def add_output(handler)
      @outputs << handler
    end
    
    ##
    # Usually called by #with_context method but you can use
    # it directly to push a context on the stack, it may be useful
    # for asynchronous handling or just to push a global context.<commit_msg>let the outputs handle thread safety<commit_after>require 'thread'

module DLogger
  class Logger
    def initialize(name = "_default")
      @name = name
      @outputs = []
      
      # initialize context
      context
    end
    
    ##
    # Main entry point, log a message with
    # its metadata.
    # 
    # @param [String] msg the message
    # @param [Hash] metadata Additional data
    # 
    def log(msg, metadata = {})
      # clearing a small hash is slightly faster than creating a new
      # one each time.
      merged_metadata.clear
    
      # first load context data
      context.each do |ctx_data|
        case ctx_data
        when Hash
          merged_metadata.merge!(ctx_data)
        
        when Extension
          ctx_data.class.properties.each do |attr_name|
            merged_metadata[attr_name] = ctx_data.send(attr_name)
          end
        
        end
      end
    
      # then add our data
      merged_metadata.merge!(metadata)
      
      # and dispatch the result
      dispatch(msg, merged_metadata)
    end
    
    # Helper methods to mimic the standard ruby logger interface.
    %w(debug info error warn).each do |level|
      define_method(level) do |msg, metadata = {}|
        log(msg, metadata.merge(:severity => level.to_sym))
      end
    end
    
    ##
    # Register a new output, the only requirement is that
    # the object passed reponds to the "dispatch" method.
    # 
    # @param [Object] handler the handler
    # 
    def add_output(handler)
      @outputs << handler
    end
    
    ##
    # Usually called by #with_context method but you can use
    # it directly to push a context on the stack, it may be useful
    # for asynchronous handling or just to push a global context.
{'fraction_non_alphanumeric': 0.0702387562465297, 'fraction_numerical': 0.0, 'mean_word_length': 1.9245129870129871, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, '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': '5409572', 'n_tokens_mistral': 992, 'n_tokens_neox': 973, 'n_words': 349}