fluent-plugin-statsite 0.0.3 → 0.0.4

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