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