evidence 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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