fluent-plugin-calc 0.1.1 → 0.1.2

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.
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