Module: Evidence

Defined in:
lib/evidence.rb,
lib/evidence/lazy.rb,
lib/evidence/rails.rb,
lib/evidence/action_parser.rb,
lib/evidence/rails_action_parser.rb

Defined Under Namespace

Modules: Lazy Classes: ActionParser

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.by_time_window(time_window, start = nil) ⇒ Object

actions.chunk(&time_window(60))



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/evidence.rb', line 43

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_analysisObject

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(nil, &time_window(60 seconds)).map do |range, actions|

  littles_law_analysis(range, actions)
end


62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/evidence.rb', line 62

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) ⇒ Object

Parse log file stream by given pattern

pattern: ruby regex expression, has named group specified

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



13
14
15
16
17
18
19
# 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)]
    end
  end
end

.rails2_action_parser(pid, message) ⇒ Object

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



29
30
31
# File 'lib/evidence.rb', line 29

def rails2_action_parser(pid, message)
  ActionParser.new(pid, message, rails2_action_patterns)
end

.rails_action_parser(pid, message, version = 2) ⇒ Object

default to rails 2



22
23
24
# File 'lib/evidence.rb', line 22

def rails_action_parser(pid, message, version=2)
  rails2_action_parser(pid, message)
end

.request_timestamp_parser(format = "%Y-%m-%d %H:%M:%S") ⇒ Object

Rails action request timestamp parser

log.map(&rails_action_parser(pid, message)).compact.map(&request_timestamp_parser)


35
36
37
38
39
40
# File 'lib/evidence.rb', line 35

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

Instance Method Details

#rails2_action_patternsObject



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/evidence/rails.rb', line 2

def rails2_action_patterns
  {
    start: /^
        (\#012\#012)?             # ignore encoded newlines
        Processing\s+
        (?<controller>\w+)\#(?<action>\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*
        (\s*DB\:\s(?<db_time>\d+))?
        \)?\s+\|\s+
        (?<code>\d+)\s+
        (?<status>\w+)\s+
        \[(?<url>.+)\]
      $/x
  }
end