cloudwatchtographite 0.0.0.pre1 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/README.md +1 -0
- data/bin/cloudwatch_to_graphite +25 -5
- data/lib/cloudwatchtographite/version.rb +2 -2
- data/lib/cloudwatchtographite.rb +19 -31
- data/spec/cloudwatchtographite_spec.rb +2 -2
- metadata +22 -6
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,7 @@ submit them to a Graphite server of your choosing.
|
|
10
10
|
- [Graphite](http://graphite.wikidot.com/)
|
11
11
|
- [AWS CloudWatch](http://aws.amazon.com/cloudwatch/)
|
12
12
|
|
13
|
+
[![Gem Version](https://badge.fury.io/rb/cloudwatchtographite.png)](http://badge.fury.io/rb/cloudwatchtographite)
|
13
14
|
[![Build Status](https://travis-ci.org/zsprackett/cloudwatchtographite.png?branch=master)](https://travis-ci.org/zsprackett/cloudwatchtographite)
|
14
15
|
[![Code Climate](https://codeclimate.com/github/zsprackett/cloudwatchtographite.png)](https://codeclimate.com/github/zsprackett/cloudwatchtographite)
|
15
16
|
[![Coverage Status](https://coveralls.io/repos/zsprackett/cloudwatchtographite/badge.png)](https://coveralls.io/r/zsprackett/cloudwatchtographite)
|
data/bin/cloudwatch_to_graphite
CHANGED
@@ -17,6 +17,13 @@
|
|
17
17
|
|
18
18
|
require 'optparse'
|
19
19
|
require 'pp'
|
20
|
+
require 'log4r'
|
21
|
+
|
22
|
+
logger = Log4r::Logger.new('cloudwatchtographite')
|
23
|
+
logger.level = Log4r::ERROR
|
24
|
+
f = Log4r::Outputter.stderr
|
25
|
+
f.formatter = Log4r::PatternFormatter.new(:pattern => "[%d] %C: %m")
|
26
|
+
logger.outputters = f
|
20
27
|
|
21
28
|
begin
|
22
29
|
require 'cloudwatchtographite'
|
@@ -37,7 +44,6 @@ options = {
|
|
37
44
|
:graphite_server => 'localhost',
|
38
45
|
:graphite_port => 2003,
|
39
46
|
:carbon_prefix => 'cloudwatch',
|
40
|
-
:verbose => false
|
41
47
|
}
|
42
48
|
opt_parser = OptionParser.new do |opt|
|
43
49
|
opt.banner = "Usage: %s [OPTIONS]" % File.basename($0)
|
@@ -69,8 +75,17 @@ opt_parser = OptionParser.new do |opt|
|
|
69
75
|
opt.on("-c","--carbon-prefix=prefix","Carbon Prefix (Default: #{options[:carbon_prefix]})") do |prefix|
|
70
76
|
options[:carbon_prefix] = prefix
|
71
77
|
end
|
78
|
+
opt.on("-l","--logfile=prefix","Log file (Default: stderr") do |logfile|
|
79
|
+
f = Log4r::FileOutputter.new(
|
80
|
+
'logfile',
|
81
|
+
:filename => logfile,
|
82
|
+
:trunc => false
|
83
|
+
)
|
84
|
+
f.formatter = Log4r::PatternFormatter.new(:pattern => "[%l] %d %C: %m")
|
85
|
+
logger.outputters = f
|
86
|
+
end
|
72
87
|
opt.on("-v","--verbose","Increase verbosity") do
|
73
|
-
|
88
|
+
logger.level = Log4r::DEBUG
|
74
89
|
end
|
75
90
|
opt.on("-V","--version","Print version and exit") do
|
76
91
|
puts File.basename($0) + " " + CloudwatchToGraphite::VERSION::STRING
|
@@ -109,25 +124,27 @@ end
|
|
109
124
|
metrics = nil
|
110
125
|
begin
|
111
126
|
if not options[:json_metrics].nil?
|
127
|
+
logger.debug('Parsing JSON metrics')
|
112
128
|
metrics = CloudwatchToGraphite::LoadMetrics.from_json_file(options[:json_metrics])
|
113
129
|
else
|
130
|
+
logger.debug('Parsing YAML metrics')
|
114
131
|
metrics = CloudwatchToGraphite::LoadMetrics.from_yaml_file(options[:yaml_metrics])
|
115
132
|
end
|
116
133
|
rescue CloudwatchToGraphite::ParseError
|
117
|
-
|
134
|
+
logger.fatal('Failed to parse option file')
|
118
135
|
exit 1
|
119
136
|
end
|
120
137
|
|
121
138
|
if metrics.empty?
|
122
|
-
|
139
|
+
logger.fatal('Exiting due to lack of metric definitions')
|
123
140
|
exit 1
|
124
141
|
end
|
125
142
|
|
143
|
+
logger.debug('Initializing CloudwatchToGraphite::Base')
|
126
144
|
cwtg = CloudwatchToGraphite::Base.new(
|
127
145
|
options[:access_key],
|
128
146
|
options[:secret_key],
|
129
147
|
options[:region],
|
130
|
-
options[:verbose]
|
131
148
|
)
|
132
149
|
|
133
150
|
cwtg.carbon_prefix = options[:carbon_prefix]
|
@@ -135,8 +152,11 @@ cwtg.protocol = options[:protocol]
|
|
135
152
|
cwtg.graphite_server = options[:graphite_server]
|
136
153
|
cwtg.graphite_port = options[:graphite_port]
|
137
154
|
|
155
|
+
logger.debug('Fetching and forwarding metrics')
|
138
156
|
if cwtg.fetch_and_forward(metrics)
|
157
|
+
logger.info('Exiting Success')
|
139
158
|
exit 0
|
140
159
|
else
|
160
|
+
logger.info('Exiting Failure')
|
141
161
|
exit 1
|
142
162
|
end
|
data/lib/cloudwatchtographite.rb
CHANGED
@@ -13,6 +13,7 @@ require_relative './cloudwatchtographite/validator'
|
|
13
13
|
require 'socket'
|
14
14
|
require 'fog'
|
15
15
|
require 'pp'
|
16
|
+
require 'log4r'
|
16
17
|
|
17
18
|
module CloudwatchToGraphite
|
18
19
|
# This class is responsible for retrieving metrics from CloudWatch and
|
@@ -29,14 +30,14 @@ module CloudwatchToGraphite
|
|
29
30
|
# region:: The AWS region (eg: us-west-1)
|
30
31
|
# verbose:: boolean to enable verbose output
|
31
32
|
#
|
32
|
-
def initialize(aws_access_key, aws_secret_key, region
|
33
|
+
def initialize(aws_access_key, aws_secret_key, region)
|
34
|
+
@logger = Log4r::Logger.new('cloudwatchtographite::base')
|
33
35
|
@protocol = 'udp'
|
34
36
|
@carbon_prefix = 'cloudwatch'
|
35
37
|
@graphite_server = 'localhost'
|
36
38
|
@graphite_port = 2003
|
37
|
-
@verbose = verbose
|
38
39
|
|
39
|
-
|
40
|
+
@logger.debug("Fog setting up for region #{region}")
|
40
41
|
|
41
42
|
@cloudwatch = Fog::AWS::CloudWatch.new(
|
42
43
|
:aws_access_key_id => aws_access_key,
|
@@ -52,15 +53,15 @@ module CloudwatchToGraphite
|
|
52
53
|
sock = nil
|
53
54
|
contents = contents.join("\n") if contents.kind_of?(Array)
|
54
55
|
|
55
|
-
|
56
|
-
"to #{@graphite_server}:#{@graphite_port} via udp"
|
56
|
+
@logger.debug("Attempting to send #{contents.length} bytes " +
|
57
|
+
"to #{@graphite_server}:#{@graphite_port} via udp")
|
57
58
|
|
58
59
|
begin
|
59
60
|
sock = UDPSocket.open
|
60
61
|
sock.send(contents, 0, @graphite_server, @graphite_port)
|
61
62
|
retval = true
|
62
63
|
rescue Exception => e
|
63
|
-
|
64
|
+
@logger.debug("Caught exception! [#{e}]")
|
64
65
|
retval = false
|
65
66
|
ensure
|
66
67
|
sock.close if sock
|
@@ -75,8 +76,8 @@ module CloudwatchToGraphite
|
|
75
76
|
sock = nil
|
76
77
|
contents = contents.join("\n") if contents.kind_of?(Array)
|
77
78
|
|
78
|
-
|
79
|
-
"to #{@graphite_server}:#{@graphite_port} via tcp"
|
79
|
+
@logger.debug("Attempting to send #{contents.length} bytes " +
|
80
|
+
"to #{@graphite_server}:#{@graphite_port} via tcp")
|
80
81
|
|
81
82
|
retval = false
|
82
83
|
begin
|
@@ -84,7 +85,7 @@ module CloudwatchToGraphite
|
|
84
85
|
sock.print(contents)
|
85
86
|
retval = true
|
86
87
|
rescue Exception => e
|
87
|
-
|
88
|
+
@logger.debug("Caught exception! [#{e}]")
|
88
89
|
ensure
|
89
90
|
sock.close if sock
|
90
91
|
end
|
@@ -97,22 +98,22 @@ module CloudwatchToGraphite
|
|
97
98
|
begin
|
98
99
|
ret.concat retrieve_one_datapoint(m)
|
99
100
|
rescue Excon::Errors::SocketError, Excon::Errors::BadRequest => e
|
100
|
-
|
101
|
+
@logger.error("[Error in CloudWatch call] #{e.message}")
|
101
102
|
rescue Excon::Errors::Forbidden
|
102
|
-
|
103
|
+
@logger.error(
|
104
|
+
"[Error in CloudWatch call] permission denied - check keys!"
|
105
|
+
)
|
103
106
|
end
|
104
107
|
end
|
105
108
|
ret
|
106
109
|
end
|
107
110
|
|
108
111
|
def retrieve_one_datapoint(metric)
|
109
|
-
|
110
|
-
debug_object metric.to_h
|
112
|
+
@logger.debug("Sending to CloudWatch: #{metric.to_h}")
|
111
113
|
data_points = @cloudwatch.get_metric_statistics(
|
112
114
|
metric.to_h
|
113
115
|
).body['GetMetricStatisticsResult']['Datapoints']
|
114
|
-
|
115
|
-
debug_object data_points
|
116
|
+
@logger.debug("Received from CloudWatch: #{data_points}")
|
116
117
|
|
117
118
|
return retrieve_statistics(metric, order_data_points(data_points))
|
118
119
|
end
|
@@ -125,8 +126,7 @@ module CloudwatchToGraphite
|
|
125
126
|
ret.push "#{name} #{d[stat]} #{d['Timestamp'].utc.to_i}"
|
126
127
|
end
|
127
128
|
end
|
128
|
-
|
129
|
-
debug_object ret
|
129
|
+
@logger.debug("Returning Statistics: #{ret}")
|
130
130
|
ret
|
131
131
|
end
|
132
132
|
|
@@ -141,7 +141,7 @@ module CloudwatchToGraphite
|
|
141
141
|
when 'udp'
|
142
142
|
send_udp(results)
|
143
143
|
else
|
144
|
-
|
144
|
+
@logger.debug("Unknown protocol #{@protocol}")
|
145
145
|
raise ProtocolError
|
146
146
|
end
|
147
147
|
end
|
@@ -163,23 +163,11 @@ module CloudwatchToGraphite
|
|
163
163
|
end
|
164
164
|
|
165
165
|
if data_points.length == 0
|
166
|
-
|
166
|
+
logger.debug("No data points!")
|
167
167
|
data_points
|
168
168
|
else
|
169
169
|
data_points = data_points.sort_by {|array| array['Timestamp'] }
|
170
170
|
end
|
171
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
172
|
end
|
185
173
|
end
|
@@ -2,11 +2,11 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe CloudwatchToGraphite::Base do
|
4
4
|
before :each do
|
5
|
-
@base = CloudwatchToGraphite::Base.new 'foo', 'bar', 'us-east-1'
|
5
|
+
@base = CloudwatchToGraphite::Base.new 'foo', 'bar', 'us-east-1'
|
6
6
|
end
|
7
7
|
|
8
8
|
describe ".new" do
|
9
|
-
it "takes
|
9
|
+
it "takes three parameters and returns a CloudwatchToGraphite::Base" do
|
10
10
|
@base.should be_an_instance_of CloudwatchToGraphite::Base
|
11
11
|
end
|
12
12
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudwatchtographite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- S. Zachariah Sprackett
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -75,6 +75,22 @@ dependencies:
|
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: 0.1.3
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: log4r
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.1.10
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.1.10
|
78
94
|
- !ruby/object:Gem::Dependency
|
79
95
|
name: rdoc
|
80
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -220,13 +236,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
220
236
|
version: '0'
|
221
237
|
segments:
|
222
238
|
- 0
|
223
|
-
hash:
|
239
|
+
hash: -2454461472709138499
|
224
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
225
241
|
none: false
|
226
242
|
requirements:
|
227
|
-
- - ! '
|
243
|
+
- - ! '>='
|
228
244
|
- !ruby/object:Gem::Version
|
229
|
-
version:
|
245
|
+
version: '0'
|
230
246
|
requirements: []
|
231
247
|
rubyforge_project:
|
232
248
|
rubygems_version: 1.8.23
|