<commit_before>require 'httparty'
require 'json'
require 'toml'
require 'parallel'

class Pagerduty
  def initialize
    @config = TOML.load_file('config.toml')['pagerduty']
    raise 'Could not load credentials file at config.toml' if @config.nil? || @config.empty?
    @config['auth_token'] = "Token token=#{@config['auth_token']}" unless @config['auth_token'].start_with?('Token token=')
  end

  def pagerduty_url
    "https://#{@config['account_name']}.pagerduty.com"
  end

  def request(endpoint)
    pagination_limit  = 100
    pagination_offset = 0
    result = []
    begin
      # Some endpoints have query strings already.  Detect this, and add onto the query string
      # if it exists, or otherwise create one
      char = endpoint.include?('?') ? '&' : '?'
      endpoint = "#{endpoint}#{char}sort_by=created_on:desc&offset=#{pagination_offset}"
      response = HTTParty.get(
        endpoint,
        :headers => {
          'Content-Type'  => 'application/json',
          'Authorization' => @config['auth_token']
        }
      )
      response = JSON.parse(response.body).values.first
      response_count = response.count
      debug("received #{response_count} responses from pd for #{endpoint}")
      response.each { |r| result << r }
      pagination_offset += pagination_limit
    end while response_count >= pagination_limit
    result
  end

  def incidents(start_date, finish_date = nil)
    finish_clause     = finish_date ? "&until=#{finish_date}" : ''
    time_zone = @config['time_zone']
    endpoint  = "#{pagerduty_url}/api/v1/incidents?since=#{start_date}#{finish_clause}&time_zone=#{time_zone}"
    response  = request(endpoint)
    incidents = response.map do |incident|
      tmp = {
        :id           => incident['id'],
        :created_on   => incident['created_on'],
        :description  => incident['trigger_summary_data']['description'],
        :incident_key => incident['incident_key'],
        :input_type   => incident['service']['name'],
        :category     => 'not set'
      }
      if incident['trigger_summary_data']['description'].nil?
        # some alerts don't have a description (e.g.: website pulse), fall back on subject and service name
        tmp[:description] = "#{incident['service']['name']}: #{incident['trigger_summary_data']['subject']}"
      end
      tmp
    end
    add_ack_resolve(incidents)
  end

  def add_ack_resolve(incidents)
    Parallel.each(incidents, :in_threads => 20) do |incident|
      incident_id      = incident[:id]
      log              = request("#{pagerduty_url}/api/v1/incidents/#{incident_id}/log_entries")
                         .sort_by { |x| x['created_at'] }
      problem          = log.find { |x| x['type'] == 'trigger' }
      problem_time     = Time.parse(problem['created_at'])
      acknowledge_by   = nil
      time_to_ack      = nil
      time_to_resolve  = nil

      if log.any? { |x| x['type'] == 'acknowledge' }
        acknowledge      = log.find { |x| x['type'] == 'acknowledge' }
        acknowledge_by   = acknowledge['agent']['email']
        # If the alert was acknowledged via Flapjack, we have no ack_by
        # (only PagerDuty provides this)- the best we can get is the acknowledgement string
        if acknowledge_by.nil?
          match = acknowledge['channel']['summary'].match(/unscheduled maintenance created for.+, (.+)$/)
          acknowledge_by = match[1] if match
        end
        acknowledge_time = Time.parse(acknowledge['created_at'])
        time_to_ack      = acknowledge_time - problem_time
      end

      if log.any? { |x| x['type'] == 'resolve' }
        resolve         = log.find { |x| x['type'] == 'resolve' }
        resolve_time    = Time.parse(resolve['created_at'])<commit_msg>INF-1135 Fetch incident start time differently<commit_after>require 'httparty'
require 'json'
require 'toml'
require 'parallel'

class Pagerduty
  def initialize
    @config = TOML.load_file('config.toml')['pagerduty']
    raise 'Could not load credentials file at config.toml' if @config.nil? || @config.empty?
    @config['auth_token'] = "Token token=#{@config['auth_token']}" unless @config['auth_token'].start_with?('Token token=')
  end

  def pagerduty_url
    "https://#{@config['account_name']}.pagerduty.com"
  end

  def request(endpoint)
    pagination_limit  = 100
    pagination_offset = 0
    result = []
    begin
      # Some endpoints have query strings already.  Detect this, and add onto the query string
      # if it exists, or otherwise create one
      char = endpoint.include?('?') ? '&' : '?'
      endpoint = "#{endpoint}#{char}sort_by=created_on:desc&offset=#{pagination_offset}"
      response = HTTParty.get(
        endpoint,
        :headers => {
          'Content-Type'  => 'application/json',
          'Authorization' => @config['auth_token']
        }
      )
      response = JSON.parse(response.body).values.first
      response_count = response.count
      debug("received #{response_count} responses from pd for #{endpoint}")
      response.each { |r| result << r }
      pagination_offset += pagination_limit
    end while response_count >= pagination_limit
    result
  end

  def incidents(start_date, finish_date = nil)
    finish_clause     = finish_date ? "&until=#{finish_date}" : ''
    time_zone = @config['time_zone']
    endpoint  = "#{pagerduty_url}/api/v1/incidents?since=#{start_date}#{finish_clause}&time_zone=#{time_zone}"
    response  = request(endpoint)
    incidents = response.map do |incident|
      tmp = {
        :id           => incident['id'],
        :created_on   => incident['created_on'],
        :description  => incident['trigger_summary_data']['description'],
        :incident_key => incident['incident_key'],
        :input_type   => incident['service']['name'],
        :category     => 'not set'
      }
      if incident['trigger_summary_data']['description'].nil?
        # some alerts don't have a description (e.g.: website pulse), fall back on subject and service name
        tmp[:description] = "#{incident['service']['name']}: #{incident['trigger_summary_data']['subject']}"
      end
      tmp
    end
    add_ack_resolve(incidents)
  end

  def add_ack_resolve(incidents)
    Parallel.each(incidents, :in_threads => 20) do |incident|
      incident_id      = incident[:id]
      log              = request("#{pagerduty_url}/api/v1/incidents/#{incident_id}/log_entries")
                         .sort_by { |x| x['created_at'] }
      problem_time    = Time.parse(log.map { |entry| entry['created_at'] }.sort.first)
      acknowledge_by   = nil
      time_to_ack      = nil
      time_to_resolve  = nil

      if log.any? { |x| x['type'] == 'acknowledge' }
        acknowledge      = log.find { |x| x['type'] == 'acknowledge' }
        acknowledge_by   = acknowledge['agent']['email']
        # If the alert was acknowledged via Flapjack, we have no ack_by
        # (only PagerDuty provides this)- the best we can get is the acknowledgement string
        if acknowledge_by.nil?
          match = acknowledge['channel']['summary'].match(/unscheduled maintenance created for.+, (.+)$/)
          acknowledge_by = match[1] if match
        end
        acknowledge_time = Time.parse(acknowledge['created_at'])
        time_to_ack      = acknowledge_time - problem_time
      end

      if log.any? { |x| x['type'] == 'resolve' }
        resolve         = log.find { |x| x['type'] == 'resolve' }
        resolve_time    = Time.parse(resolve['created_at'])
{'fraction_non_alphanumeric': 0.13739641807003475, 'fraction_numerical': 0.0029403902699812884, 'mean_word_length': 2.913702928870293, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 25, 'https://': 2, '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': '5956432', 'n_tokens_mistral': 2268, 'n_tokens_neox': 2233, 'n_words': 502}