fluent-plugin-calc 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 509139d04a8c636beb1a9da08e6ee48df90b3a35
4
- data.tar.gz: 47bb1eb2987b1fe83c9bac58709eaffcd19fc28f
3
+ metadata.gz: 0f8d625101f66b98091f034d26d6bdb61332f507
4
+ data.tar.gz: 5e65dc06ab15e2ff39d19cdc287fd71532a4a6d4
5
5
  SHA512:
6
- metadata.gz: 7d4c04775644c8fe7d383e1b85ed803313d9f7e6ef6df4ba2d1f2b8421f8a79287bac9098d370fb8b8a9e78302ab5ec601b9135e16f09ff6e979064ebc7cc709
7
- data.tar.gz: 40e571e79841859b9ca6d09b128f58ddc15f148974b59f9b448278647620bf1dd8bc439675bf8faddd9daf6824cedd27b573bf45566cb6b84672666d4313e261
6
+ metadata.gz: c9f94407643311294a2d6014dfbbaae0682e787cfa057934025a3f23531a35d9fd2665ca279cd875bc9dca3e18c17f5ba617d5dc2ce43b2cdf45f28cb1679ad3
7
+ data.tar.gz: e3fd1ab151b4cee10922e6b553a88f931ec0d4ab70a052c4f92d111f7dbcb6cf97e37c5373150d79f91bb5e75aa4a5b78542aaf5dea5853f14d564e9cc668e44
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.1.2 (2013/10/10)
2
+
3
+ Enhancement:
4
+
5
+ - Add `zero_emit` option to emit 0 on the next interval like datacounter plugin
6
+
1
7
  ## 0.1.1 (2013/09/02)
2
8
 
3
9
  Fixes
data/README.md CHANGED
@@ -92,6 +92,14 @@ then output bocomes as belows:
92
92
 
93
93
  Store internal data into a file of the given path on shutdown, and load on starting.
94
94
 
