<commit_before>module RailsGraylogger
  class Message
    FIELD_KEY_REGEXP = /^[\w\.\-]*$/

    attr_accessor :level, :full_message, :short_message, :extra_fields

    def initialize(opts = {})
      @level = opts[:level] || GELF::Levels::INFO
      @short_message = opts[:short_message] || ""
      @full_message = opts[:full_message] || ""
      @extra_fields = {}
    end

    class << self
      def from_event_payload(payload)
        message = self.new
        message.process_event_payload(payload)
        message
      end
    end

    def process_event_payload(payload)
      self.level = level_from_status(payload[:status])
      self.short_message = "#{payload[:controller]}##{payload[:action]} #{payload[:method]} \"#{payload[:path]}\" from #{payload[:ipaddress]}"
      process_extra_fields(payload)
    end

    def tags=(tags)
      raise ArgumentError.new("Not an array: #{tags.inspect}") unless tags.is_a?(Array)
      self.extra_fields[:_tags] = tags.join(" ")
    end

    def to_hash
      {
        level: level,
        short_message: short_message
      }.tap do |hash|
        hash[:full_message] = short_message + "\n" + full_message unless full_message.blank?
      end.merge(extra_fields)
    end

    def process_extra_fields(payload)
      process_exception_data(payload.delete(:exception))

      payload.each do |key, value|
        @extra_fields["_#{key}"] = formatted_value(value) if valid_key?(key)
      end
    end

    private

    def formatted_value(value)
      if value.is_a?(Numeric)
        value
      else
        value.to_s
      end
    end

    def valid_key?(key)
      key.match(FIELD_KEY_REGEXP)
    end

    def level_from_status(status)
      status < 400 ? GELF::Levels::INFO : GELF::Levels::ERROR
    end

    def process_exception_data(exception)
      return unless exception.is_a?(Array)
      @extra_fields["_exception_class"] = exception.first.to_s
      @extra_fields["_exception_message"] = exception.last.to_s
    end
  end
end<commit_msg>Don't break if status is nil<commit_after>module RailsGraylogger
  class Message
    FIELD_KEY_REGEXP = /^[\w\.\-]*$/

    attr_accessor :level, :full_message, :short_message, :extra_fields

    def initialize(opts = {})
      @level = opts[:level] || GELF::Levels::INFO
      @short_message = opts[:short_message] || ""
      @full_message = opts[:full_message] || ""
      @extra_fields = {}
    end

    class << self
      def from_event_payload(payload)
        message = self.new
        message.process_event_payload(payload)
        message
      end
    end

    def process_event_payload(payload)
      self.level = level_from_status(payload[:status])
      self.short_message = "#{payload[:controller]}##{payload[:action]} #{payload[:method]} \"#{payload[:path]}\" from #{payload[:ipaddress]}"
      process_extra_fields(payload)
    end

    def tags=(tags)
      raise ArgumentError.new("Not an array: #{tags.inspect}") unless tags.is_a?(Array)
      self.extra_fields[:_tags] = tags.join(" ")
    end

    def to_hash
      {
        level: level,
        short_message: short_message
      }.tap do |hash|
        hash[:full_message] = short_message + "\n" + full_message unless full_message.blank?
      end.merge(extra_fields)
    end

    def process_extra_fields(payload)
      process_exception_data(payload.delete(:exception))

      payload.each do |key, value|
        @extra_fields["_#{key}"] = formatted_value(value) if valid_key?(key)
      end
    end

    private

    def formatted_value(value)
      if value.is_a?(Numeric)
        value
      else
        value.to_s
      end
    end

    def valid_key?(key)
      key.match(FIELD_KEY_REGEXP)
    end

    def level_from_status(status)
      if status.is_a?(Numeric) && status < 400
        GELF::Levels::INFO
      else
        GELF::Levels::ERROR
      end
    end

    def process_exception_data(exception)
      return unless exception.is_a?(Array)
      @extra_fields["_exception_class"] = exception.first.to_s
      @extra_fields["_exception_message"] = exception.last.to_s
    end
  end
end
{'fraction_non_alphanumeric': 0.12028417442430181, 'fraction_numerical': 0.0014698677119059284, 'mean_word_length': 2.8591682419659734, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, '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': '1055476', 'n_tokens_mistral': 1319, 'n_tokens_neox': 1280, 'n_words': 246}