fluent-plugin-statsite 0.0.3 → 0.0.4

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: b6059da4a4125aeea69ef03347f56317fa4b5d8a
4
- data.tar.gz: 8794355360c98abd1a354dce70186f30ddc02c46
3
+ metadata.gz: 18bf875092d09bd490fd29b12b3749aeefc44248
4
+ data.tar.gz: 522741407db13e270fbd60fa523020d0428ecb5a
5
5
  SHA512:
6
- metadata.gz: 20e3f8b875b41781b482a8797b7e4134052e3978184145edaff4ebaf5d6fdc06b9be94703911692652a99d7914e68205aedc75b14eef27d7bcce0be76a48cfd7
7
- data.tar.gz: 7edcf9f85c7937bed2485e888c6e5b8105659fb3a822b799bf1c9198ed3c77964daced8d942cb5f155f93e8fc3bc99b7258f98555b5915347c2bfcd3323297d0
6
+ metadata.gz: 0f48dfb35f0409afa99d40aa18bc8599b98bafa13d78fdc2a177aa2404fd8bd173ee92380c08bc1e73015563fec80535768a69ecd9f7fb6ddec6a9aa0b690399
7
+ data.tar.gz: e61528aee4cd10d6ad2821d1cdbe5ecd48d4ef02c97b0f04fa7f3dbf87addeef6528c149ecba9897236f9d7edd5e642001b0080dc464b8e8a1f59b06547959d4
data/.travis.yml CHANGED
@@ -4,12 +4,9 @@ rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
6
  - 2.1
7
- - ruby-head
8
- - rbx-2
9
7
 
10
8
  os:
11
9
  - linux
12
- - osx
13
10
 
14
11
  branches:
15
12
  only:
@@ -19,8 +16,3 @@ gemfile:
19
16
  - Gemfile
20
17
 
21
18
  script: bundle exec rake
22
-
23
- matrix:
24
- allow_failures:
25
- - rvm: ruby-head
26
- - rvm: rbx-2
data/README.md CHANGED
@@ -30,10 +30,10 @@ It is strongly recommended to use '[V1 config format](http://docs.fluentd.org/ar
30
30
  tag statsite
31
31
  metrics [
32
32
  "${status}:1|c",
33
- {"key": "request_time", "value_field": "request_time", "type": "ms"}
33
+ {"key": "request_time", "value": "request_time", "type": "ms"}
34
34
  ]
35
35
  histograms [
36
- {"prefix": "request_time" "min": 0, "max": 1, "width": 0.1}
36
+ {"prefix": "request_time", "min": 0, "max": 1, "width": 0.1}
37
37
  ]
38
38
  statsite_path "statsite"
39
39
  statsite_flush_interval 1s
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "fluent-plugin-statsite"
7
- spec.version = "0.0.3"
7
+ spec.version = "0.0.4"
8
8
  spec.authors = ["OKUNO Akihiro"]
9
9
  spec.email = ["choplin.choplin@gmail.com"]
10
10
  spec.summary = %q{Fluentd statsite plugin}
@@ -1,3 +1,5 @@
1
+ require_relative 'metric_format'
2
+
1
3
  module Fluent
2
4
  module StatsitePlugin
3
5
  class Metric
@@ -6,34 +8,25 @@ module Fluent
6
8
  HASH_FIELD = %w(
7
9
  type
8
10
  key
9
- key_field
10
11
  value
11
- value_field
12
12
  )
13
13
 
