cloudwatchtographite 0.0.0.pre1
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.
- data/.coveralls.yml +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +25 -0
- data/LICENSE +21 -0
- data/README.md +138 -0
- data/Rakefile +54 -0
- data/bin/cloudwatch_to_graphite +142 -0
- data/conf/example-metrics.json +23 -0
- data/conf/example-metrics.yaml +25 -0
- data/lib/cloudwatchtographite/exception.rb +36 -0
- data/lib/cloudwatchtographite/loadmetrics.rb +70 -0
- data/lib/cloudwatchtographite/metricdefinition.rb +205 -0
- data/lib/cloudwatchtographite/metricdimension.rb +48 -0
- data/lib/cloudwatchtographite/validator.rb +47 -0
- data/lib/cloudwatchtographite/version.rb +25 -0
- data/lib/cloudwatchtographite.rb +185 -0
- data/spec/cloudwatchtographite_spec.rb +28 -0
- data/spec/factories/metricdefinition.rb +12 -0
- data/spec/factories/metricdimension.rb +6 -0
- data/spec/loadmetrics_spec.rb +27 -0
- data/spec/metricdefinition_spec.rb +143 -0
- data/spec/metricdimension_spec.rb +74 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/version_spec.rb +7 -0
- metadata +236 -0
@@ -0,0 +1,205 @@
|
|
1
|
+
# _*_ coding: utf-8 _*_
|
2
|
+
# == Synopsis
|
3
|
+
# CloudwatchToGraphite retrieves metrics from the Amazon CloudWatch APIs
|
4
|
+
# and passes them on to a graphite server
|
5
|
+
#
|
6
|
+
# == Author
|
7
|
+
# S. Zachariah Sprackett <zac@sprackett.com>
|
8
|
+
#
|
9
|
+
# == License
|
10
|
+
# The MIT License (MIT)
|
11
|
+
#
|
12
|
+
# == Copyright
|
13
|
+
# Copyright (C) 2013 - S. Zachariah Sprackett <zac@sprackett.com>
|
14
|
+
#
|
15
|
+
require 'time'
|
16
|
+
require 'hashifiable'
|
17
|
+
|
18
|
+
module CloudwatchToGraphite
|
19
|
+
UNITS = [
|
20
|
+
'None',
|
21
|
+
'Seconds',
|
22
|
+
'Microseconds',
|
23
|
+
'Milliseconds',
|
24
|
+
'Bytes',
|
25
|
+
'Kilobytes',
|
26
|
+
'Megabytes',
|
27
|
+
'Gigabytes',
|
28
|
+
'Terabytes',
|
29
|
+
'Bits',
|
30
|
+
'Kilobits',
|
31
|
+
'Megabits',
|
32
|
+
'Gigabits',
|
33
|
+
'Terabits',
|
34
|
+
'Gigabytes/Second',
|
35
|
+
'Terabytes/Second',
|
36
|
+
'Bits/Second',
|
37
|
+
'Kilobits/Second',
|
38
|
+
'Megabits/Second',
|
39
|
+
'Gigabits/Second',
|
40
|
+
'Terabits/Second',
|
41
|
+
'Count/Second'
|
42
|
+
]
|
43
|
+
|
44
|
+
STATISTICS = [
|
45
|
+
'Minimum',
|
46
|
+
'Maximum',
|
47
|
+
'Sum',
|
48
|
+
'Average',
|
49
|
+
'SampleCount'
|
50
|
+
]
|
51
|
+
|
52
|
+
SETTER_MAPPINGS = {
|
53
|
+
'namespace' => :Namespace=,
|
54
|
+
'metricname' => :MetricName=,
|
55
|
+
'statistics' => :Statistics=,
|
56
|
+
'starttime' => :StartTime=,
|
57
|
+
'endtime' => :EndTime=,
|
58
|
+
'period' => :Period=,
|
59
|
+
'dimensions' => :Dimensions=,
|
60
|
+
'unit' => :Unit=
|
61
|
+
}
|
62
|
+
|
63
|
+
# A hashable representation of an AWS CloudWatch metric
|
64
|
+
#
|
65
|
+
class MetricDefinition
|
66
|
+
attr_reader :Namespace, :MetricName, :Statistics, :Unit, :Period
|
67
|
+
extend Hashifiable
|
68
|
+
hashify 'Namespace', 'MetricName', 'Statistics', 'StartTime', \
|
69
|
+
'EndTime', 'Period', 'Dimensions'#, 'Unit'
|
70
|
+
|
71
|
+
def initialize
|
72
|
+
@Unit = UNITS[0]
|
73
|
+
@Dimensions = []
|
74
|
+
@Statistics = []
|
75
|
+
@Period = 60
|
76
|
+
end
|
77
|
+
|
78
|
+
def Namespace=(n)
|
79
|
+
Validator::string_shorter_than(n, 256)
|
80
|
+
@Namespace=n
|
81
|
+
end
|
82
|
+
|
83
|
+
def MetricName=(n)
|
84
|
+
Validator::string_shorter_than(n, 256)
|
85
|
+
@MetricName=n
|
86
|
+
end
|
87
|
+
|
88
|
+
def StartTime=(time)
|
89
|
+
raise ArgumentTypeError unless time.kind_of?(Time)
|
90
|
+
@StartTime=time
|
91
|
+
end
|
92
|
+
|
93
|
+
def StartTime
|
94
|
+
if @StartTime.nil?
|
95
|
+
(Time.now-600).iso8601
|
96
|
+
else
|
97
|
+
@StartTime.iso8601
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def EndTime=(time)
|
102
|
+
raise ArgumentTypeError unless time.kind_of?(Time)
|
103
|
+
@EndTime=time
|
104
|
+
end
|
105
|
+
|
106
|
+
def EndTime
|
107
|
+
if @EndTime.nil?
|
108
|
+
Time.now.iso8601
|
109
|
+
else
|
110
|
+
@EndTime.iso8601
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def Period=(n)
|
115
|
+
raise ArgumentTypeError unless n.kind_of? Integer
|
116
|
+
@Period = n
|
117
|
+
end
|
118
|
+
|
119
|
+
def Unit=(n)
|
120
|
+
raise ArgumentTypeError unless UNITS.include? n
|
121
|
+
@Unit = n
|
122
|
+
end
|
123
|
+
|
124
|
+
def Dimensions
|
125
|
+
@Dimensions.map(&:to_h)
|
126
|
+
end
|
127
|
+
|
128
|
+
def add_statistic(n)
|
129
|
+
raise ArgumentTypeError unless STATISTICS.include? n
|
130
|
+
if not @Statistics.include? n
|
131
|
+
@Statistics.push(n)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def add_dimension(n)
|
136
|
+
if not n.kind_of?(MetricDimension)
|
137
|
+
raise ArgumentTypeError
|
138
|
+
elsif @Dimensions.length >= 10
|
139
|
+
raise TooManyDimensionError
|
140
|
+
end
|
141
|
+
@Dimensions.push(n)
|
142
|
+
end
|
143
|
+
|
144
|
+
def valid?
|
145
|
+
if @Namespace.nil? or @MetricName.nil? or @Statistics.empty? \
|
146
|
+
or @Dimensions.empty? or @Unit.nil?
|
147
|
+
false
|
148
|
+
else
|
149
|
+
true
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def graphite_path(stat)
|
154
|
+
path = "%s.%s.%s.%s" % [
|
155
|
+
self.Namespace,
|
156
|
+
self.MetricName,
|
157
|
+
stat,
|
158
|
+
@Dimensions.join('.')
|
159
|
+
]
|
160
|
+
path.gsub('/', '.').downcase
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.create_and_fill(definition)
|
164
|
+
md = MetricDefinition.new
|
165
|
+
definition.each_key do |k|
|
166
|
+
populate_metric_definition(
|
167
|
+
md, k, definition[k]
|
168
|
+
)
|
169
|
+
end
|
170
|
+
raise ParseError unless md.valid?
|
171
|
+
return md
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.populate_metric_definition(md, key, value)
|
175
|
+
case key
|
176
|
+
when 'namespace', 'metricname', 'period', 'unit'
|
177
|
+
md.send(SETTER_MAPPINGS[key], value)
|
178
|
+
when 'starttime', 'endtime'
|
179
|
+
begin
|
180
|
+
md.send(SETTER_MAPPINGS[key], Time.parse(value))
|
181
|
+
rescue ArgumentTypeError
|
182
|
+
raise ParseError
|
183
|
+
end
|
184
|
+
when 'statistics'
|
185
|
+
populate_statistics(md, value)
|
186
|
+
when 'dimensions'
|
187
|
+
populate_dimensions_from_hashes(md, value)
|
188
|
+
else
|
189
|
+
raise ParseError
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def self.populate_statistics(md, statistics)
|
194
|
+
Array(statistics).each do |stat|
|
195
|
+
md.add_statistic(stat)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def self.populate_dimensions_from_hashes(md, dimensions)
|
200
|
+
Array(dimensions).each do |dimension|
|
201
|
+
md.add_dimension(MetricDimension.create_from_hash(dimension))
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# _*_ coding: utf-8 _*_
|
2
|
+
# == Synopsis
|
3
|
+
# CloudwatchToGraphite retrieves metrics from the Amazon CloudWatch APIs
|
4
|
+
# and passes them on to a graphite server
|
5
|
+
#
|
6
|
+
# == Author
|
7
|
+
# S. Zachariah Sprackett <zac@sprackett.com>
|
8
|
+
#
|
9
|
+
# == License
|
10
|
+
# The MIT License (MIT)
|
11
|
+
#
|
12
|
+
# == Copyright
|
13
|
+
# Copyright (C) 2013 - S. Zachariah Sprackett <zac@sprackett.com>
|
14
|
+
#
|
15
|
+
module CloudwatchToGraphite
|
16
|
+
# A hashable representation of an AWS CloudWatch metric dimension
|
17
|
+
class MetricDimension
|
18
|
+
attr_reader :Name, :Value
|
19
|
+
extend Hashifiable
|
20
|
+
hashify 'Name', 'Value'
|
21
|
+
|
22
|
+
def Name=(n)
|
23
|
+
Validator::string_shorter_than(n, 256)
|
24
|
+
@Name=n
|
25
|
+
end
|
26
|
+
|
27
|
+
def Value=(n)
|
28
|
+
Validator::string_shorter_than(n, 256)
|
29
|
+
@Value=n
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.create(name, value)
|
33
|
+
md = MetricDimension.new
|
34
|
+
md.Name = name
|
35
|
+
md.Value = value
|
36
|
+
md
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.create_from_hash(dhash)
|
40
|
+
Validator::hash_with_keys(dhash, ['name', 'value'])
|
41
|
+
|
42
|
+
MetricDimension::create(
|
43
|
+
dhash['name'],
|
44
|
+
dhash['value']
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# _*_ coding: utf-8 _*_
|
2
|
+
# == Synopsis
|
3
|
+
# CloudwatchToGraphite retrieves metrics from the Amazon CloudWatch APIs
|
4
|
+
# and passes them on to a graphite server
|
5
|
+
#
|
6
|
+
# == Author
|
7
|
+
# S. Zachariah Sprackett <zac@sprackett.com>
|
8
|
+
#
|
9
|
+
# == License
|
10
|
+
# The MIT License (MIT)
|
11
|
+
#
|
12
|
+
# == Copyright
|
13
|
+
# Copyright (C) 2013 - S. Zachariah Sprackett <zac@sprackett.com>
|
14
|
+
#
|
15
|
+
module CloudwatchToGraphite
|
16
|
+
# static methods to validate arguments
|
17
|
+
class Validator
|
18
|
+
def self.string(n)
|
19
|
+
raise ArgumentTypeError unless n.kind_of?(String)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.string_shorter_than(n, length)
|
23
|
+
string(n)
|
24
|
+
raise ArgumentLengthError unless n.length < length
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.string_longer_than(n, length)
|
28
|
+
string(n)
|
29
|
+
raise ArgumentLengthError unless n.length > length
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.hash_with_key(h, key)
|
33
|
+
raise ArgumentTypeError unless h.kind_of?(Hash) and h.has_key?(key)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.hash_with_keys(h, keys)
|
37
|
+
keys.each do |k|
|
38
|
+
hash_with_key(h,k)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.hash_with_key_of_type(h, key, type)
|
43
|
+
hash_with_key(h, key)
|
44
|
+
raise ArgumentTypeError unless h[key].kind_of?(type)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# _*_ coding: utf-8 _*_
|
2
|
+
# == Synopsis
|
3
|
+
# CloudwatchToGraphite retrieves metrics from the Amazon CloudWatch APIs
|
4
|
+
# and passes them on to a graphite server
|
5
|
+
#
|
6
|
+
# == Author
|
7
|
+
# S. Zachariah Sprackett <zac@sprackett.com>
|
8
|
+
#
|
9
|
+
# == License
|
10
|
+
# The MIT License (MIT)
|
11
|
+
#
|
12
|
+
# == Copyright
|
13
|
+
# Copyright (C) 2013 - S. Zachariah Sprackett <zac@sprackett.com>
|
14
|
+
#
|
15
|
+
module CloudwatchToGraphite
|
16
|
+
class VERSION
|
17
|
+
MAJOR = 0
|
18
|
+
MINOR = 0
|
19
|
+
PATCH = 0
|
20
|
+
BUILD = 'pre1'
|
21
|
+
|
22
|
+
STRING = [MAJOR, MINOR, PATCH].compact.join('.') \
|
23
|
+
+ (BUILD.empty? ? '' : ".#{BUILD}")
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
# _*_ coding: utf-8 _*_
|
2
|
+
#
|
3
|
+
# Author:: S. Zachariah Sprackett <zac@sprackett.com>
|
4
|
+
# License:: The MIT License (MIT)
|
5
|
+
# Copyright:: Copyright (C) 2013 - S. Zachariah Sprackett <zac@sprackett.com>
|
6
|
+
#
|
7
|
+
require_relative './cloudwatchtographite/exception'
|
8
|
+
require_relative './cloudwatchtographite/version'
|
9
|
+
require_relative './cloudwatchtographite/metricdefinition'
|
10
|
+
require_relative './cloudwatchtographite/metricdimension'
|
11
|
+
require_relative './cloudwatchtographite/loadmetrics'
|
12
|
+
require_relative './cloudwatchtographite/validator'
|
13
|
+
require 'socket'
|
14
|
+
require 'fog'
|
15
|
+
require 'pp'
|
16
|
+
|
17
|
+
module CloudwatchToGraphite
|
18
|
+
# This class is responsible for retrieving metrics from CloudWatch and
|
19
|
+
# sending the results to a Graphite server.
|
20
|
+
class Base
|
21
|
+
attr_accessor :protocol
|
22
|
+
attr_accessor :graphite_server
|
23
|
+
attr_accessor :graphite_port
|
24
|
+
attr_reader :carbon_prefix
|
25
|
+
|
26
|
+
# Initialize the CloudwatchToGraphite::Base object.
|
27
|
+
# aws_access_key:: The AWS user key
|
28
|
+
# aws_secret_key:: The AWS secret
|
29
|
+
# region:: The AWS region (eg: us-west-1)
|
30
|
+
# verbose:: boolean to enable verbose output
|
31
|
+
#
|
32
|
+
def initialize(aws_access_key, aws_secret_key, region, verbose=false)
|
33
|
+
@protocol = 'udp'
|
34
|
+
@carbon_prefix = 'cloudwatch'
|
35
|
+
@graphite_server = 'localhost'
|
36
|
+
@graphite_port = 2003
|
37
|
+
@verbose = verbose
|
38
|
+
|
39
|
+
debug_log "Fog setting up for region #{region}"
|
40
|
+
|
41
|
+
@cloudwatch = Fog::AWS::CloudWatch.new(
|
42
|
+
:aws_access_key_id => aws_access_key,
|
43
|
+
:aws_secret_access_key => aws_secret_key,
|
44
|
+
:region => region
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Send data to a Graphite server via the UDP protocol
|
49
|
+
# contents:: a string or array containing the contents to send
|
50
|
+
#
|
51
|
+
def send_udp(contents)
|
52
|
+
sock = nil
|
53
|
+
contents = contents.join("\n") if contents.kind_of?(Array)
|
54
|
+
|
55
|
+
debug_log "Attempting to send #{contents.length} bytes " +
|
56
|
+
"to #{@graphite_server}:#{@graphite_port} via udp"
|
57
|
+
|
58
|
+
begin
|
59
|
+
sock = UDPSocket.open
|
60
|
+
sock.send(contents, 0, @graphite_server, @graphite_port)
|
61
|
+
retval = true
|
62
|
+
rescue Exception => e
|
63
|
+
debug_log "Caught exception! [#{e}]"
|
64
|
+
retval = false
|
65
|
+
ensure
|
66
|
+
sock.close if sock
|
67
|
+
end
|
68
|
+
retval
|
69
|
+
end
|
70
|
+
|
71
|
+
# Send data to a Graphite server via the TCP protocol
|
72
|
+
# contents:: a string or array containing the contents to send
|
73
|
+
#
|
74
|
+
def send_tcp(contents)
|
75
|
+
sock = nil
|
76
|
+
contents = contents.join("\n") if contents.kind_of?(Array)
|
77
|
+
|
78
|
+
debug_log "Attempting to send #{contents.length} bytes " +
|
79
|
+
"to #{@graphite_server}:#{@graphite_port} via tcp"
|
80
|
+
|
81
|
+
retval = false
|
82
|
+
begin
|
83
|
+
sock = TCPSocket.open(@graphite_server, @graphite_port)
|
84
|
+
sock.print(contents)
|
85
|
+
retval = true
|
86
|
+
rescue Exception => e
|
87
|
+
debug_log "Caught exception! [#{e}]"
|
88
|
+
ensure
|
89
|
+
sock.close if sock
|
90
|
+
end
|
91
|
+
retval
|
92
|
+
end
|
93
|
+
|
94
|
+
def retrieve_datapoints(metrics)
|
95
|
+
ret = []
|
96
|
+
Array(metrics).each do |m|
|
97
|
+
begin
|
98
|
+
ret.concat retrieve_one_datapoint(m)
|
99
|
+
rescue Excon::Errors::SocketError, Excon::Errors::BadRequest => e
|
100
|
+
warn "[Error in CloudWatch call] #{e.message}"
|
101
|
+
rescue Excon::Errors::Forbidden
|
102
|
+
warn "[Error in CloudWatch call] permission denied - check keys!"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
ret
|
106
|
+
end
|
107
|
+
|
108
|
+
def retrieve_one_datapoint(metric)
|
109
|
+
debug_log "Sending to CloudWatch:"
|
110
|
+
debug_object metric.to_h
|
111
|
+
data_points = @cloudwatch.get_metric_statistics(
|
112
|
+
metric.to_h
|
113
|
+
).body['GetMetricStatisticsResult']['Datapoints']
|
114
|
+
debug_log "Received from CloudWatch:"
|
115
|
+
debug_object data_points
|
116
|
+
|
117
|
+
return retrieve_statistics(metric, order_data_points(data_points))
|
118
|
+
end
|
119
|
+
|
120
|
+
def retrieve_statistics(metric, data_points)
|
121
|
+
ret = []
|
122
|
+
metric.Statistics.each do |stat|
|
123
|
+
name = "#{@carbon_prefix}.#{metric.graphite_path(stat)}"
|
124
|
+
data_points.each do |d|
|
125
|
+
ret.push "#{name} #{d[stat]} #{d['Timestamp'].utc.to_i}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
debug_log "Returning Statistics:"
|
129
|
+
debug_object ret
|
130
|
+
ret
|
131
|
+
end
|
132
|
+
|
133
|
+
def fetch_and_forward(metrics)
|
134
|
+
results = retrieve_datapoints(metrics)
|
135
|
+
if results.length == 0
|
136
|
+
false
|
137
|
+
else
|
138
|
+
case @protocol
|
139
|
+
when 'tcp'
|
140
|
+
send_tcp(results)
|
141
|
+
when 'udp'
|
142
|
+
send_udp(results)
|
143
|
+
else
|
144
|
+
debug_log "Unknown protocol #{@protocol}"
|
145
|
+
raise ProtocolError
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# set the carbon prefix
|
151
|
+
# p:: the string prefix to use
|
152
|
+
def carbon_prefix=(p)
|
153
|
+
Validator::string_longer_than(p, 0)
|
154
|
+
@carbon_prefix=p
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
def order_data_points(data_points)
|
159
|
+
if data_points.nil?
|
160
|
+
data_points = []
|
161
|
+
else
|
162
|
+
data_points = Array(data_points)
|
163
|
+
end
|
164
|
+
|
165
|
+
if data_points.length == 0
|
166
|
+
warn "No data points!"
|
167
|
+
data_points
|
168
|
+
else
|
169
|
+
data_points = data_points.sort_by {|array| array['Timestamp'] }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def debug_log(s)
|
174
|
+
if @verbose
|
175
|
+
warn s
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def debug_object(s)
|
180
|
+
if @verbose
|
181
|
+
warn PP.pp(s, "")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe CloudwatchToGraphite::Base do
|
4
|
+
before :each do
|
5
|
+
@base = CloudwatchToGraphite::Base.new 'foo', 'bar', 'us-east-1', false
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ".new" do
|
9
|
+
it "takes four parameters and returns a CloudwatchToGraphite::Base" do
|
10
|
+
@base.should be_an_instance_of CloudwatchToGraphite::Base
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ".fetch_and_forward" do
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".carbon_prefix=" do
|
18
|
+
it "allows setting a prefix for carbon" do
|
19
|
+
expect { @base.carbon_prefix = 123 }.to \
|
20
|
+
raise_error(CloudwatchToGraphite::ArgumentTypeError)
|
21
|
+
expect { @base.carbon_prefix = '' }.to \
|
22
|
+
raise_error(CloudwatchToGraphite::ArgumentLengthError)
|
23
|
+
@base.carbon_prefix = "the_prefix"
|
24
|
+
@base.carbon_prefix.should eql "the_prefix"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :metricdefinition, class: CloudwatchToGraphite::MetricDefinition do
|
3
|
+
sequence(:MetricName) { |n| "metricname#{n}" }
|
4
|
+
sequence(:Namespace) { |n| "namespace#{n}" }
|
5
|
+
Period 90
|
6
|
+
Unit 'None'
|
7
|
+
after(:build) do |definition, evaluator|
|
8
|
+
definition.add_statistic('Sum')
|
9
|
+
definition.add_statistic('Average')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe CloudwatchToGraphite::LoadMetrics do
|
4
|
+
|
5
|
+
describe "#load_content" do
|
6
|
+
it "it should not load invalid metrics" do
|
7
|
+
content = {'shmetrics' => 'foo'}
|
8
|
+
expect {
|
9
|
+
CloudwatchToGraphite::LoadMetrics::load_content(content)
|
10
|
+
}.to raise_error(CloudwatchToGraphite::ArgumentTypeError)
|
11
|
+
end
|
12
|
+
|
13
|
+
#it "it should load valid metrics" do
|
14
|
+
# content = {
|
15
|
+
# 'metrics' => [ {
|
16
|
+
# 'namespace' => 'thenamespace',
|
17
|
+
# 'metricname' => 'themetricname',
|
18
|
+
# 'statistics' => 'Average',
|
19
|
+
# 'period' => 1,
|
20
|
+
# 'dimensions' => [ { 'name' => 'thename', 'value' => 'thevalue' }]
|
21
|
+
# }]
|
22
|
+
# }
|
23
|
+
# metrics = CloudwatchToGraphite::LoadMetrics::load_content(content)
|
24
|
+
# metrics.should be_an(Array)
|
25
|
+
#end
|
26
|
+
end
|
27
|
+
end
|