cloudwatchtographite 0.0.0.pre1 → 0.0.1
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/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
|
+
[](http://badge.fury.io/rb/cloudwatchtographite)
|
13
14
|
[](https://travis-ci.org/zsprackett/cloudwatchtographite)
|
14
15
|
[](https://codeclimate.com/github/zsprackett/cloudwatchtographite)
|
15
16
|
[](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
|