fluent-plugin-librato-metrics 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +54 -12
- data/VERSION +1 -1
- data/lib/fluent/plugin/out_librato_metrics.rb +60 -24
- data/lib/fluent/plugin/out_librato_metrics_mixin.rb +14 -8
- data/test/out_librato_metrics.rb +17 -5
- metadata +7 -7
data/README.rdoc
CHANGED
@@ -18,34 +18,76 @@ Simply use RubyGems:
|
|
18
18
|
librato_user YOUR_LIBRATO_USER_NAME
|
19
19
|
librato_token YOUR_LIBRATO_TOKEN
|
20
20
|
|
21
|
-
#
|
22
|
-
<metrics metrics.status.**>
|
23
|
-
name status
|
24
|
-
each_key key
|
25
|
-
value_key value
|
26
|
-
</metrics>
|
27
|
-
|
28
|
-
# single-stream event count
|
21
|
+
# event count
|
29
22
|
<metrics metrics.event.mytask>
|
30
23
|
name mytask.count
|
31
24
|
</metrics>
|
32
25
|
|
33
|
-
#
|
26
|
+
# event sum
|
34
27
|
<metrics metrics.event.mytask>
|
35
28
|
name mytask.size
|
36
29
|
value_key size
|
37
30
|
</metrics>
|
38
31
|
|
39
|
-
#
|
32
|
+
# event sum with float type
|
40
33
|
<metrics metrics.event.mytask>
|
41
34
|
name mytask.elapsed
|
42
35
|
value_key elapsed
|
43
36
|
type float
|
44
37
|
</metrics>
|
45
38
|
|
39
|
+
# count with source
|
40
|
+
<metrics metrics.web_event.4xx>
|
41
|
+
name web.status_count
|
42
|
+
source 4xx
|
43
|
+
</metrics>
|
44
|
+
<metrics metrics.web_event.5xx>
|
45
|
+
name web.status_count
|
46
|
+
source 5xx
|
47
|
+
</metrics>
|
48
|
+
|
49
|
+
# sum with source
|
50
|
+
<metrics metrics.web_count>
|
51
|
+
name web.status_count
|
52
|
+
value_key 4xx_count
|
53
|
+
source 4xx
|
54
|
+
</metrics>
|
55
|
+
<metrics metrics.web_count>
|
56
|
+
name web.status_count
|
57
|
+
value_key 5xx_count
|
58
|
+
source 5xx
|
59
|
+
</metrics>
|
60
|
+
|
61
|
+
# key-value metrics (multi-stream)
|
62
|
+
<metrics metrics.status.**>
|
63
|
+
name status # actual name is status.$record[key]
|
64
|
+
each_key key
|
65
|
+
value_key value
|
66
|
+
</metrics>
|
67
|
+
|
46
68
|
</match>
|
47
69
|
|
48
|
-
|
70
|
+
=== Global configuration
|
71
|
+
|
72
|
+
[librato_user STRING (required)] User name of librato metrics
|
73
|
+
|
74
|
+
[librato_token STRING (required)] Token of librato metrics
|
75
|
+
|
76
|
+
[source STRING] Default source name of metrics
|
77
|
+
|
78
|
+
=== <metrics> configuration
|
79
|
+
|
80
|
+
[name STRING (required)] Name of this metrics
|
81
|
+
|
82
|
+
[source STRING] Source name of this metrics
|
83
|
+
|
84
|
+
[each_key STRING] Append 'record[each_key]' to this metrics name
|
85
|
+
|
86
|
+
[each_keys COMMA,SEPARATED,STRINGS] Append 'record[key].record[key].record[key]...' to this metrics name
|
87
|
+
|
88
|
+
[value_key STIRNG] Use 'record[value]' for the value of this metrics. Default is 1.
|
89
|
+
|
90
|
+
[count_key STIRNG] Use 'record[value] * record[count_key]' for the value of this metrics. Default is 1.
|
49
91
|
|
50
|
-
[
|
92
|
+
[type STIRNG] 'int' or 'float'. Default is int.
|
51
93
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
@@ -37,6 +37,17 @@ class LibratoMetricsOutput < Fluent::BufferedOutput
|
|
37
37
|
super
|
38
38
|
end
|
39
39
|
|
40
|
+
class LibratoMetricsMetrics < Metrics
|
41
|
+
config_param :source, :string, :default => nil
|
42
|
+
end
|
43
|
+
|
44
|
+
# override
|
45
|
+
def new_metrics(conf, pattern)
|
46
|
+
m = LibratoMetricsMetrics.new(pattern)
|
47
|
+
m.configure(conf)
|
48
|
+
m
|
49
|
+
end
|
50
|
+
|
40
51
|
def format(tag, time, record)
|
41
52
|
out = ''.force_encoding('ASCII-8BIT')
|
42
53
|
each_metrics(tag, time, record) {|d|
|
@@ -47,26 +58,35 @@ class LibratoMetricsOutput < Fluent::BufferedOutput
|
|
47
58
|
key = "#{name}.#{d.keys.join('.')}"
|
48
59
|
end
|
49
60
|
partitioned_time = time / 60 * 60
|
50
|
-
|
61
|
+
value = d.value * d.count
|
62
|
+
source = d.metrics.source
|
63
|
+
[key, partitioned_time, value, source].to_msgpack(out)
|
51
64
|
}
|
52
65
|
out
|
53
66
|
end
|
54
67
|
|
68
|
+
AggregationKey = Struct.new(:name, :time, :source)
|
69
|
+
|
55
70
|
def write(chunk)
|
56
|
-
counters = {} #=> {
|
57
|
-
gauges = {} #=> {
|
58
|
-
|
59
|
-
chunk.msgpack_each {|key,
|
60
|
-
if m = /^counter\.(.*)$/.match(key)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
71
|
+
counters = {} #=> {AggregationKey => XxxAggregator}
|
72
|
+
gauges = {} #=> {AggregationKey => XxxAggregator}
|
73
|
+
|
74
|
+
chunk.msgpack_each {|key,time,value,source|
|
75
|
+
#if m = /^counter\.(.*)$/.match(key)
|
76
|
+
# # FIXME what's the actual behavior of counters?
|
77
|
+
# name = m[1]
|
78
|
+
# k = AggregationKey.new(name, time, source)
|
79
|
+
# (counters[k] ||= MaxAggregator.new).add(value)
|
80
|
+
#elsif m = /^gauge\.(.*)$/.match(key)
|
81
|
+
# # FIXME what's the actual behavior of gauges?
|
82
|
+
# name = m[1]
|
83
|
+
# k = AggregationKey.new(name, time, source)
|
84
|
+
# (gauges[k] ||= AverageAggregator.new).add(value)
|
85
|
+
#else
|
67
86
|
name = key
|
68
|
-
|
69
|
-
|
87
|
+
k = AggregationKey.new(name, time, source)
|
88
|
+
(gauges[k] ||= SumAggregator.new).add(value)
|
89
|
+
#end
|
70
90
|
}
|
71
91
|
|
72
92
|
#http = Net::HTTP.new('metrics-api.librato.com', 80)
|
@@ -78,18 +98,19 @@ class LibratoMetricsOutput < Fluent::BufferedOutput
|
|
78
98
|
header = {}
|
79
99
|
|
80
100
|
begin
|
81
|
-
{'counters'=>counters, 'gauges'=>gauges}.each_pair {|type,
|
82
|
-
|
101
|
+
{'counters'=>counters, 'gauges'=>gauges}.each_pair {|type,k_aggrs|
|
102
|
+
# send upto 10 entries at once
|
103
|
+
k_aggrs.each_slice(10) {|k_aggrs_slice|
|
83
104
|
req = Net::HTTP::Post.new('/v1/metrics', header)
|
84
105
|
req.basic_auth @librato_user, @librato_token
|
85
106
|
|
86
|
-
params = {
|
87
|
-
|
88
|
-
}
|
89
|
-
params['source'] = @source if @source
|
107
|
+
params = {}
|
108
|
+
params['source'] = @source if @source # default source
|
90
109
|
|
91
|
-
|
92
|
-
params["#{type}[#{i}][name]"] = name
|
110
|
+
k_aggrs_slice.each_with_index {|(k,aggr),i|
|
111
|
+
params["#{type}[#{i}][name]"] = k.name
|
112
|
+
params["#{type}[#{i}][measure_time]"] = k.time.to_s
|
113
|
+
params["#{type}[#{i}][source]"] = k.source if k.source
|
93
114
|
params["#{type}[#{i}][value]"] = aggr.get.to_s
|
94
115
|
}
|
95
116
|
|
@@ -110,7 +131,7 @@ class LibratoMetricsOutput < Fluent::BufferedOutput
|
|
110
131
|
|
111
132
|
|
112
133
|
# max(value) aggregator
|
113
|
-
class
|
134
|
+
class MaxAggregator
|
114
135
|
def initialize
|
115
136
|
@value = 0
|
116
137
|
end
|
@@ -126,8 +147,23 @@ class LibratoMetricsOutput < Fluent::BufferedOutput
|
|
126
147
|
end
|
127
148
|
end
|
128
149
|
|
150
|
+
# sum(value) aggregator
|
151
|
+
class SumAggregator
|
152
|
+
def initialize
|
153
|
+
@value = 0
|
154
|
+
end
|
155
|
+
|
156
|
+
def add(value)
|
157
|
+
@value += value
|
158
|
+
end
|
159
|
+
|
160
|
+
def get
|
161
|
+
@value
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
129
165
|
# avg(value) aggregator
|
130
|
-
class
|
166
|
+
class AverageAggregator
|
131
167
|
def initialize
|
132
168
|
@value = 0
|
133
169
|
@num = 0
|
@@ -46,7 +46,7 @@ module LibratoMetricsOutput::MetricsMixin
|
|
46
46
|
e.name == 'metrics'
|
47
47
|
}.each {|e|
|
48
48
|
defaults.each_pair {|k,v| e[k] = v if v != nil }
|
49
|
-
|
49
|
+
@metrics << new_metrics(e, e.arg)
|
50
50
|
}
|
51
51
|
|
52
52
|
if mk = @match_key
|
@@ -56,10 +56,9 @@ module LibratoMetricsOutput::MetricsMixin
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
def
|
59
|
+
def new_metrics(conf, pattern)
|
60
60
|
m = Metrics.new(pattern)
|
61
61
|
m.configure(conf)
|
62
|
-
@metrics << m
|
63
62
|
end
|
64
63
|
|
65
64
|
class Data
|
@@ -185,18 +184,25 @@ module LibratoMetricsOutput::MetricsMixin
|
|
185
184
|
def evaluate(tag, time, record)
|
186
185
|
return nil unless @match_proc.call(tag)
|
187
186
|
|
188
|
-
|
189
|
-
|
190
|
-
keys = data.keys = @key_proc.call(record)
|
187
|
+
keys = @key_proc.call(record)
|
191
188
|
return nil unless keys
|
192
189
|
|
193
|
-
value =
|
190
|
+
value = @value_proc.call(record)
|
194
191
|
return nil unless value
|
195
192
|
|
196
|
-
|
193
|
+
count = @count_proc.call(record)
|
194
|
+
|
195
|
+
data = new_data
|
196
|
+
data.keys = keys
|
197
|
+
data.value = value
|
198
|
+
data.count = count
|
197
199
|
|
198
200
|
return data
|
199
201
|
end
|
202
|
+
|
203
|
+
def new_data
|
204
|
+
Data.new(self)
|
205
|
+
end
|
200
206
|
end
|
201
207
|
|
202
208
|
def each_metrics(tag, time, record, &block)
|
data/test/out_librato_metrics.rb
CHANGED
@@ -36,6 +36,13 @@ class LibratoMetricsOutputTest < Test::Unit::TestCase
|
|
36
36
|
value_key elapsed
|
37
37
|
type float
|
38
38
|
</metrics>
|
39
|
+
|
40
|
+
# single-stream event sum with source
|
41
|
+
<metrics test5.**>
|
42
|
+
name test5.stack
|
43
|
+
value_key count
|
44
|
+
source type1
|
45
|
+
</metrics>
|
39
46
|
]
|
40
47
|
|
41
48
|
TIME = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
@@ -57,23 +64,28 @@ class LibratoMetricsOutputTest < Test::Unit::TestCase
|
|
57
64
|
def test_format
|
58
65
|
d = create_driver("test1.1")
|
59
66
|
d.emit({"key"=>"a", "value"=>10, "count"=>2}, TIME)
|
60
|
-
d.expect_format ["test1.a", TIME/60*60, 20].to_msgpack
|
67
|
+
d.expect_format ["test1.a", TIME/60*60, 20, nil].to_msgpack
|
61
68
|
d.run
|
62
69
|
|
63
70
|
d = create_driver("test2.2")
|
64
71
|
d.emit({}, TIME)
|
65
|
-
d.expect_format ["test2.count", TIME/60*60, 1].to_msgpack
|
72
|
+
d.expect_format ["test2.count", TIME/60*60, 1, nil].to_msgpack
|
66
73
|
d.run
|
67
74
|
|
68
75
|
d = create_driver("test3.3")
|
69
76
|
d.emit({"size"=>2100}, TIME)
|
70
|
-
d.expect_format ["test3.size", TIME/60*60, 2100].to_msgpack
|
77
|
+
d.expect_format ["test3.size", TIME/60*60, 2100, nil].to_msgpack
|
71
78
|
d.run
|
72
79
|
|
73
80
|
d = create_driver("test3.test4")
|
74
81
|
d.emit({"size"=>2400, "elapsed"=>10.0}, TIME)
|
75
|
-
d.expect_format ["test3.size", TIME/60*60, 2400].to_msgpack
|
76
|
-
d.expect_format ["test4.elapsed", TIME/60*60, 10.0].to_msgpack
|
82
|
+
d.expect_format ["test3.size", TIME/60*60, 2400, nil].to_msgpack
|
83
|
+
d.expect_format ["test4.elapsed", TIME/60*60, 10.0, nil].to_msgpack
|
84
|
+
d.run
|
85
|
+
|
86
|
+
d = create_driver("test5")
|
87
|
+
d.emit({"count"=>12}, TIME)
|
88
|
+
d.expect_format ["test5.stack", TIME/60*60, 12, "type1"].to_msgpack
|
77
89
|
d.run
|
78
90
|
end
|
79
91
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-librato-metrics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-03-30 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|
16
|
-
requirement: &
|
16
|
+
requirement: &70308779156220 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.10.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70308779156220
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70308779155740 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 0.9.2
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70308779155740
|
36
36
|
description: Librato metrics output plugin for Fluent event collector
|
37
37
|
email:
|
38
38
|
- frsyuki@gmail.com
|
@@ -64,7 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
64
64
|
version: '0'
|
65
65
|
segments:
|
66
66
|
- 0
|
67
|
-
hash:
|
67
|
+
hash: 3018102368853295399
|
68
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
69
|
none: false
|
70
70
|
requirements:
|
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
73
|
version: '0'
|
74
74
|
segments:
|
75
75
|
- 0
|
76
|
-
hash:
|
76
|
+
hash: 3018102368853295399
|
77
77
|
requirements: []
|
78
78
|
rubyforge_project:
|
79
79
|
rubygems_version: 1.8.12
|