Module: LogStats::Stats

Defined in:
lib/log_stats/stats.rb

Class Method Summary collapse

Class Method Details

.avg(events, field_name) ⇒ Object



67
68
69
70
# File 'lib/log_stats/stats.rb', line 67

def self.avg(events, field_name)
  sum = events.lazy.map { |event| event[field_name] }.reduce(&:+)
  sum/events.size.to_f
end

.field_stats_numeric(events, field) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/log_stats/stats.rb', line 19

def self.field_stats_numeric(events, field)
  sorted_events = events.sort_by { |event| event[field[:name]] }
  percentile_levels = (5..95).step(5).map { |n| n/100.0 } + [0.99, 0.999]
  percentiles = percentile_levels.reduce({}) do |acc, level|
    acc[level] = percentile(sorted_events, field[:name], level)
    acc
  end
  result = {
    min: sorted_events[0][field[:name]],
    max: sorted_events[-1][field[:name]],
    avg: avg(events, field[:name]),
    median: percentile(sorted_events, field[:name], 0.5),
    percentiles: percentiles
  }
  if field[:events]
    events_options = (field[:events].is_a?(Hash) ? field[:events] : {})
    events_limit = events_options[:limit] || 10
    result[:events] = if events_options[:sort] == "asc"
                        sorted_events[0, events_limit]
                      else
                        events_start_index = [0, sorted_events.size-events_limit].max
                        sorted_events[events_start_index..-1].reverse
                      end
  end
  result
end

.fields(events, event_config) ⇒ Object



3
4
5
6
7
8
9
10
# File 'lib/log_stats/stats.rb', line 3

def self.fields(events, event_config)
  event_config[:fields].reduce({}) do |acc, field|
    if field[:numeric]
      acc[field[:name]] = field_stats_numeric(events, field)
    end
    acc
  end
end

.group_by(events, event_config) ⇒ Object



12
13
14
15
16
17
# File 'lib/log_stats/stats.rb', line 12

def self.group_by(events, event_config)
  event_config[:group_by].reduce({}) do |acc, (name, group_by)|
    acc[name] = group_by_stats(events, group_by, event_config)
    acc
  end
end

.group_by_stats(events, group_by, event_config) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/log_stats/stats.rb', line 46

def self.group_by_stats(events, group_by, event_config)
  total_count = events.size
  events_by_group = events.group_by { |event| group_by[:id].call(event) }.select { |key, _| !key.nil? }
  grouped = events_by_group.reduce({}) do |acc, (key, group_events)|
    group_count = group_events.size
    percent = (group_count.to_f*100/total_count).round(4)
    acc[key] = {
      count: group_count,
      percent: percent,
      fields: fields(group_events, event_config)
    }
    acc
  end
  keys = if sort_by = group_by[:sort_by]
           grouped.keys.sort_by { |key| sort_by.call(grouped[key]) }
         else
           grouped.keys
         end
  keys.map { |key| {key: key, data: grouped[key]} }
end

.percentile(sorted_events, field_name, level) ⇒ Object



72
73
74
75
76
# File 'lib/log_stats/stats.rb', line 72

def self.percentile(sorted_events, field_name, level)
  index = (sorted_events.size*level).round - 1
  event = sorted_events[index]
  event && event[field_name]
end