class Dynowatch::Parser

Constants

API_ENDPOINT
API_RESOURCE
CONNECT_TIME

Regular expressions for obtaining request times

DYNO

Regular expression to fetch responding dyno

ENDPOINTS

A list of endpoints to be analyzed as specified by the problem statement

REQUEST_METHOD
SERVICE_TIME
VALID_LOG_LINE

Regular expressions for testing routes

Public Class Methods

get_dyno(log) click to toggle source

Get the responding dyno for the request in the log

# File lib/dynowatch/parser.rb, line 74
def self.get_dyno(log)
  log.match(DYNO)[1]
end
get_route_name(log, valid_resource) click to toggle source

Check if the log file contains a request to a route listed in ENDPOINTS

# File lib/dynowatch/parser.rb, line 44
def self.get_route_name(log, valid_resource)
  # Get the request method
  method = log.match(REQUEST_METHOD).to_a.dig(1)
  # Get API resource
  resource = log.match(API_RESOURCE).to_a.dig(1)
  # Get API endpoint
  endpoint = log.match(API_ENDPOINT).to_a.dig(1) || 'blank'

  # Check if the log should be processed
  # - Ensure a method exists
  # - Ensure the resource in the route matches the ones to be analyzed. For
  # example, the current resource to be analyzed is 'users' so the route
  # must match /api/users
  # - Ensure the endpoint is listed in the ENDPOINTS object
  if method && (resource == valid_resource) && (ENDPOINTS[valid_resource.to_sym].keys().include? endpoint.to_sym)
    ENDPOINTS[resource.to_sym][endpoint.to_sym][method.to_sym]
  else
    false
  end
end
get_time(log) click to toggle source

Obtain the response time for the request in the log

# File lib/dynowatch/parser.rb, line 66
def self.get_time(log)
  connect_time = log.match(CONNECT_TIME)[1].to_i
  service_time = log.match(SERVICE_TIME)[1].to_i

  connect_time + service_time
end
is_valid_log(log) click to toggle source

A valid Heroku log has the form: time hostname heroku: <log-details> Example: 2014-01-09T06:16:53.742892+00:00 heroku: at=info method=GET path=/api/users/100002266342173/count_pending_messages host=services.pocketplaylab.com fwd=“94.66.255.106” dyno=web.8 connect=9ms service=9ms status=304 bytes=0 We're only concerned with the format at the beginning.

# File lib/dynowatch/parser.rb, line 39
def self.is_valid_log(log)
  !!(log =~ VALID_LOG_LINE)
end
new() click to toggle source
# File lib/dynowatch/parser.rb, line 30
def initialize

end
parse_log_file(log_file_path, valid_resource, log_file_info) click to toggle source

Read information from a log file and update the log data

# File lib/dynowatch/parser.rb, line 93
def self.parse_log_file(log_file_path, valid_resource, log_file_info)
  # Resource path
  resc = valid_resource.to_sym

  # Read log file
  File.open(log_file_path, 'r') do |infile|
    while line = infile.gets
      log_info = parse_log_line(line, valid_resource)

      if log_info
        log_url = log_info[:route].to_sym

        # Increment count for the file
        log_file_info[resc][log_url][:count] += 1
        log_file_info[resc][log_url][:times] << log_info[:time]
        log_file_info[resc][log_url][:dynos] << log_info[:dyno]
      end
    end
  end

  log_file_info
end
parse_log_line(log, valid_resource) click to toggle source

Get route, response time and dyno details from a log line

# File lib/dynowatch/parser.rb, line 79
def self.parse_log_line(log, valid_resource)
  if is_valid_log(log)
    route_name = get_route_name(log, valid_resource)
    if route_name
      {
        route: route_name,
        time: get_time(log),
        dyno: get_dyno(log)
      }
    end
  end
end