14
- FIELD = '\w+|\$\{\w+\}'
15
-
16
- STRING_PATTERN = /^(#{FIELD}):(#{FIELD})\|(#{TYPE.join('|')})$/
17
- STRING_EXAMPLE = "key_field:value_field|type"
14
+ STRING_PATTERN = /^(#{MetricFormat::PATTERN}):(#{MetricFormat::PATTERN})\|(#{TYPE.join('|')})$/
18
15
 
19
- def initialize(key, key_field, value, value_field, type)
16
+ def initialize(key, value, type)
20
17
  @key = key
21
- @key_field = key_field
22
18
  @value = value
23
- @value_field = value_field
24
19
  @type = type
25
20
  end
26
21
 
27
22
  def convert(record)
28
- k = @key.nil? ? record[@key_field] : @key
29
- v = @value.nil? ? record[@value_field] : @value
23
+ k = @key.convert(record)
24
+ v = @value.convert(record)
30
25
  (k.nil? or v.nil?) ? nil : "#{k}:#{v}|#{@type}\n"
31
26
  end
32
27
 
33
28
  def to_s
34
- k = @key.nil? ? "key_field=#{@key_field}" :"key=#{@key}"
35
- v = @value.nil? ? "value_field=#{@value_field}" :"value=#{@value}"
36
- "Metric(#{k}, #{v}, type=#{@type})"
29
+ "Metric(#{@key}, #{@value}, type=#{@type})"
37
30
  end
38
31
 
39
32
  def self.validate(m)
@@ -49,31 +42,23 @@ module Fluent
49
42
  end
50
43
  end
51
44
 
52
- if not m.has_key?('key') ^ m.has_key?('key_field')
53
- raise ConfigError, "metrics element must contain either one of 'key' or 'key_field'"
54
- end
55
-
56
- if not m.has_key?('value') ^ m.has_key?('value_field')
57
- raise ConfigError, "metrics element must contain either one of 'value' or 'value_field'"
58
- end
59
-
60
- if not m.has_key?('type')
61
- raise ConfigError, "metrics element must contain 'type'"
45
+ HASH_FIELD.each do |f|
46
+ if not m.has_key?(f)
47
+ raise ConfigError, "metrics element must contain '#{f}'"
48
+ end
62
49
  end
63
50
 
64
51
  if not TYPE.member?(m['type'])
65
52
  raise ConfigError, "metrics type must be one of the following: #{TYPE.join(' ')}, but specified as #{m['type']}"
66
53
  end
67
54
 
68
- new(m['key'], m['value_field'], m['value'], m['value_field'], m['type'])
55
+ new(MetricFormat.validate(m['key']), MetricFormat.validate(m['value']), m['type'])
69
56
  when String
70
57
  if (STRING_PATTERN =~ m).nil?
71
58
  raise ConfigError, "metrics string must be #{STRING_PATTERN}, but specified as #{m}"
72
59
  end
73
60
 
74
- key, key_field = $1.start_with?('$') ? [nil, $1[2..-2]] : [$1, nil]
75
- value, value_field = $2.start_with?('$') ? [nil, $2[2..-2]] : [$2, nil]
76
- new(key, key_field, value, value_field, $3)
61
+ new(MetricFormat.validate($1), MetricFormat.validate($2), $3)
77
62
  end
78
63
  end
79
64
  end
@@ -0,0 +1,37 @@
1
+ module Fluent
2
+ module StatsitePlugin
3
+ # This represent a key/value format of Metric
4
+ class MetricFormat
5
+ CONSTANT_VALUE = '\w+'
6
+ SUBSTITUTE = '\$\{\w+\}'
7
+ SUBSTITUTE_REGEXP = /\$\{(\w+)\}/
8
+ ELEMENT = "(?:#{CONSTANT_VALUE}|#{SUBSTITUTE})"
9
+ PATTERN = "#{ELEMENT}+"
10
+
11
+ def initialize(str)
12
+ @str = str
13
+ @no_substitute = str.index('$').nil?
14
+ end
15
+
16
+ def convert(record)
17
+ if @no_substitute
18
+ @str
19
+ else
20
+ @str.gsub(SUBSTITUTE_REGEXP) { record.fetch($1) } rescue nil
21
+ end
22
+ end
23
+
24
+ def to_s
25
+ @str
26
+ end
27
+
28
+ def self.validate(str)
29
+ if /^#{PATTERN}$/.match(str).nil?
30
+ raise ConfigError, "invalid format of key/value field, it must be #{PATTERN}, but specified as #{str}"
31
+ end
32
+
33
+ new(str)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -6,8 +6,8 @@ include Fluent::StatsitePlugin
6
6
  class StatsiteFormatterTest < Test::Unit::TestCase
7
7
  def setup
8
8
  metrics = [
9
- Metric.validate('${k}:${v}|g'),
10
- Metric.validate('${k}:v|g')
9
+ Metric.validate('test_${k}:test_${v}|g'),
10
+ Metric.validate('test_${k}:test_v|g')
11
11
  ]
12
12
  @formatter = StatsiteFormatter.new(metrics)
13
13
  end
@@ -17,9 +17,9 @@ class StatsiteFormatterTest < Test::Unit::TestCase
17
17
  assert_equal "", @formatter.call(record)
18
18
 
19
19
  record = {'k' => 'key'}
20
- assert_equal "key:v|g\n", @formatter.call(record)
20
+ assert_equal "test_key:test_v|g\n", @formatter.call(record)
21
21
 
22
22
  record = {'k' => 'key', 'v' => 'value'}
23
- assert_equal "key:value|g\nkey:v|g\n", @formatter.call(record)
23
+ assert_equal "test_key:test_value|g\ntest_key:test_v|g\n", @formatter.call(record)
24
24
  end
25
25
  end
data/test/test_metric.rb CHANGED
@@ -4,13 +4,17 @@ require 'fluent/plugin/statsite/metric'
4
4
  include Fluent::StatsitePlugin
5
5
 
6
6
  class Metric
7
- attr_reader :key, :key_field, :value, :value_field, :type
7
+ attr_reader :key, :value, :type
8
8
  end
9
9
 
10
10
  class MetricTest < Test::Unit::TestCase
11
11
 
12
12
  def valid_config
13
- {'key' => 'k', 'value' => 'v', 'type' => 'kv'}
13
+ {'key' => 'test_${k}', 'value' => 'test_${v}', 'type' => 'kv'}
14
+ end
15
+
16
+ def invalid_kv_format
17
+ 'test_${'
14
18
  end
15
19
 
16
20
  def test_validate_object_type
@@ -25,21 +29,25 @@ class MetricTest < Test::Unit::TestCase
25
29
  end
26
30
 
27
31
  def test_validate_key
28
- config = (valid_config)['key_field'] = 'k'
29
- assert_raises(Fluent::ConfigError) { Metric.validate(config) }
30
-
31
32
  config = (valid_config)
32
33
  config.delete('key')
33
34
  assert_raises(Fluent::ConfigError) { Metric.validate(config) }
34
- end
35
35
 
36
- def test_validate_value
37
- config = (valid_config)['value_field'] = 'k'
36
+ # invalid key format
37
+ config = valid_config
38
+ config['key'] = invalid_kv_format
38
39
  assert_raises(Fluent::ConfigError) { Metric.validate(config) }
40
+ end
39
41
 
42
+ def test_validate_value
40
43
  config = (valid_config)
41
44
  config.delete('value')
42
45
  assert_raises(Fluent::ConfigError) { Metric.validate(config) }
46
+
47
+ # invalid value format
48
+ config = valid_config
49
+ config['key'] = invalid_kv_format
50
+ assert_raises(Fluent::ConfigError) { Metric.validate(config) }
43
51
  end
44
52
 
45
53
  def test_validate_type
@@ -52,41 +60,51 @@ class MetricTest < Test::Unit::TestCase
52
60
  assert_raises(Fluent::ConfigError) { Metric.validate(config) }
53
61
  end
54
62
 
63
+ def test_validate_deprecated
64
+ config = valid_config
65
+ config.delete('value')
66
+ config['value_field'] = 'v'
67
+ assert_raises(Fluent::ConfigError) { Metric.validate(config) }
68
+
69
+ config = valid_config
70
+ config.delete('key')
71
+ config['key_field'] = 'k'
72
+ assert_raises(Fluent::ConfigError) { Metric.validate(config) }
73
+ end
74
+
55
75
  def test_validate_string
56
76
  config = "foo"
57
77
  assert_raises(Fluent::ConfigError) { Metric.validate(config) }
58
78
 
79
+ # invalid type
59
80
  config = "k:v|foo"
60
81
  assert_raises(Fluent::ConfigError) { Metric.validate(config) }
82
+
83
+ # invalid key format
84
+ config = "${k:v|foo"
85
+ assert_raises(Fluent::ConfigError) { Metric.validate(config) }
86
+
87
+ # invalid value format
88
+ config = "k:v_()|foo"
89
+ assert_raises(Fluent::ConfigError) { Metric.validate(config) }
61
90
  end
62
91
 
63
92
  def test_validate_result
64
93
  m = Metric.validate(valid_config)
65
- assert_equal 'k', m.key
66
- assert_nil m.key_field
67
- assert_equal 'v', m.value
68
- assert_nil m.value_field
94
+ assert_equal 'test_${k}', m.key.to_s
95
+ assert_equal 'test_${v}', m.value.to_s
69
96
  assert_equal 'kv', m.type
70
97
  end
71
98
 
72
99
  def test_validate_result_string
73
- m = Metric.validate('k:v|kv')
74
- assert_equal 'k', m.key
75
- assert_nil m.key_field
76
- assert_equal 'v', m.value
77
- assert_nil m.value_field
78
- assert_equal 'kv', m.type
79
-
80
- m = Metric.validate('${k}:${v}|kv')
81
- assert_nil m.key
82
- assert_equal 'k', m.key_field
83
- assert_nil m.value
84
- assert_equal 'v', m.value_field
100
+ m = Metric.validate('test_${k}:test_${v}|kv')
101
+ assert_equal 'test_${k}', m.key.to_s
102
+ assert_equal 'test_${v}', m.value.to_s
85
103
  assert_equal 'kv', m.type
86
104
  end
87
105
 
88
106
  def test_convert
89
- m = Metric.validate('${k}:${v}|kv')
107
+ m = Metric.validate('test_${k}:test_${v}|kv')
90
108
 
91
109
  record = {'k' => 'key'}
92
110
  assert_nil m.convert(record)
@@ -95,6 +113,12 @@ class MetricTest < Test::Unit::TestCase
95
113
  assert_nil m.convert(record)
96
114
 
97
115
  record = {'k' => 'key', 'v' => 'value'}
98
- assert_equal "key:value|kv\n", m.convert(record)
116
+ assert_equal "test_key:test_value|kv\n", m.convert(record)
117
+ end
118
+
119
+ def test_convert_constant
120
+ m = Metric.validate('k:v|kv')
121
+ record = {}
122
+ assert_equal "k:v|kv\n", m.convert(record)
99
123
  end
100
124
  end
@@ -0,0 +1,37 @@
1
+ require 'helper'
2
+ require 'fluent/plugin/statsite/metric_format'
3
+
4
+ include Fluent::StatsitePlugin
5
+
6
+ class MetricFormat
7
+ attr_reader :str, :no_substitute
8
+ end
9
+
10
+ class MetricFormatTest < Test::Unit::TestCase
11
+ def test_validate
12
+ assert_raises(Fluent::ConfigError) { MetricFormat.validate('()') }
13
+ assert_raises(Fluent::ConfigError) { MetricFormat.validate('$') }
14
+ assert_raises(Fluent::ConfigError) { MetricFormat.validate('{}}') }
15
+ end
16
+
17
+ def test_validate_result
18
+ s = 'foo_${bar}_foobar'
19
+ mf = MetricFormat.validate(s)
20
+ assert_equal s, mf.str
21
+ assert (not mf.no_substitute)
22
+
23
+ s = 'foo_bar_foobar'
24
+ mf = MetricFormat.validate(s)
25
+ assert_equal s, mf.str
26
+ assert mf.no_substitute
27
+ end
28
+
29
+ def test_validate_convert
30
+ s = 'foo_${bar}_foobar'
31
+ mf = MetricFormat.validate(s)
32
+
33
+ assert_equal 'foo_hoge_foobar', mf.convert({'bar' => 'hoge'})
34
+
35
+ assert_nil mf.convert({'hoge' => 'fuga'})
36
+ end
37
+ end
@@ -17,7 +17,7 @@ class StatsiteFilterOutputTest < Test::Unit::TestCase
17
17
  type statsite
18
18
  tag statsite
19
19
  metrics [
20
- "${status}:1|c"
20
+ "status_${status}:1|c"
21
21
  ]
22
22
  histograms [
23
23
  {"prefix": "k", "min": 0, "max": 10, "width": 1.0}
@@ -60,6 +60,6 @@ class StatsiteFilterOutputTest < Test::Unit::TestCase
60
60
 
61
61
  count_result = emits.pop
62
62
  assert_equal 'statsite', count_result[0]
63
- assert_equal({type: 'counts', key: '200', value: 4.0}, count_result[2])
63
+ assert_equal({type: 'counts', key: 'status_200', value: 4.0}, count_result[2])
64
64
  end
65
65
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-statsite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - OKUNO Akihiro
@@ -73,10 +73,12 @@ files:
73
73
  - lib/fluent/plugin/statsite/format.rb
74
74
  - lib/fluent/plugin/statsite/histogram.rb
75
75
  - lib/fluent/plugin/statsite/metric.rb
76
+ - lib/fluent/plugin/statsite/metric_format.rb
76
77
  - test/helper.rb
77
78
  - test/test_formatter.rb
78
79
  - test/test_histogram.rb
79
80
  - test/test_metric.rb
81
+ - test/test_metric_format.rb
80
82
  - test/test_out_statsite_filter.rb
81
83
  - test/test_parser.rb
82
84
  homepage: https://github.com/choplin/fluent-plugin-statsite
@@ -108,5 +110,6 @@ test_files:
108
110
  - test/test_formatter.rb
109
111
  - test/test_histogram.rb
110
112
  - test/test_metric.rb
113
+ - test/test_metric_format.rb
111
114
  - test/test_out_statsite_filter.rb
112
115
  - test/test_parser.rb