95
+ - zero_emit
96
+
97
+ Emit 0 on the next interval. This is useful for some software which requires to reset data such as [GrowthForecast](http://kazeburo.github.io/GrowthForecast/) .
98
+
99
+ calc.foo.bar: {"4xx_count":5,"5xx_count":4","reqtime_max":24831,"reqtime_min":10,"reqtime_avg":270.46}
100
+ # after @interval later
101
+ calc.foo.bar: {"4xx_count":0,"5xx_count":0","reqtime_max":0,"reqtime_min":0,"reqtime_avg":0}
102
+
95
103
  ## ChangeLog
96
104
 
97
105
  See [CHANGELOG.md](CHANGELOG.md) for details.
@@ -3,11 +3,11 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "fluent-plugin-calc"
6
- s.version = "0.1.1"
6
+ s.version = "0.1.2"
7
7
  s.authors = ["Naotoshi SEO"]
8
8
  s.email = ["sonots@gmail.com"]
9
9
  s.homepage = "https://github.com/sonots/fluent-plugin-calc"
10
- s.summary = "fluentd plugin to calc messages"
10
+ s.summary = "fluentd plugin to calcucate numbers in messages"
11
11
  s.description = s.summary
12
12
 
13
13
  s.rubyforge_project = "fluent-plugin-calc"
@@ -24,8 +24,8 @@ class Fluent::CalcOutput < Fluent::Output
24
24
  config_param :add_tag_prefix, :string, :default => 'calc'
25
25
  config_param :aggregate, :string, :default => 'tag'
26
26
  config_param :store_file, :string, :default => nil
27
+ config_param :zero_emit, :bool, :default => false
27
28
 
28
- attr_accessor :counts
29
29
  attr_accessor :matches
30
30
  attr_accessor :saved_duration
31
31
  attr_accessor :saved_at
@@ -53,11 +53,28 @@ class Fluent::CalcOutput < Fluent::Output
53
53
  raise Fluent::ConfigError, "tag must be specified for aggregate all" if @tag.nil?
54
54
  end
55
55
 
56
- @counts = {}
57
56
  @matches = {}
58
57
  @mutex = Mutex.new
59
58
  end
60
59
 
60
+ def initial_matches(prev_matches = nil)
61
+ if @zero_emit && prev_matches
62
+ matches = {}
63
+ prev_matches.keys.each do |tag|
64
+ next unless prev_matches[tag][:count] > 0 # Prohibit to emit anymore
65
+ matches[tag] = { :count => 0, :sum => {}, :max => {}, :min => {}, :avg => {} }
66
+ # ToDo: would want default configuration for :max, :min
67
+ prev_matches[tag][:sum].keys.each {|key| matches[tag][:sum][key] = 0 }
68
+ prev_matches[tag][:max].keys.each {|key| matches[tag][:max][key] = 0 }
69
+ prev_matches[tag][:min].keys.each {|key| matches[tag][:min][key] = 0 }
70
+ prev_matches[tag][:avg].keys.each {|key| matches[tag][:avg][key] = 0 }
71
+ end
72
+ matches
73
+ else
74
+ {}
75
+ end
76
+ end
77
+
61
78
  def start
62
79
  super
63
80
  load_status(@store_file, @interval) if @store_file
@@ -75,7 +92,7 @@ class Fluent::CalcOutput < Fluent::Output
75
92
  def emit(tag, es, chain)
76
93
  tag = 'all' if @aggregate == 'all'
77
94
  # calc
78
- count = 0; matches = { :sum => {}, :max => {}, :min => {}, :avg => {} }
95
+ matches = { :count => 0, :sum => {}, :max => {}, :min => {}, :avg => {} }
79
96
  es.each do |time, record|
80
97
  @sum_keys.each do |key|
81
98
  next unless record[key] and value = record[key].to_f
@@ -108,12 +125,11 @@ class Fluent::CalcOutput < Fluent::Output
108
125
  matches[:avg][key] = sum(matches[:avg][key], value) # sum yet
109
126
  end
110
127
  end if @sum || @max || @min || @avg
111
- count += 1
128
+ matches[:count] += 1
112
129
  end
113
130
 
114
131
  # thread safe merge
115
- @counts[tag] ||= 0
116
- @matches[tag] ||= { :sum => {}, :max => {}, :min => {}, :avg => {} }
132
+ @matches[tag] ||= { :count => 0, :sum => {}, :max => {}, :min => {}, :avg => {} }
117
133
  @mutex.synchronize do
118
134
  matches[:sum].keys.each do |key|
119
135
  @matches[tag][:sum][key] = sum(@matches[tag][:sum][key], matches[:sum][key])
@@ -127,7 +143,7 @@ class Fluent::CalcOutput < Fluent::Output
127
143
  matches[:avg].keys.each do |key|
128
144
  @matches[tag][:avg][key] = sum(@matches[tag][:avg][key], matches[:avg][key]) # sum yet
129
145
  end
130
- @counts[tag] += count
146
+ @matches[tag][:count] += matches[:count]
131
147
  end
132
148
 
133
149
  chain.next
@@ -156,18 +172,17 @@ class Fluent::CalcOutput < Fluent::Output
156
172
  # This method is the real one to emit
157
173
  def flush_emit(step)
158
174
  time = Fluent::Engine.now
159
- flushed_counts, flushed_matches, @counts, @matches = @counts, @matches, {}, {}
175
+ flushed_matches, @matches = @matches, initial_matches(@matches)
160
176
 
161
- flushed_counts.keys.each do |tag|
162
- count = flushed_counts[tag]
177
+ flushed_matches.keys.each do |tag|
163
178
  matches = flushed_matches[tag]
164
- output = generate_output(count, matches)
179
+ output = generate_output(matches)
165
180
  tag = @tag ? @tag : "#{@add_tag_prefix}.#{tag}"
166
181
  Fluent::Engine.emit(tag, time, output) if output
167
182
  end
168
183
  end
169
184
 
170
- def generate_output(count, matches)
185
+ def generate_output(matches)
171
186
  return nil if matches.empty?
172
187
  output = {}
173
188
  matches[:sum].keys.each do |key|
@@ -180,7 +195,8 @@ class Fluent::CalcOutput < Fluent::Output
180
195
  output[key + @min_suffix] = matches[:min][key]
181
196
  end
182
197
  matches[:avg].keys.each do |key|
183
- output[key + @avg_suffix] = matches[:avg][key] / count.to_f # compute avg here
198
+ output[key + @avg_suffix] = matches[:avg][key]
199
+ output[key + @avg_suffix] /= matches[:count].to_f if matches[:count] > 0
184
200
  end
185
201
  output
186
202
  end
@@ -208,7 +224,6 @@ class Fluent::CalcOutput < Fluent::Output
208
224
  @saved_at = Fluent::Engine.now
209
225
  @saved_duration = @saved_at - @last_checked
210
226
  Marshal.dump({
211
- :counts => @counts,
212
227
  :matches => @matches,
213
228
  :saved_at => @saved_at,
214
229
  :saved_duration => @saved_duration,
@@ -246,10 +261,13 @@ class Fluent::CalcOutput < Fluent::Output
246
261
  end
247
262
 
248
263
  if Fluent::Engine.now <= stored[:saved_at] + interval
249
- @counts = stored[:counts]
250
264
  @matches = stored[:matches]
251
265
  @saved_at = stored[:saved_at]
252
266
  @saved_duration = stored[:saved_duration]
267
+ # for lower compatibility
268
+ if counts = stored[:counts]
269
+ @matches.keys.each {|tag| @matches[tag][:count] = counts[tag] }
270
+ end
253
271
 
254
272
  # skip the saved duration to continue counting
255
273
  @last_checked = Fluent::Engine.now - @saved_duration
@@ -77,6 +77,9 @@ describe Fluent::CalcOutput do
77
77
  driver.run { messages.each {|message| driver.emit(message, time) } }
78
78
  driver.instance.flush_emit(0)
79
79
  end
80
+ let(:empty_emit) do
81
+ driver.instance.flush_emit(0)
82
+ end
80
83
 
81
84
  context 'sum/max/min/avg' do
82
85
  let(:config) do
@@ -96,6 +99,28 @@ describe Fluent::CalcOutput do
96
99
  it { emit }
97
100
  end
98
101
 
102
+ context 'zero_emit' do
103
+ let(:config) do
104
+ CONFIG + %[
105
+ sum _count$
106
+ max _max$
107
+ min _min$
108
+ avg _avg$
109
+ zero_emit true
110
+ ]
111
+ end
112
+ before do
113
+ Fluent::Engine.stub(:now).and_return(time)
114
+ Fluent::Engine.should_receive(:emit).with("calc.#{tag}", time, {
115
+ "4xx_count"=>6,"5xx_count"=>6,"reqtime_max"=>6,"reqtime_min"=>1,"reqtime_avg"=>3.0
116
+ })
117
+ Fluent::Engine.should_receive(:emit).with("calc.#{tag}", time, {
118
+ "4xx_count"=>0,"5xx_count"=>0,"reqtime_max"=>0,"reqtime_min"=>0,"reqtime_avg"=>0.0
119
+ })
120
+ end
121
+ it { emit; empty_emit }
122
+ end
123
+
99
124
  context 'sum/max/min/avg_keys' do
100
125
  let(:config) do
101
126
  CONFIG + %[
@@ -244,22 +269,18 @@ describe Fluent::CalcOutput do
244
269
  it 'stored_data and loaded_data should equal' do
245
270
  driver.run { messages.each {|message| driver.emit(message, time) } }
246
271
  driver.instance.shutdown
247
- stored_counts = driver.instance.counts
248
272
  stored_matches = driver.instance.matches
249
273
  stored_saved_at = driver.instance.saved_at
250
274
  stored_saved_duration = driver.instance.saved_duration
251
- driver.instance.counts = {}
252
275
  driver.instance.matches = {}
253
276
  driver.instance.saved_at = nil
254
277
  driver.instance.saved_duration = nil
255
278
 
256
279
  driver.instance.start
257
- loaded_counts = driver.instance.counts
258
280
  loaded_matches = driver.instance.matches
259
281
  loaded_saved_at = driver.instance.saved_at
260
282
  loaded_saved_duration = driver.instance.saved_duration
261
283
 
262
- loaded_counts.should == stored_counts
263
284
  loaded_matches.should == stored_matches
264
285
  loaded_saved_at.should == stored_saved_at
265
286
  loaded_saved_duration.should == stored_saved_duration
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-calc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Naotoshi SEO
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-03 00:00:00.000000000 Z
11
+ date: 2013-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -80,7 +80,7 @@ dependencies:
80
80
  - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- description: fluentd plugin to calc messages
83
+ description: fluentd plugin to calcucate numbers in messages
84
84
  email:
85
85
  - sonots@gmail.com
86
86
  executables: []
@@ -123,7 +123,7 @@ rubyforge_project: fluent-plugin-calc
123
123
  rubygems_version: 2.0.2
124
124
  signing_key:
125
125
  specification_version: 4
126
- summary: fluentd plugin to calc messages
126
+ summary: fluentd plugin to calcucate numbers in messages
127
127
  test_files:
128
128
  - spec/out_calc_spec.rb
129
129
  - spec/spec_helper.rb