evidence 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,10 +5,6 @@ module Evidence
5
5
  end
6
6
 
7
7
  def [](output)
8
- single_pattern_parser(output)
9
- end
10
-
11
- def single_pattern_parser(output)
12
8
  lambda do |line|
13
9
  if m = @pattern.match(line)
14
10
  output.call(to_hash(m))
@@ -1,15 +1,19 @@
1
1
  module Evidence
2
- module Pipeline
2
+ module Stream
3
+ include Enumerable
4
+
3
5
  def |(process)
4
- Stream.new(self, process)
6
+ case process
7
+ when SliceStream
8
+ process.slice(self)
9
+ else
10
+ PipeStream.new(self, process)
11
+ end
5
12
  end
6
13
  end
7
14
 
8
- # A stream is an Enumerable with a process processing the data comming
9
- # from input stream and output as another stream
10
- class Stream
11
- include Enumerable
12
- include Pipeline
15
+ class PipeStream
16
+ include Stream
13
17
 
14
18
  def initialize(upstream, process)
15
19
  @upstream, @process = upstream, process
@@ -24,49 +28,34 @@ module Evidence
24
28
  end
25
29
  end
26
30
 
27
- class FileStream
28
- include Enumerable
29
- include Pipeline
31
+ class EnumStream
32
+ include Stream
30
33
 
31
- def initialize(file)
32
- @file = file
34
+ def initialize(enum)
35
+ @enum = enum
33
36
  end
34
37
 
35
38
  def eos?
36
- @file.eof?
37
- end
38
-
39
- def each(&output)
40
- @file.each(&output)
41
- end
42
- end
43
-
44
- class ArrayStream
45
- include Enumerable
46
- include Pipeline
47
-
48
- def initialize(array)
49
- @array = array
50
- end
51
-
52
- def eos?
53
- @array.empty?
39
+ @enum.peek
40
+ false
41
+ rescue StopIteration
42
+ true
54
43
  end
55
44
 
56
45
  def each(&output)
57
- while(item = @array.shift) do
58
- output.call(item)
46
+ loop do
47
+ output[@enum.next]
59
48
  end
49
+ rescue StopIteration
60
50
  end
61
51
 
62
52
  def to_s
63
- "$[#{@array.inspect}]"
53
+ "$[#{@enum.inspect}]"
64
54
  end
65
55
  end
66
56
 
67
57
  class MergedStream
68
- include Enumerable
69
- include Pipeline
58
+ include Stream
70
59
 
71
60
  def initialize(streams, comparator)
72
61
  @comparator = comparator
@@ -103,22 +92,104 @@ module Evidence
103
92
  end
104
93
  end
105
94
 
106
- class Counter
107
- include Enumerable
108
- include Pipeline
95
+ class SlicedStreams
96
+ include Stream
109
97
 
110
- def initialize
111
- @count = 0
98
+ def initialize(stream, index, start_index, end_index)
99
+ @stream, @index, @start_index, @end_index = stream, index, start_index, end_index
100
+ @slice_start_index, @slice_end_index = nil
112
101
  end
113
102
 
114
103
  def eos?
115
- false
104
+ @stream.eos?
116
105
  end
117
106
 
118
107
  def each(&output)
108
+ return if eos?
109
+ @head ||= @stream.first
110
+ @slice_start_index ||= @start_index || @index[@head]
111
+ @slice_end_index ||= @end_index[@slice_start_index]
112
+ @eos_in_slice ||= false
113
+ loop do
114
+ if @slice_start_index > @index[@head]
115
+ return if eos?
116
+ @head = @stream.first
117
+ else
118
+ break
119
+ end
120
+ end
121
+
119
122
  loop do
120
- output.call(@count += 1)
123
+ break if @eos_in_slice
124
+ range = @slice_start_index..@slice_end_index
125
+ slice_enum = Enumerator.new do |y|
126
+ loop do
127
+ break if range.max <= @index[@head]
128
+ if @eos_in_slice = eos?
129
+ y << @head
130
+ break
131
+ end
132
+ head, @head = @head, @stream.first
133
+ y << head
134
+ end
135
+ end
136
+ @slice_start_index, @slice_end_index = range.max, @end_index[range.max]
137
+ output[range, EnumStream.new(slice_enum)]
121
138
  end
122
139
  end
123
140
  end
