module Evidence

Public Instance Methods

by_time_window(time_window, start=nil) click to toggle source

actions.chunk(&by_time_window(60))

# File lib/evidence.rb, line 45
def by_time_window(time_window, start=nil)
  range = nil
  lambda do |ele|
    start ||= ele[:request][:timestamp]
    range ||= start..(start + time_window)
    while(range.max <= ele[:request][:timestamp]) do
      range = range.max..(range.max + time_window)
    end
    range
  end
end
littles_law_analysis() click to toggle source

Do the little's law analysis on rails actions stream usage example:

rails_action_parser(pid, message).parse(parse_log(logs,

pattern)).each(&request_timestamp_parser).chunk({start: nil}, &time_window(60 seconds)).map do |range, actions|

  littles_law_analysis(range, actions)
end
# File lib/evidence.rb, line 64
def littles_law_analysis
  lambda do |args|
    range, actions = args
    statistics = actions.inject(sum: 0, count: 0) do |memo, action|
      memo[:count] += 1
      memo[:sum] += action[:response][:completed_time].to_i
      memo
    end
    avg_sec_arrival_rate = statistics[:count].to_f/(range.max - range.min)
    avg_sec_response_time = statistics[:sum].to_f / statistics[:count] /1000
    {range: range, value: avg_sec_arrival_rate * avg_sec_response_time}
  end
end
parse_log(pattern) click to toggle source

Parse log file stream by given pattern

pattern: ruby regex expression, has named group specified

example: logs.map(&parse_log(pattern)).compact

# File lib/evidence.rb, line 13
def parse_log(pattern)
  lambda do |log|
    if m = pattern.match(log)
      Hash[m.names.map(&:to_sym).zip(m.captures)].tap do |h|
        h[:origin] = log unless h.has_key?(:origin)
      end
    end
  end
end
rails2_action_parser(pid, message) click to toggle source

Parse out rails actions by given:

pid: a lambda returns process id used to group logs
message: a lambda returns rails log string message

example: logs.map(&rails_action_parser(pid, message)).compact

# File lib/evidence.rb, line 31
def rails2_action_parser(pid, message)
  ActionParser.new(pid, message, rails2_action_patterns)
end
rails2_action_patterns() click to toggle source
# File lib/evidence/rails.rb, line 2
def rails2_action_patterns
  {
    start: /^
        (\#012\#012)?             # ignore encoded newlines
        Processing\s+
        (?<controller>\w+)\#(?<action>\w+)\s+
        (to\s+(?<format>\w+)\s+)?
        \(for\s+
        (?<remote_addr>[^\s]+)\s+
        at\s+
        (?<timestamp>[^\)]+)\)\s+
        \[(?<method>[\w]+)\]
      $/x,
    end: /^
        Completed\sin\s
        (?<completed_time>\d+)ms\s+
        (
          \(
              (View\:\s(?<view_time>\d+))?
              \s*,?\s*
              (DB\:\s(?<db_time>\d+))?
          \)?
        )?\s*\|\s*
        (?<code>\d+)\s+
        (?<status>[ \w-]+)\s+
        (?<url>.+)
      $/x
  }
end
rails_action_parser(pid, message, version=2) click to toggle source

default to rails 2

# File lib/evidence.rb, line 24
def rails_action_parser(pid, message, version=2)
  rails2_action_parser(pid, message)
end
request_timestamp_parser(format="%Y-%m-%d %H:%M:%S") click to toggle source

Rails action request timestamp parser

log.map(&rails_action_parser(pid, message)).compact.map(&request_timestamp_parser)
# File lib/evidence.rb, line 37
def request_timestamp_parser(format="%Y-%m-%d %H:%M:%S")
  lambda do |action|
    action[:request][:timestamp] = Time.strptime(action[:request][:timestamp], format)
    action
  end
end