fluent-plugin-growthforecast 0.3.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|