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 +4 -4
- data/.travis.yml +0 -8
- data/README.md +2 -2
- data/fluent-plugin-statsite.gemspec +1 -1
- data/lib/fluent/plugin/statsite/metric.rb +13 -28
- data/lib/fluent/plugin/statsite/metric_format.rb +37 -0
- data/test/test_formatter.rb +4 -4
- data/test/test_metric.rb +50 -26
- data/test/test_metric_format.rb +37 -0
- data/test/test_out_statsite_filter.rb +2 -2
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18bf875092d09bd490fd29b12b3749aeefc44248
|
4
|
+
data.tar.gz: 522741407db13e270fbd60fa523020d0428ecb5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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", "
|
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.
|
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
|
-
|
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,
|
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.
|
29
|
-
v = @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
|
-
|
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
|
-
|
53
|
-
|
54
|
-
|
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['
|
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
|
-
|
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
|
data/test/test_formatter.rb
CHANGED
@@ -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}
|
10
|
-
Metric.validate('${k}:
|
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 "
|
20
|
+
assert_equal "test_key:test_v|g\n", @formatter.call(record)
|
21
21
|
|
22
22
|
record = {'k' => 'key', 'v' => 'value'}
|
23
|
-
assert_equal "
|
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, :
|
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
|
-
|
37
|
-
config =
|
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
|
-
|
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
|
-
|
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}
|
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 "
|
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: '
|
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.
|
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
|