fluent-plugin-growthforecast 0.3.0 → 1.0.0
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/.travis.yml +4 -4
- data/Rakefile +1 -1
- data/fluent-plugin-growthforecast.gemspec +2 -3
- data/lib/fluent/plugin/out_growthforecast.rb +117 -129
- data/test/plugin/test_out_growthforecast.rb +102 -65
- metadata +3 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf5a24c232fc6602f645d4346ef5998eb06de333
|
4
|
+
data.tar.gz: 44ba1c503ca39fe3caef6824319095eda7174d9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95bf947b9b8bf21ab1f87dfe6ecc5074c24a564b22e07ce0c3201d5a840d9c60a952c8abd73835fbe6df24244b602a5cb3e9c33a8e75a908b50878d782ae0071
|
7
|
+
data.tar.gz: c04777c0fd35009631a57d46618f8a01961e63e9658722bb6517c96e538ce01466b2443b1c83afc4f5ea2df7409772aedf6a9ede9671e58121db972c1355dea6
|
data/.travis.yml
CHANGED
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
4
|
gem.name = "fluent-plugin-growthforecast"
|
5
|
-
gem.version = "0.
|
5
|
+
gem.version = "1.0.0"
|
6
6
|
gem.authors = ["TAGOMORI Satoshi"]
|
7
7
|
gem.email = ["tagomoris@gmail.com"]
|
8
8
|
gem.summary = %q{Fluentd output plugin to post numbers to GrowthForecast (by kazeburo)}
|
@@ -17,7 +17,6 @@ Gem::Specification.new do |gem|
|
|
17
17
|
|
18
18
|
gem.add_development_dependency "rake"
|
19
19
|
gem.add_development_dependency "test-unit", ">= 3.0.0"
|
20
|
-
gem.add_runtime_dependency "fluentd", "
|
21
|
-
gem.add_runtime_dependency "fluent-mixin-config-placeholders", ">= 0.3.0"
|
20
|
+
gem.add_runtime_dependency "fluentd", ">= 0.14.0"
|
22
21
|
gem.add_runtime_dependency "resolve-hostname", ">= 0.0.4"
|
23
22
|
end
|
@@ -1,96 +1,102 @@
|
|
1
|
-
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'cgi/util'
|
4
|
+
require 'resolve/hostname'
|
5
|
+
|
6
|
+
class Fluent::Plugin::GrowthForecastOutput < Fluent::Plugin::Output
|
2
7
|
Fluent::Plugin.register_output('growthforecast', self)
|
3
8
|
|
4
9
|
def initialize
|
5
10
|
super
|
6
|
-
require 'net/http'
|
7
|
-
require 'uri'
|
8
|
-
require 'resolve/hostname'
|
9
11
|
end
|
10
12
|
|
11
13
|
config_param :gfapi_url, :string, # growth.forecast.local/api/
|
12
|
-
:
|
13
|
-
config_param :graph_path, :string, :
|
14
|
-
:
|
14
|
+
desc: 'The URL of a GrowthForecast API endpoint.'
|
15
|
+
config_param :graph_path, :string, default: nil,
|
16
|
+
desc: <<-DESC
|
15
17
|
The graph path for GrowthForecast API endpoint with the order of service, section, graph_name.
|
16
18
|
DESC
|
17
|
-
config_param :service, :string, :
|
18
|
-
:
|
19
|
-
config_param :section, :string, :
|
20
|
-
:
|
21
|
-
config_param :graphs, :string, :
|
22
|
-
:
|
19
|
+
config_param :service, :string, default: nil,
|
20
|
+
desc: 'The service_name of graphs to create.'
|
21
|
+
config_param :section, :string, default: nil,
|
22
|
+
desc: 'The section_name of graphs to create.'
|
23
|
+
config_param :graphs, :string, default: nil,
|
24
|
+
desc: <<-DESC
|
23
25
|
You may use this option to specify graph names correspond to each of name_keys.
|
24
26
|
Separate by , (comma). The number of graph names must be same with the number of name_keys.
|
25
27
|
DESC
|
26
28
|
|
27
|
-
config_param :ssl, :bool, :
|
28
|
-
:
|
29
|
-
config_param :verify_ssl, :bool, :
|
30
|
-
:
|
29
|
+
config_param :ssl, :bool, default: false,
|
30
|
+
desc: 'Use SSL (https) or not.'
|
31
|
+
config_param :verify_ssl, :bool, default: false,
|
32
|
+
desc: 'Do SSL verification or not.'
|
31
33
|
|
32
|
-
config_param :name_keys, :string, :
|
33
|
-
:
|
34
|
+
config_param :name_keys, :string, default: nil,
|
35
|
+
desc: <<-DESC
|
34
36
|
Specify field names of the input record. Separate by , (comma).
|
35
37
|
The values of these fields are posted as numbers, and names of thease fields are used as parts of grame_names.
|
36
38
|
Either of name_keys or name_key_pattern is required.
|
37
39
|
DESC
|
38
|
-
config_param :name_key_pattern, :string, :
|
39
|
-
:
|
40
|
+
config_param :name_key_pattern, :string, default: nil,
|
41
|
+
desc: <<-DESC
|
40
42
|
Specify the field names of the input record by a regular expression.
|
41
43
|
The values of these fields are posted as numbers,
|
42
44
|
and names of thease fields are used as parts of grame_names.
|
43
45
|
Either of name_keys or name_key_pattern is required.
|
44
46
|
DESC
|
45
47
|
|
46
|
-
config_param :mode, :string, :
|
47
|
-
:
|
48
|
+
config_param :mode, :string, default: 'gauge', # or count/modified
|
49
|
+
desc: <<-DESC
|
48
50
|
The graph mode (either of gauge, count, or modified).
|
49
51
|
Just same as mode of GrowthForecast POST parameter.
|
50
52
|
DESC
|
51
53
|
|
52
|
-
config_param :remove_prefix, :string, :
|
53
|
-
:
|
54
|
-
config_param :tag_for, :string, :
|
55
|
-
:
|
54
|
+
config_param :remove_prefix, :string, default: nil,
|
55
|
+
desc: 'The prefix string which will be removed from the tag.'
|
56
|
+
config_param :tag_for, :string, default: 'name_prefix', # or 'ignore' or 'section' or 'service'
|
57
|
+
desc: 'Either of name_prefix, section, service, or ignore.'
|
56
58
|
|
57
|
-
config_param :background_post, :bool, :
|
58
|
-
:
|
59
|
+
config_param :background_post, :bool, default: false,
|
60
|
+
desc: 'Post to GrowthForecast in background thread, without retries for failures'
|
59
61
|
|
60
|
-
config_param :timeout, :integer, :
|
61
|
-
:
|
62
|
-
config_param :retry, :bool, :
|
63
|
-
:
|
62
|
+
config_param :timeout, :integer, default: nil, # default 60secs
|
63
|
+
desc: 'Read/Write timeout seconds'
|
64
|
+
config_param :retry, :bool, default: true,
|
65
|
+
desc: <<-DESC
|
64
66
|
Do retry for HTTP request failures, or not.
|
65
67
|
This feature will be set as false for background_post yes automatically.
|
66
68
|
DESC
|
67
|
-
config_param :keepalive, :bool, :
|
68
|
-
:
|
69
|
-
config_param :enable_float_number, :bool, :
|
70
|
-
:
|
71
|
-
|
72
|
-
config_param :authentication, :string, :
|
73
|
-
:
|
74
|
-
config_param :username, :string, :
|
75
|
-
:
|
76
|
-
config_param :password, :string, :
|
77
|
-
:
|
69
|
+
config_param :keepalive, :bool, default: true,
|
70
|
+
desc: 'Use a keepalive HTTP connection.'
|
71
|
+
config_param :enable_float_number, :bool, default: false,
|
72
|
+
desc: 'Post a floating number rather than an interger number.'
|
73
|
+
|
74
|
+
config_param :authentication, :string, default: nil, # nil or 'none' or 'basic'
|
75
|
+
desc: 'Specify basic if your GrowthForecast protected with basic authentication.'
|
76
|
+
config_param :username, :string, default: '',
|
77
|
+
desc: 'The username for authentication.'
|
78
|
+
config_param :password, :string, default: '', secret: true,
|
79
|
+
desc: 'The password for authentication.'
|
80
|
+
|
81
|
+
config_section :buffer do
|
82
|
+
config_set_default :chunk_keys, ["tag"]
|
83
|
+
config_set_default :flush_mode, :immediate
|
84
|
+
end
|
78
85
|
|
79
86
|
DEFAULT_GRAPH_PATH = {
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
83
|
-
:
|
87
|
+
ignore: '${service}/${section}/${key_name}',
|
88
|
+
service: '${tag}/${section}/${key_name}',
|
89
|
+
section: '${service}/${tag}/${key_name}',
|
90
|
+
name_prefix: '${service}/${section}/${tag}_${key_name}',
|
84
91
|
}
|
85
92
|
|
86
|
-
# Define `log` method for v0.10.42 or earlier
|
87
|
-
unless method_defined?(:log)
|
88
|
-
define_method("log") { $log }
|
89
|
-
end
|
90
|
-
|
91
93
|
def configure(conf)
|
92
94
|
super
|
93
95
|
|
96
|
+
unless @chunk_key_tag
|
97
|
+
raise Fluent::ConfigError, "configure buffer chunk_keys with tag"
|
98
|
+
end
|
99
|
+
|
94
100
|
if @gfapi_url !~ /\/api\/\Z/
|
95
101
|
raise Fluent::ConfigError, "gfapi_url must end with /api/"
|
96
102
|
end
|
@@ -156,46 +162,15 @@ DESC
|
|
156
162
|
else
|
157
163
|
:none
|
158
164
|
end
|
159
|
-
@resolver = Resolve::Hostname.new(:
|
160
|
-
end
|
161
|
-
|
162
|
-
def start
|
163
|
-
super
|
164
|
-
|
165
|
-
@running = true
|
166
|
-
@thread = nil
|
167
|
-
@queue = nil
|
168
|
-
@mutex = nil
|
169
|
-
if @background_post
|
170
|
-
@mutex = Mutex.new
|
171
|
-
@queue = []
|
172
|
-
@thread = Thread.new(&method(:poster))
|
173
|
-
end
|
165
|
+
@resolver = Resolve::Hostname.new(system_resolver: true)
|
174
166
|
end
|
175
167
|
|
176
|
-
def
|
177
|
-
|
178
|
-
@thread.join if @thread
|
179
|
-
super
|
168
|
+
def multi_workers_ready?
|
169
|
+
true
|
180
170
|
end
|
181
171
|
|
182
|
-
def
|
183
|
-
|
184
|
-
if @queue.size < 1
|
185
|
-
sleep(0.2)
|
186
|
-
next
|
187
|
-
end
|
188
|
-
|
189
|
-
events = @mutex.synchronize {
|
190
|
-
es,@queue = @queue,[]
|
191
|
-
es
|
192
|
-
}
|
193
|
-
begin
|
194
|
-
post_events(events) if events.size > 0
|
195
|
-
rescue => e
|
196
|
-
log.warn "HTTP POST in background Error occures to growthforecast server", :error_class => e.class, :error => e.message
|
197
|
-
end
|
198
|
-
end
|
172
|
+
def prefer_buffered_processing
|
173
|
+
@background_post
|
199
174
|
end
|
200
175
|
|
201
176
|
def placeholder_mapping(tag, name)
|
@@ -203,12 +178,17 @@ DESC
|
|
203
178
|
( (tag.start_with?(@removed_prefix_string) and tag.length > @removed_length) or tag == @remove_prefix)
|
204
179
|
tag = tag[@removed_length..-1]
|
205
180
|
end
|
206
|
-
{'${service}' => @service, '${section}' => @section, '${tag}' => tag, '${key_name}' => name}
|
181
|
+
{'${service}' => escape(@service), '${section}' => escape(@section), '${tag}' => escape(tag), '${key_name}' => escape(name)}
|
182
|
+
end
|
183
|
+
|
184
|
+
def escape(param)
|
185
|
+
escaped ||= param
|
186
|
+
escaped = CGI.escape(param) if param
|
207
187
|
end
|
208
188
|
|
209
189
|
def format_url(tag, name)
|
210
190
|
graph_path = @graph_path.gsub(/(\${[_a-z]+})/, placeholder_mapping(tag, name))
|
211
|
-
return @gfapi_url +
|
191
|
+
return @gfapi_url + graph_path
|
212
192
|
end
|
213
193
|
|
214
194
|
def connect_to(tag, name)
|
@@ -253,7 +233,7 @@ DESC
|
|
253
233
|
host,port = connect_to(tag, name)
|
254
234
|
req = post_request(tag, name, value)
|
255
235
|
http = http_connection(host, port)
|
256
|
-
res = http.start {|
|
236
|
+
res = http.start {|client| client.request(req) }
|
257
237
|
rescue IOError, EOFError, SystemCallError
|
258
238
|
# server didn't respond
|
259
239
|
log.warn "net/http POST raises exception: #{$!.class}, '#{$!.message}'"
|
@@ -283,19 +263,13 @@ DESC
|
|
283
263
|
log.warn "failed to post to growthforecast: #{host}:#{port}#{req.path}, post_data: #{req.body} code: #{res && res.code}"
|
284
264
|
end
|
285
265
|
rescue IOError, EOFError, Errno::ECONNRESET, Errno::ETIMEDOUT, SystemCallError
|
286
|
-
log.warn "net/http keepalive POST raises exception:
|
287
|
-
|
288
|
-
http.finish
|
289
|
-
rescue => e
|
290
|
-
# ignore all errors for connection with error
|
291
|
-
end
|
266
|
+
log.warn "net/http keepalive POST raises exception", error: $!
|
267
|
+
http.finish rescue nil # ignore all errors for connection with error
|
292
268
|
http = nil
|
293
269
|
end
|
294
270
|
end
|
295
|
-
|
296
|
-
http.finish
|
297
|
-
rescue => e
|
298
|
-
# ignore
|
271
|
+
if http
|
272
|
+
http.finish rescue nil
|
299
273
|
end
|
300
274
|
end
|
301
275
|
|
@@ -309,38 +283,52 @@ DESC
|
|
309
283
|
end
|
310
284
|
end
|
311
285
|
|
312
|
-
def
|
286
|
+
def gf_events(tag, time, record)
|
313
287
|
events = []
|
314
288
|
if @name_keys
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
end
|
320
|
-
}
|
321
|
-
}
|
322
|
-
else # for name_key_pattern
|
323
|
-
es.each {|time,record|
|
324
|
-
record.keys.each {|key|
|
325
|
-
if @name_key_pattern.match(key) and record[key]
|
326
|
-
events.push({:tag => tag, :name => key, :value => record[key]})
|
327
|
-
end
|
328
|
-
}
|
329
|
-
}
|
330
|
-
end
|
331
|
-
if @thread
|
332
|
-
@mutex.synchronize do
|
333
|
-
@queue += events
|
289
|
+
@name_keys.each_with_index do |name, i|
|
290
|
+
if value = record[name]
|
291
|
+
events.push({tag: tag, name: (@graphs ? @graphs[i] : name), value: value})
|
292
|
+
end
|
334
293
|
end
|
335
|
-
else
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
raise if @retry
|
294
|
+
else # for name_key_pattern
|
295
|
+
record.keys.each do |key|
|
296
|
+
if @name_key_pattern.match(key) and record[key]
|
297
|
+
events.push({tag: tag, name: key, value: record[key]})
|
298
|
+
end
|
341
299
|
end
|
342
300
|
end
|
301
|
+
events
|
302
|
+
end
|
303
|
+
|
304
|
+
def gf_events_from_es(tag, es)
|
305
|
+
events = []
|
306
|
+
es.each do |time, record|
|
307
|
+
events.concat(gf_events(tag, time, record))
|
308
|
+
end
|
309
|
+
events
|
310
|
+
end
|
311
|
+
|
312
|
+
def process(tag, es)
|
313
|
+
events = gf_events_from_es(tag, es)
|
314
|
+
begin
|
315
|
+
post_events(events)
|
316
|
+
rescue => e
|
317
|
+
log.warn "HTTP POST Error occurs to growthforecast server, ignored (use background_post for retries)", error: e
|
318
|
+
end
|
319
|
+
end
|
343
320
|
|
344
|
-
|
321
|
+
def write(chunk)
|
322
|
+
tag = chunk.metadata.tag
|
323
|
+
events = []
|
324
|
+
chunk.each do |time, record|
|
325
|
+
events.concat(gf_events(tag, time, record))
|
326
|
+
end
|
327
|
+
begin
|
328
|
+
post_events(events)
|
329
|
+
rescue => e
|
330
|
+
log.warn "HTTP POST Error occures to growthforecast server", error: e
|
331
|
+
raise if @retry
|
332
|
+
end
|
345
333
|
end
|
346
334
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'fluent/test/driver/output'
|
2
3
|
|
3
4
|
class GrowthForecastOutputTest < Test::Unit::TestCase
|
4
5
|
# setup/teardown and tests of dummy growthforecast server defined at the end of this class...
|
@@ -119,8 +120,8 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
119
120
|
remove_prefix test
|
120
121
|
]
|
121
122
|
|
122
|
-
def create_driver(conf=CONFIG1
|
123
|
-
Fluent::Test::
|
123
|
+
def create_driver(conf=CONFIG1)
|
124
|
+
Fluent::Test::Driver::Output.new(Fluent::Plugin::GrowthForecastOutput).configure(conf)
|
124
125
|
end
|
125
126
|
|
126
127
|
def test_configure_and_format_url
|
@@ -170,9 +171,11 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
170
171
|
# tag_for name_prefix
|
171
172
|
# ]
|
172
173
|
def test_emit_1
|
173
|
-
d = create_driver(CONFIG1
|
174
|
-
d.
|
175
|
-
d.run
|
174
|
+
d = create_driver(CONFIG1)
|
175
|
+
d.end_if{ @posted.size == 3 }
|
176
|
+
d.run(default_tag: 'test.metrics') do
|
177
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
178
|
+
end
|
176
179
|
|
177
180
|
assert_equal 3, @posted.size
|
178
181
|
v1st = @posted[0]
|
@@ -202,9 +205,11 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
202
205
|
# mode count
|
203
206
|
# ]
|
204
207
|
def test_emit_2
|
205
|
-
d = create_driver(CONFIG2
|
206
|
-
d.
|
207
|
-
d.run
|
208
|
+
d = create_driver(CONFIG2)
|
209
|
+
d.end_if{ @posted.size == 3 }
|
210
|
+
d.run(default_tag: 'test.metrics') do
|
211
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
212
|
+
end
|
208
213
|
|
209
214
|
assert_equal 3, @posted.size
|
210
215
|
v1st = @posted[0]
|
@@ -234,10 +239,12 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
234
239
|
# mode modified
|
235
240
|
# ]
|
236
241
|
def test_emit_3
|
237
|
-
d = create_driver(CONFIG3
|
238
|
-
|
239
|
-
d.
|
240
|
-
|
242
|
+
d = create_driver(CONFIG3)
|
243
|
+
d.end_if{ @posted.size == 3 }
|
244
|
+
d.run(default_tag: 'test.metrics') do
|
245
|
+
# recent ruby's Hash saves elements order....
|
246
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
247
|
+
end
|
241
248
|
|
242
249
|
assert_equal 3, @posted.size
|
243
250
|
v1st = @posted[0]
|
@@ -268,9 +275,12 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
268
275
|
def test_emit_4_auth
|
269
276
|
@auth = true # enable authentication of dummy server
|
270
277
|
|
271
|
-
d = create_driver(CONFIG1
|
272
|
-
d.
|
273
|
-
d.run
|
278
|
+
d = create_driver(CONFIG1)
|
279
|
+
d.end_if{ @prohibited == 3 }
|
280
|
+
d.run(default_tag: 'test.metrics') do
|
281
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
282
|
+
# failed in background, and output warn log
|
283
|
+
end
|
274
284
|
|
275
285
|
assert_equal 0, @posted.size
|
276
286
|
assert_equal 3, @prohibited
|
@@ -279,9 +289,12 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
279
289
|
authentication basic
|
280
290
|
username alice
|
281
291
|
password wrong_password
|
282
|
-
]
|
283
|
-
d.
|
284
|
-
d.run
|
292
|
+
])
|
293
|
+
d.end_if{ @prohibited == 6 }
|
294
|
+
d.run(default_tag: 'test.metrics') do
|
295
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
296
|
+
# failed in background, and output warn log
|
297
|
+
end
|
285
298
|
|
286
299
|
assert_equal 0, @posted.size
|
287
300
|
assert_equal 6, @prohibited
|
@@ -290,9 +303,12 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
290
303
|
authentication basic
|
291
304
|
username alice
|
292
305
|
password secret!
|
293
|
-
]
|
294
|
-
d.
|
295
|
-
d.run
|
306
|
+
])
|
307
|
+
d.end_if{ @posted.size == 3 }
|
308
|
+
d.run(default_tag: 'test.metrics') do
|
309
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
310
|
+
# failed in background, and output warn log
|
311
|
+
end
|
296
312
|
|
297
313
|
assert_equal 6, @prohibited
|
298
314
|
assert_equal 3, @posted.size
|
@@ -307,10 +323,12 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
307
323
|
# ]
|
308
324
|
|
309
325
|
def test_emit_5
|
310
|
-
d = create_driver(CONFIG4
|
311
|
-
|
312
|
-
d.
|
313
|
-
|
326
|
+
d = create_driver(CONFIG4)
|
327
|
+
d.end_if{ @posted.size == 3 }
|
328
|
+
d.run(default_tag: 'test.service') do
|
329
|
+
# recent ruby's Hash saves elements order....
|
330
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
331
|
+
end
|
314
332
|
|
315
333
|
assert_equal 3, @posted.size
|
316
334
|
v1st = @posted[0]
|
@@ -339,9 +357,11 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
339
357
|
# tag_for ignore
|
340
358
|
# ]
|
341
359
|
def test_with_space_1
|
342
|
-
d = create_driver(CONFIG_SPACE
|
343
|
-
d.
|
344
|
-
d.run
|
360
|
+
d = create_driver(CONFIG_SPACE)
|
361
|
+
d.end_if{ @posted.size == 1 }
|
362
|
+
d.run(default_tag: 'test.foo') do
|
363
|
+
d.feed({ 'field z' => 3 })
|
364
|
+
end
|
345
365
|
|
346
366
|
assert_equal 1, @posted.size
|
347
367
|
v = @posted[0]
|
@@ -349,9 +369,9 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
349
369
|
assert_equal 3, v[:data][:number]
|
350
370
|
assert_equal 'gauge', v[:data][:mode]
|
351
371
|
assert_nil v[:auth]
|
352
|
-
assert_equal 'service
|
353
|
-
assert_equal 'metrics
|
354
|
-
assert_equal 'field
|
372
|
+
assert_equal 'service+x', v[:service]
|
373
|
+
assert_equal 'metrics+y', v[:section]
|
374
|
+
assert_equal 'field+z', v[:name]
|
355
375
|
end
|
356
376
|
|
357
377
|
# CONFIG_NON_KEEPALIVE = %[
|
@@ -363,9 +383,11 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
363
383
|
# keepalive false
|
364
384
|
# ]
|
365
385
|
def test_non_keepalive
|
366
|
-
d = create_driver(CONFIG_NON_KEEPALIVE
|
367
|
-
d.
|
368
|
-
d.run
|
386
|
+
d = create_driver(CONFIG_NON_KEEPALIVE)
|
387
|
+
d.end_if{ @posted.size == 3 }
|
388
|
+
d.run(default_tag: 'test.metrics') do
|
389
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
390
|
+
end
|
369
391
|
|
370
392
|
assert_equal 3, @posted.size
|
371
393
|
v1st = @posted[0]
|
@@ -397,10 +419,11 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
397
419
|
# timeout 120
|
398
420
|
# ]
|
399
421
|
def test_threading
|
400
|
-
d = create_driver(CONFIG_THREADING_KEEPALIVE
|
401
|
-
d.
|
402
|
-
d.run
|
403
|
-
|
422
|
+
d = create_driver(CONFIG_THREADING_KEEPALIVE)
|
423
|
+
d.end_if{ @posted.size == 3 }
|
424
|
+
d.run(default_tag: 'test.metrics') do
|
425
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
426
|
+
end
|
404
427
|
|
405
428
|
assert_equal 3, @posted.size
|
406
429
|
v1st = @posted[0]
|
@@ -431,10 +454,11 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
431
454
|
# keepalive false
|
432
455
|
# ]
|
433
456
|
def test_threading_non_keepalive
|
434
|
-
d = create_driver(CONFIG_THREADING_NON_KEEPALIVE
|
435
|
-
d.
|
436
|
-
d.run
|
437
|
-
|
457
|
+
d = create_driver(CONFIG_THREADING_NON_KEEPALIVE)
|
458
|
+
d.end_if{ @posted.size == 3 }
|
459
|
+
d.run(default_tag: 'test.metrics') do
|
460
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
461
|
+
end
|
438
462
|
|
439
463
|
assert_equal 3, @posted.size
|
440
464
|
v1st = @posted[0]
|
@@ -465,9 +489,11 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
465
489
|
# tag_for name_prefix
|
466
490
|
# ]
|
467
491
|
def test_graphs
|
468
|
-
d = create_driver(CONFIG_GRAPHS
|
469
|
-
d.
|
470
|
-
d.run
|
492
|
+
d = create_driver(CONFIG_GRAPHS)
|
493
|
+
d.end_if{ @posted.size == 3 }
|
494
|
+
d.run(default_tag: 'test.metrics') do
|
495
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
496
|
+
end
|
471
497
|
|
472
498
|
assert_equal 3, @posted.size
|
473
499
|
v1st = @posted[0]
|
@@ -499,9 +525,11 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
499
525
|
def test_enable_float_number
|
500
526
|
@enable_float_number = true # enable float number of dummy server
|
501
527
|
|
502
|
-
d = create_driver(CONFIG_ENABLE_FLOAT_NUMBER
|
503
|
-
d.
|
504
|
-
d.run
|
528
|
+
d = create_driver(CONFIG_ENABLE_FLOAT_NUMBER)
|
529
|
+
d.end_if{ @posted.size == 3 }
|
530
|
+
d.run(default_tag: 'test.metrics') do
|
531
|
+
d.feed({ 'field1' => 50.5, 'field2' => -20.1, 'field3' => 10, 'otherfield' => 1 })
|
532
|
+
end
|
505
533
|
|
506
534
|
assert_equal 3, @posted.size
|
507
535
|
v1st = @posted[0]
|
@@ -515,7 +543,7 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
515
543
|
assert_equal 'metrics', v1st[:section]
|
516
544
|
assert_equal 'test.metrics_field1', v1st[:name]
|
517
545
|
|
518
|
-
assert_equal -20.1, v2nd[:data][:number]
|
546
|
+
assert_equal (-20.1), v2nd[:data][:number]
|
519
547
|
assert_equal 'test.metrics_field2', v2nd[:name]
|
520
548
|
|
521
549
|
assert_equal 1, v3rd[:data][:number]
|
@@ -523,10 +551,13 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
523
551
|
end
|
524
552
|
|
525
553
|
def test_gfapi_path
|
526
|
-
d = create_driver(CONFIG_GFAPI_PATH
|
527
|
-
|
528
|
-
d.
|
529
|
-
d.run
|
554
|
+
d = create_driver(CONFIG_GFAPI_PATH)
|
555
|
+
|
556
|
+
d.end_if{ @posted.size == 3 }
|
557
|
+
d.run(default_tag: 'test.service') do
|
558
|
+
# recent ruby's Hash saves elements order....
|
559
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
560
|
+
end
|
530
561
|
|
531
562
|
assert_equal 3, @posted.size
|
532
563
|
v1st = @posted[0]
|
@@ -556,10 +587,10 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
556
587
|
@enable_float_number = false
|
557
588
|
@dummy_server_thread = Thread.new do
|
558
589
|
srv = if ENV['VERBOSE']
|
559
|
-
WEBrick::HTTPServer.new({:
|
590
|
+
WEBrick::HTTPServer.new({BindAddress: '127.0.0.1', Port: GF_TEST_LISTEN_PORT})
|
560
591
|
else
|
561
592
|
logger = WEBrick::Log.new('/dev/null', WEBrick::BasicLog::DEBUG)
|
562
|
-
WEBrick::HTTPServer.new({:
|
593
|
+
WEBrick::HTTPServer.new({BindAddress: '127.0.0.1', Port: GF_TEST_LISTEN_PORT, Logger: logger, AccessLog: []})
|
563
594
|
end
|
564
595
|
begin
|
565
596
|
srv.mount_proc('/api') { |req,res| # /api/:service/:section/:name
|
@@ -586,11 +617,11 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
586
617
|
|
587
618
|
number = @enable_float_number ? post_param['number'].to_f : post_param['number'].to_i
|
588
619
|
@posted.push({
|
589
|
-
:
|
590
|
-
:
|
591
|
-
:
|
592
|
-
:
|
593
|
-
:
|
620
|
+
service: service,
|
621
|
+
section: section,
|
622
|
+
name: graph_name,
|
623
|
+
auth: nil,
|
624
|
+
data: { number: number, mode: post_param['mode'] },
|
594
625
|
})
|
595
626
|
|
596
627
|
res.status = 200
|
@@ -608,7 +639,7 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
608
639
|
# to wait completion of dummy server.start()
|
609
640
|
require 'thread'
|
610
641
|
cv = ConditionVariable.new
|
611
|
-
|
642
|
+
_watcher = Thread.new {
|
612
643
|
connected = false
|
613
644
|
while not connected
|
614
645
|
begin
|
@@ -636,9 +667,12 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
636
667
|
host = server.split(':')[0]
|
637
668
|
port = server.split(':')[1].to_i
|
638
669
|
client = Net::HTTP.start(host, port)
|
670
|
+
content_type = {'Content-Type' => 'application/x-www-form-urlencoded'}
|
639
671
|
|
640
672
|
assert_equal '200', client.request_get('/').code
|
641
|
-
assert_equal '200', client.request_post('/api/service/metrics/hoge',
|
673
|
+
assert_equal '200', client.request_post('/api/service/metrics/hoge',
|
674
|
+
'number=1&mode=gauge',
|
675
|
+
initheader = content_type).code
|
642
676
|
|
643
677
|
assert_equal 1, @posted.size
|
644
678
|
|
@@ -649,7 +683,9 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
649
683
|
assert_equal 'metrics', @posted[0][:section]
|
650
684
|
assert_equal 'hoge', @posted[0][:name]
|
651
685
|
|
652
|
-
assert_equal '200', client.request_post(
|
686
|
+
assert_equal '200', client.request_post('/api/service%20x/metrics/hoge',
|
687
|
+
'number=1&mode=gauge',
|
688
|
+
initheader = content_type).code
|
653
689
|
|
654
690
|
assert_equal 2, @posted.size
|
655
691
|
|
@@ -662,7 +698,9 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
662
698
|
|
663
699
|
@auth = true
|
664
700
|
|
665
|
-
assert_equal '403', client.request_post('/api/service/metrics/pos',
|
701
|
+
assert_equal '403', client.request_post('/api/service/metrics/pos',
|
702
|
+
'number=30&mode=gauge',
|
703
|
+
initheader = content_type).code
|
666
704
|
|
667
705
|
req_with_auth = lambda do |number, mode, user, pass|
|
668
706
|
url = URI.parse("http://#{host}:#{port}/api/service/metrics/pos")
|
@@ -688,5 +726,4 @@ class GrowthForecastOutputTest < Test::Unit::TestCase
|
|
688
726
|
@dummy_server_thread.kill
|
689
727
|
@dummy_server_thread.join
|
690
728
|
end
|
691
|
-
|
692
729
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-growthforecast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TAGOMORI Satoshi
|
@@ -40,32 +40,18 @@ dependencies:
|
|
40
40
|
version: 3.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: fluentd
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "<"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.14.0
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "<"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 0.14.0
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: fluent-mixin-config-placeholders
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - ">="
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
47
|
+
version: 0.14.0
|
62
48
|
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - ">="
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
54
|
+
version: 0.14.0
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: resolve-hostname
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|