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 +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +8 -0
- data/fluent-plugin-calc.gemspec +2 -2
- data/lib/fluent/plugin/out_calc.rb +33 -15
- data/spec/out_calc_spec.rb +25 -4
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f8d625101f66b98091f034d26d6bdb61332f507
|
4
|
+
data.tar.gz: 5e65dc06ab15e2ff39d19cdc287fd71532a4a6d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9f94407643311294a2d6014dfbbaae0682e787cfa057934025a3f23531a35d9fd2665ca279cd875bc9dca3e18c17f5ba617d5dc2ce43b2cdf45f28cb1679ad3
|
7
|
+
data.tar.gz: e3fd1ab151b4cee10922e6b553a88f931ec0d4ab70a052c4f92d111f7dbcb6cf97e37c5373150d79f91bb5e75aa4a5b78542aaf5dea5853f14d564e9cc668e44
|
data/CHANGELOG.md
CHANGED
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.
|
data/fluent-plugin-calc.gemspec
CHANGED
@@ -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.
|
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
|
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
|
-
|
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
|
-
@
|
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
|
-
@
|
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
|
-
|
175
|
+
flushed_matches, @matches = @matches, initial_matches(@matches)
|
160
176
|
|
161
|
-
|
162
|
-
count = flushed_counts[tag]
|
177
|
+
flushed_matches.keys.each do |tag|
|
163
178
|
matches = flushed_matches[tag]
|
164
|
-
output = generate_output(
|
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(
|
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]
|
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
|
data/spec/out_calc_spec.rb
CHANGED
@@ -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.
|
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-
|
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
|
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
|
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
|