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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65ef251fcecd3b5a3e25e19999f7a729169ec5dd
4
- data.tar.gz: ec9832faf2b9e613f20c21cd9865a09fe7d98820
3
+ metadata.gz: cf5a24c232fc6602f645d4346ef5998eb06de333
4
+ data.tar.gz: 44ba1c503ca39fe3caef6824319095eda7174d9d
5
5
  SHA512:
6
- metadata.gz: cf66365063373360b71a8443b6f0495efdb626c3ac3b49fc2814fc6033afde42703910fd3716060e9f9251ac7847c7d95a9372312de8679a379db6914e47277a
7
- data.tar.gz: 33f8c44d73ae0af1e5805a130aa0d0efccbd04c2bdd6020b1f81ce1e00c0f0934827905033c7f5caa19cbd00600e69a53bc5711d30dbfd79438604cff2307b52
6
+ metadata.gz: 95bf947b9b8bf21ab1f87dfe6ecc5074c24a564b22e07ce0c3201d5a840d9c60a952c8abd73835fbe6df24244b602a5cb3e9c33a8e75a908b50878d782ae0071
7
+ data.tar.gz: c04777c0fd35009631a57d46618f8a01961e63e9658722bb6517c96e538ce01466b2443b1c83afc4f5ea2df7409772aedf6a9ede9671e58121db972c1355dea6
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.0.0
5
- - 2.1.8
6
- - 2.2.4
7
- - 2.3.0
4
+ - 2.1.10
5
+ - 2.2.6
6
+ - 2.3.3
7
+ - 2.4.0
data/Rakefile CHANGED
@@ -8,4 +8,4 @@ Rake::TestTask.new(:test) do |test|
8
8
  test.verbose = true
9
9
  end
10
10
 
11
- task :default => :test
11
+ task default: :test
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = "fluent-plugin-growthforecast"
5
- gem.version = "0.3.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", "< 0.14.0"
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
- class Fluent::GrowthForecastOutput < Fluent::Output
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
- :desc => 'The URL of a GrowthForecast API endpoint.'
13
- config_param :graph_path, :string, :default => nil,
14
- :desc => <<-DESC
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, :default => nil,
18
- :desc => 'The service_name of graphs to create.'
19
- config_param :section, :string, :default => nil,
20
- :desc => 'The section_name of graphs to create.'
21
- config_param :graphs, :string, :default => nil,
22
- :desc => <<-DESC
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, :default => false,
28
- :desc => 'Use SSL (https) or not.'
29
- config_param :verify_ssl, :bool, :default => false,
30
- :desc => 'Do SSL verification or not.'
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, :default => nil,
33
- :desc => <<-DESC
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, :default => nil,
39
- :desc => <<-DESC
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, :default => 'gauge', # or count/modified
47
- :desc => <<-DESC
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, :default => nil,
53
- :desc => 'The prefix string which will be removed from the tag.'
54
- config_param :tag_for, :string, :default => 'name_prefix', # or 'ignore' or 'section' or 'service'
55
- :desc => 'Either of name_prefix, section, service, or ignore.'
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, :default => false,
58
- :desc => 'Post to GrowthForecast in background thread, without retries for failures'
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, :default => nil, # default 60secs
61
- :desc => 'Read/Write timeout seconds'
62
- config_param :retry, :bool, :default => true,
63
- :desc => <<-DESC
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, :default => true,
68
- :desc => 'Use a keepalive HTTP connection.'
69
- config_param :enable_float_number, :bool, :default => false,
70
- :desc => 'Post a floating number rather than an interger number.'
71
-
72
- config_param :authentication, :string, :default => nil, # nil or 'none' or 'basic'
73
- :desc => 'Specify basic if your GrowthForecast protected with basic authentication.'
74
- config_param :username, :string, :default => '',
75
- :desc => 'The username for authentication.'
76
- config_param :password, :string, :default => '', :secret => true,
77
- :desc => 'The password for authentication.'
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
- :ignore => '${service}/${section}/${key_name}',
81
- :service => '${tag}/${section}/${key_name}',
82
- :section => '${service}/${tag}/${key_name}',
83
- :name_prefix => '${service}/${section}/${tag}_${key_name}',
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(:system_resolver => true)
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 shutdown
177
- @running = false
178
- @thread.join if @thread
179
- super
168
+ def multi_workers_ready?
169
+ true
180
170
  end
181
171
 
182
- def poster
183
- while @running
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 + URI.escape(graph_path)
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 {|http| http.request(req) }
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: #{$!.class}, '#{$!.message}'"
287
- begin
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
- begin
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 emit(tag, es, chain)
286
+ def gf_events(tag, time, record)
313
287
  events = []
314
288
  if @name_keys
315
- es.each {|time,record|
316
- @name_keys.each_with_index {|name, i|
317
- if value = record[name]
318
- events.push({:tag => tag, :name => (@graphs ? @graphs[i] : name), :value => value})
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
- begin
337
- post_events(events)
338
- rescue => e
339
- log.warn "HTTP POST Error occures to growthforecast server", :error_class => e.class, :error => e.message
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
- chain.next
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, tag='test.metrics')
123
- Fluent::Test::OutputTestDriver.new(Fluent::GrowthForecastOutput, tag).configure(conf)
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, 'test.metrics')
174
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
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, 'test.metrics')
206
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
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, 'test.metrics')
238
- # recent ruby's Hash saves elements order....
239
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
240
- d.run
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, 'test.metrics')
272
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
273
- d.run # failed in background, and output warn log
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
- ], 'test.metrics')
283
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
284
- d.run # failed in background, and output warn log
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
- ], 'test.metrics')
294
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
295
- d.run # failed in background, and output warn log
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, 'test.service')
311
- # recent ruby's Hash saves elements order....
312
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
313
- d.run
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, 'test.foo')
343
- d.emit({ 'field z' => 3 })
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 x', v[:service]
353
- assert_equal 'metrics y', v[:section]
354
- assert_equal 'field z', v[:name]
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, 'test.metrics')
367
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
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, 'test.metrics')
401
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
402
- d.run
403
- sleep 0.5 # wait internal posting thread loop
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, 'test.metrics')
435
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
436
- d.run
437
- sleep 0.5 # wait internal posting thread loop
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, 'test.metrics')
469
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
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, 'test.metrics')
503
- d.emit({ 'field1' => 50.5, 'field2' => -20.1, 'field3' => 10, 'otherfield' => 1 })
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, 'test.service')
527
- # recent ruby's Hash saves elements order....
528
- d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
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({:BindAddress => '127.0.0.1', :Port => GF_TEST_LISTEN_PORT})
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({:BindAddress => '127.0.0.1', :Port => GF_TEST_LISTEN_PORT, :Logger => logger, :AccessLog => []})
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
- :service => service,
590
- :section => section,
591
- :name => graph_name,
592
- :auth => nil,
593
- :data => { :number => number, :mode => post_param['mode'] },
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
- watcher = Thread.new {
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', 'number=1&mode=gauge').code
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(URI.escape('/api/service x/metrics/hoge'), 'number=1&mode=gauge').code
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', 'number=30&mode=gauge').code
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.3.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.3.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.3.0
54
+ version: 0.14.0
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: resolve-hostname
71
57
  requirement: !ruby/object:Gem::Requirement