141
+
142
+ class SliceStream
143
+ def initialize(index, start_index, end_index)
144
+ @index, @start_index, @end_index = index, start_index, end_index
145
+ end
146
+
147
+ def slice(stream)
148
+ SlicedStreams.new(stream, @index, @start_index, @end_index)
149
+ end
150
+ end
151
+
152
+ module_function
153
+ def stream(obj)
154
+ EnumStream.new(obj.to_enum)
155
+ end
156
+
157
+ def merge_streams(streams, comparator)
158
+ loop do
159
+ s1 = streams.shift
160
+ return s1 if streams.empty?
161
+ s2 = streams.shift
162
+ streams << MergedStream.new([s1, s2], comparator)
163
+ end
164
+ end
165
+
166
+ def slice_stream(index, step, start_index=nil)
167
+ end_index = step.is_a?(Proc) ? step : lambda { |index| index + step }
168
+ SliceStream.new(index, start_index, end_index)
169
+ end
170
+
171
+ def stream_each(&block)
172
+ lambda do |output|
173
+ lambda do |i|
174
+ block[i]
175
+ output[i]
176
+ end
177
+ end
178
+ end
179
+
180
+ def stream_map(&block)
181
+ lambda { |output| lambda { |i| output[block[i]] } }
182
+ end
183
+
184
+ def stream_filter(&block)
185
+ lambda { |output| lambda { |i| output[i] if block[i] } }
186
+ end
187
+ alias :stream_select :stream_filter
188
+
189
+ def counter
190
+ count = 0
191
+ counter = Enumerator.new { |y| loop { y << (count += 1) } }
192
+ stream(counter)
193
+ end
194
+
124
195
  end
data/lib/evidence.rb CHANGED
@@ -5,53 +5,9 @@ require 'evidence/rails_action_parser'
5
5
  module Evidence
6
6
  module_function
7
7
 
8
- # convert Array or File object to a stream
9
- def stream(obj)
10
- case obj
11
- when Array
12
- ArrayStream.new(obj)
13
- when File
14
- FileStream.new(obj)
15
- else
16
- raise "Unknown how to convert #{obj.class} to a stream"
17
- end
18
- end
19
-
20
- def merge_streams(streams, comparator)
21
- loop do
22
- s1 = streams.shift
23
- return s1 if streams.empty?
24
- s2 = streams.shift
25
- streams << MergedStream.new([s1, s2], comparator)
26
- end
27
- end
28
-
29
- def slice_stream(index, step, start_index=nil)
30
- end_index = step.is_a?(Proc) ? step : lambda { |index| index + step }
31
- lambda do |output|
32
- @cache ||= []
33
- start_index ||= @cache.first ? index[@cache.first] : nil
34
- lambda do |log|
35
- next_index = index[log]
36
- start_index = index[log] if start_index.nil?
37
- return if start_index > next_index
38
- @cache << log
39
- if end_index[start_index] <= next_index
40
- range = start_index..end_index[start_index]
41
- start_index = range.max
42
- output.call(range, @cache.shift(@cache.size - 1))
43
- end
44
- end
45
- end
46
- end
47
-
48
- def counter
49
- Counter.new
50
- end
51
-
52
8
  # Parse log file stream by given pattern
53
9
  # pattern: ruby regex expression, has named group specified
54
- # output stream: hash object with name and captured string in log
10
+ # unmatched processor: process all unmatched log
55
11
  def log_parser(pattern, unmatched=default_unmatched_process)
56
12
  LogParser.new(pattern, unmatched)
57
13
  end
@@ -66,11 +22,8 @@ module Evidence
66
22
  # Rails action request timestamp parser
67
23
  # log stream | rails_action_parser(pid, message) | request_timestamp_parser
68
24
  def request_timestamp_parser(format="%Y-%m-%d %H:%M:%S")
69
- lambda do |output|
70
- lambda do |action|
71
- action[:request][:timestamp] = Time.strptime(action[:request][:timestamp], format)
72
- output[action]
73
- end
25
+ stream_each do |action|
26
+ action[:request][:timestamp] = Time.strptime(action[:request][:timestamp], format)
74
27
  end
75
28
  end
76
29
 
@@ -79,12 +32,14 @@ module Evidence
79
32
  # log stream | rails_action_parser(pid, message) | request_timestamp_parser | slice_stream(lambda {|action| action[:request][:timestamp]}, 60) | littles_law_analysis
80
33
  def littles_law_analysis
81
34
  lambda do |output|
82
- lambda do |range, logs|
83
- count = logs.size
84
- avg_response_time = logs.reduce(0) {|memo, log| memo + log[:response][:completed_time].to_i} / count
85
-
86
- avg_sec_arrival_rate = count.to_f/(range.max - range.min)
87
- avg_sec_response_time = avg_response_time.to_f/1000
35
+ lambda do |range, actions|
36
+ statistics = actions.inject(sum: 0, count: 0) do |memo, action|
37
+ memo[:count] += 1
38
+ memo[:sum] += action[:response][:completed_time].to_i
39
+ memo
40
+ end
41
+ avg_sec_arrival_rate = statistics[:count].to_f/(range.max - range.min)
42
+ avg_sec_response_time = statistics[:sum].to_f / statistics[:count] /1000
88
43
  output[range, avg_sec_arrival_rate * avg_sec_response_time]
89
44
  end
90
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evidence
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-08-11 00:00:00.000000000 Z
13
+ date: 2013-08-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake