copperegg 0.5.3 → 0.6.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -3
- data/Gemfile.lock +4 -4
- data/README.md +84 -34
- data/copperegg.gemspec +8 -11
- data/lib/copperegg.rb +9 -14
- data/lib/copperegg/api.rb +26 -0
- data/lib/copperegg/custom_dashboard.rb +140 -0
- data/lib/copperegg/metric_group.rb +108 -0
- data/lib/copperegg/metric_sample.rb +22 -0
- data/lib/copperegg/mixins/persistence.rb +106 -0
- data/lib/copperegg/ver.rb +1 -1
- data/test/custom_dashboard_test.rb +139 -0
- data/test/metric_group_test.rb +82 -0
- data/test/metric_sample_test.rb +36 -0
- metadata +73 -48
- data/copperegg-0.5.2.1.gem +0 -0
- data/copperegg-0.5.2.gem +0 -0
- data/copperegg-0.5.3.pre.gem +0 -0
- data/copperegg-0.5.3.pre2.gem +0 -0
- data/examples/example.rb +0 -19
- data/lib/copperegg/metrics.rb +0 -99
- data/lib/copperegg/util.rb +0 -80
- data/lib/test/test_copperegg.rb +0 -0
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
copperegg (0.
|
5
|
-
|
4
|
+
copperegg (0.6.0.pre)
|
5
|
+
json_pure (~> 1.7.6)
|
6
6
|
|
7
7
|
GEM
|
8
|
-
remote:
|
8
|
+
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
10
|
+
json_pure (1.7.6)
|
11
11
|
|
12
12
|
PLATFORMS
|
13
13
|
ruby
|
data/README.md
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
# CopperEgg Gem
|
2
|
-
The CopperEgg gem allows programmatic access to the CopperEgg API.
|
3
2
|
|
4
|
-
|
5
|
-
## Usage
|
6
|
-
|
7
|
-
### Requirements
|
3
|
+
The CopperEgg gem allows programmatic access to the CopperEgg API.
|
8
4
|
|
9
5
|
## Install
|
10
6
|
|
@@ -17,9 +13,8 @@ $ gem install copperegg-ruby
|
|
17
13
|
To build and install the development branch yourself from the latest source:
|
18
14
|
|
19
15
|
```
|
20
|
-
$ git clone git
|
16
|
+
$ git clone git://github.com/CopperEgg/copperegg-ruby.git -b develop
|
21
17
|
$ cd copperegg-ruby
|
22
|
-
$ git checkout develop
|
23
18
|
$ gem build copperegg.gemspec
|
24
19
|
$ gem install copperegg-{version}.gem
|
25
20
|
```
|
@@ -31,49 +26,104 @@ $ gem install copperegg-{version}.gem
|
|
31
26
|
``` ruby
|
32
27
|
require 'rubygems' # not necessary with ruby 1.9 but included for completeness
|
33
28
|
require 'copperegg'
|
34
|
-
|
35
|
-
# Get a Metrics object:
|
36
|
-
apikey = 'sdf87xxxxxxxxxxxxxxxxxxxxx' # from the web UI
|
37
|
-
metrics = CopperEgg::Metrics.new(apikey)
|
29
|
+
CopperEgg::Api.apikey = "sdf87xxxxxxxxxxxxxxxxxxxxx" # from the web UI
|
38
30
|
```
|
39
31
|
|
40
|
-
### Get a
|
32
|
+
### Get a metric group:
|
41
33
|
|
42
34
|
``` ruby
|
43
|
-
|
44
|
-
|
35
|
+
metric_group = CopperEgg::MetricGroup.find("my_metric_group")
|
36
|
+
metric_group.name
|
37
|
+
# => "my_metric_group"
|
38
|
+
metric_group.label
|
39
|
+
# => "My Metric Group"
|
40
|
+
metric_group.metrics
|
41
|
+
# => [#<CopperEgg::MetricGroup::Metric:0x007fb43aab2570 @position=0, @type="ce_gauge", @name="metric1", @label="Metric 1", @unit="b">]
|
45
42
|
```
|
46
43
|
|
47
44
|
### Create a metric group:
|
48
45
|
|
49
46
|
``` ruby
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
{"type"=>"ce_gauge", "name"=>"reading", "unit"=>"Connections"},
|
60
|
-
{"type"=>"ce_gauge", "name"=>"writing", "unit"=>"Connections"},
|
61
|
-
{"type"=>"ce_gauge", "name"=>"waiting", "unit"=>"Connections"}
|
62
|
-
]
|
63
|
-
|
64
|
-
res = metrics.create_metric_group(group_name, groupcfg)
|
47
|
+
metric_group = CopperEgg::MetricGroup.new(:name => "my_new_metric_group", :label => "Cool New Group Visible Name", :frequency => 60) # data is sent every 60 seconds
|
48
|
+
metric_group.metrics << {"type"=>"ce_gauge", "name"=>"active_connections", "unit"=>"Connections"}
|
49
|
+
metric_group.metrics << {"type"=>"ce_gauge", "name"=>"connections_accepts", "unit"=>"Connections"}
|
50
|
+
metric_group.metrics << {"type"=>"ce_gauge", "name"=>"connections_handled", "unit"=>"Connections"}
|
51
|
+
metric_group.metrics << {"type"=>"ce_gauge", "name"=>"connections_requested", "unit"=>"Connections"}
|
52
|
+
metric_group.metrics << {"type"=>"ce_gauge", "name"=>"reading", "unit"=>"Connections"}
|
53
|
+
metric_group.metrics << {"type"=>"ce_gauge", "name"=>"writing", "unit"=>"Connections"}
|
54
|
+
metric_group.metrics << {"type"=>"ce_gauge", "name"=>"waiting", "unit"=>"Connections"}
|
55
|
+
metric_group.save
|
65
56
|
```
|
66
57
|
|
67
|
-
|
58
|
+
### Post samples for a metric group
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
CopperEgg::MetricSample.save(metric_group.name, "custom_identifier1", Time.now.to_i, "active_connections" => 2601, "connections_accepts" => 154, "connections_handled" => 128, "connections_requested" => 1342, ...)
|
62
|
+
```
|
63
|
+
|
64
|
+
### Get samples
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
# Get the most recent samples for a single metric
|
68
|
+
CopperEgg::MetricSample.samples(metric_group.name, "connections_accepts")
|
69
|
+
|
70
|
+
# Get the most recent samples for multiple metrics
|
71
|
+
CopperEgg::MetricSample.samples(metric_group.name, ["connections_accepts", "connections_handled", "reading", "writing"])
|
72
|
+
|
73
|
+
# Specify a start time and duration
|
74
|
+
CopperEgg::MetricSample.samples(metric_group.name, ["connections_accepts", "connections_handled", "reading", "writing"], :starttime => 4.hours.ago, :duration => 15.minutes)
|
75
|
+
```
|
76
|
+
|
77
|
+
The raw JSON response is returned as specified in the [API docs][sample_docs].
|
78
|
+
|
79
|
+
### Create a dashboard from a metric group
|
80
|
+
|
81
|
+
By default, the dashboard created will be named "_MetricGroupLabel_ Dashboard" and will have one timeline widget per metric matching all sources.
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
# Creates a dashboard named "My Metric Group Dashboard"
|
85
|
+
CopperEgg::CustomDashboard.create(metric_group)
|
86
|
+
```
|
68
87
|
|
88
|
+
You can pass an option to specify the name of the dashboard.
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers")
|
92
|
+
```
|
93
|
+
|
94
|
+
If a single identifier is specified, the dashboard will be created having one value widget per metric matching the single identifier.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => "custom_identifier1")
|
98
|
+
```
|
99
|
+
|
100
|
+
If an array of identifiers is specified, the dashboard will be created having one timeline widget per metric matching each identifier.
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => ["custom_identifier1", "custom_identifier2"])
|
104
|
+
```
|
105
|
+
|
106
|
+
You can limit the widgets created by metic.
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => ["custom_identifier1", "custom_identifier2"], :metrics => ["reading", "writing", "waiting"])
|
110
|
+
```
|
111
|
+
|
112
|
+
### Get a dashboard
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
CopperEgg::CustomDashboard.find_by_name("My Metric Group Dashboard")
|
116
|
+
```
|
117
|
+
|
118
|
+
## Questions / Problems?
|
69
119
|
|
70
|
-
There are more detailed examples in the
|
71
|
-
directory.
|
120
|
+
There are more detailed examples in the [test classes][test_classes].
|
72
121
|
|
73
122
|
Full [API docs][docs] are available.
|
74
123
|
|
75
|
-
[
|
124
|
+
[sample_docs]:http://dev.copperegg.com/revealmetrics/samples.html
|
125
|
+
[test_classes]:https://github.com/copperegg/copperegg-ruby/tree/feature/ares/test
|
76
126
|
[docs]:http://dev.copperegg.com
|
77
127
|
|
78
128
|
## Copyright
|
79
|
-
Copyright
|
129
|
+
Copyright 2013 CopperEgg.
|
data/copperegg.gemspec
CHANGED
@@ -1,26 +1,23 @@
|
|
1
1
|
require './lib/copperegg/ver'
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name
|
4
|
+
s.name = 'copperegg'
|
5
5
|
s.version = CopperEgg::GEM_VERSION
|
6
|
-
s.author
|
7
|
-
s.email
|
6
|
+
s.author = 'Eric Anderson'
|
7
|
+
s.email = 'anderson@copperegg.com'
|
8
8
|
|
9
9
|
s.description = 'Library for using the CopperEgg REST API'
|
10
|
-
s.summary
|
11
|
-
s.homepage
|
12
|
-
s.license
|
10
|
+
s.summary = 'Library for using the CopperEgg REST API'
|
11
|
+
s.homepage = 'http://github.com/copperegg/copperegg-ruby'
|
12
|
+
s.license = '???'
|
13
13
|
|
14
14
|
s.platform = Gem::Platform::RUBY
|
15
15
|
s.require_paths = %w[lib]
|
16
16
|
s.files = Dir["#{File.dirname(__FILE__)}/**/*"]
|
17
17
|
s.test_files = Dir.glob("{test,spec,features}/*")
|
18
|
-
s.executables
|
19
|
-
s.add_dependency('multi_json', '>= 1.3.0')
|
20
|
-
#...
|
18
|
+
s.executables = Dir.glob("bin/*")
|
21
19
|
|
22
|
-
|
20
|
+
s.add_dependency('json_pure', '~> 1.7.6')
|
23
21
|
|
24
|
-
#s.extra_rdoc_files = ['README.md', 'LICENSE']
|
25
22
|
s.rdoc_options = ['--line-numbers', '--inline-source', '--title', 'copperegg-ruby', '--main', 'README.md']
|
26
23
|
end
|
data/lib/copperegg.rb
CHANGED
@@ -1,17 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
:ssl_verify_peer => false,
|
11
|
-
#:ssl_ca_file => File.dirname(__FILE__) + '/../../../conf/cacert.pem',
|
12
|
-
:timeout => 10
|
13
|
-
}
|
1
|
+
require "net/http"
|
2
|
+
require "net/https"
|
3
|
+
require "uri"
|
4
|
+
require "json/pure"
|
5
|
+
require File.dirname(__FILE__) + "/copperegg/mixins/persistence"
|
6
|
+
require File.dirname(__FILE__) + "/copperegg/metric_group"
|
7
|
+
require File.dirname(__FILE__) + "/copperegg/custom_dashboard"
|
8
|
+
require File.dirname(__FILE__) + "/copperegg/metric_sample"
|
9
|
+
require File.dirname(__FILE__) + "/copperegg/api"
|
14
10
|
|
15
11
|
module CopperEgg
|
16
|
-
|
17
12
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module CopperEgg
|
2
|
+
class Api
|
3
|
+
class << self
|
4
|
+
attr_accessor :apikey
|
5
|
+
attr_reader :ssl_verify_peer, :timeout
|
6
|
+
|
7
|
+
@uri = "https://api.copperegg.com/v2/revealmetrics/"
|
8
|
+
|
9
|
+
def host=(host)
|
10
|
+
@uri = "#{host}/v2/revealmetrics/"
|
11
|
+
end
|
12
|
+
|
13
|
+
def uri
|
14
|
+
@uri
|
15
|
+
end
|
16
|
+
|
17
|
+
def ssl_verify_peer=(boolean)
|
18
|
+
@ssl_verify_peer = boolean ? true : false
|
19
|
+
end
|
20
|
+
|
21
|
+
def timeout=(seconds)
|
22
|
+
@timeout = seconds.to_i
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module CopperEgg
|
2
|
+
class CustomDashboard
|
3
|
+
include CopperEgg::Mixins::Persistence
|
4
|
+
|
5
|
+
WIDGET_TYPES = %w(metric metric_list timeline)
|
6
|
+
WIDGET_STYLES = %w(value timeline both list values)
|
7
|
+
WIDGET_MATCHES = %w(select multi tag all)
|
8
|
+
|
9
|
+
resource "dashboards"
|
10
|
+
|
11
|
+
attr_accessor :name, :label, :data
|
12
|
+
|
13
|
+
def initialize(attributes={})
|
14
|
+
load_attributes(attributes)
|
15
|
+
end
|
16
|
+
|
17
|
+
def load_attributes(attributes)
|
18
|
+
@data = {"widgets" => {}, "order" => []}
|
19
|
+
attributes.each do |name, value|
|
20
|
+
if name.to_s == "id"
|
21
|
+
@id = value
|
22
|
+
elsif name.to_s == "data"
|
23
|
+
attributes[name].each do |data_name, data_value|
|
24
|
+
if data_name.to_s == "order"
|
25
|
+
data["order"] = data_value
|
26
|
+
else
|
27
|
+
data["widgets"] = data_value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
elsif !respond_to?("#{name}=")
|
31
|
+
next
|
32
|
+
else
|
33
|
+
send "#{name}=", value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def valid?
|
39
|
+
@error = nil
|
40
|
+
if self.name.nil? || self.name.to_s.strip.empty?
|
41
|
+
@error = "Name can't be blank."
|
42
|
+
else
|
43
|
+
self.data["widgets"].values.each do |widget|
|
44
|
+
widget.each do |key, value|
|
45
|
+
if key.to_s == "type" && !WIDGET_TYPES.include?(value)
|
46
|
+
@error = "Invalid widget type #{value}."
|
47
|
+
elsif key.to_s == "style" && !WIDGET_STYLES.include?(value)
|
48
|
+
@error = "Invalid widget style #{value}."
|
49
|
+
elsif key.to_s == "match" && !WIDGET_MATCHES.include?(value)
|
50
|
+
@error = "Invalid widget match #{value}."
|
51
|
+
elsif key.to_s == "metric" && (!value.is_a?(Hash) || value.keys.size == 0)
|
52
|
+
@error = "Invalid widget metric. #{value}"
|
53
|
+
elsif key.to_s == "match_param" && (widget["match"] || widget[:match]) != "all" && (value.nil? || value.to_s.strip.empty?)
|
54
|
+
@error = "Missing match parameter."
|
55
|
+
else
|
56
|
+
(widget["metric"] || widget[:metric]).each do |metric_group_name, metric_group_value|
|
57
|
+
if !metric_group_value.is_a?(Array)
|
58
|
+
@error = "Invalid widget metric. #{metric_group_value}"
|
59
|
+
elsif metric_group_value.length == 0
|
60
|
+
@error = "Invalid widget metric. #{metric_group_value}"
|
61
|
+
else
|
62
|
+
metric_group_value.each do |metric_data|
|
63
|
+
if !metric_data.is_a?(Array)
|
64
|
+
@error = "Invalid widget metric. #{metric_group_value}"
|
65
|
+
elsif metric_data.length < 2
|
66
|
+
@error = "Invalid widget metric. #{metric_group_value}"
|
67
|
+
elsif (/^\d+$/ =~ metric_data.first.to_s).nil?
|
68
|
+
@error = "Invalid widget metric. #{metric_group_value}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
break if !@error.nil?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
@error.nil?
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_hash
|
82
|
+
set_data_order
|
83
|
+
self.instance_variables.reduce({}) do |memo, variable|
|
84
|
+
unless variable.to_s == "@error"
|
85
|
+
value = instance_variable_get(variable)
|
86
|
+
memo[variable.to_s.sub("@","")] = value
|
87
|
+
end
|
88
|
+
memo
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class <<self
|
93
|
+
def create(*args)
|
94
|
+
options = args.last.class == Hash ? args.pop : {}
|
95
|
+
|
96
|
+
return super(args.first) if args.first.is_a?(Hash)
|
97
|
+
|
98
|
+
metric_group = args.first
|
99
|
+
raise ArgumentError.new("CopperEgg::MetricGroup object expected") if !metric_group.is_a?(MetricGroup)
|
100
|
+
raise ArgumentError.new("Invalid metric group") if !metric_group.valid?
|
101
|
+
|
102
|
+
metrics = filter_metrics(metric_group, options[:metrics]).map { |name| metric_group.metrics.find {|metric| metric.name == name} }
|
103
|
+
identifiers = options[:identifiers].is_a?(Array) ? (options[:identifiers].empty? ? nil : options[:identifiers]) : (options[:identifier] ? [options[:identifiers]] : nil)
|
104
|
+
widget_match = identifiers.nil? ? "all" : (identifiers.size == 1 ? "select" : "multi")
|
105
|
+
widget_type = widget_match == "select" ? "metric" : "timeline"
|
106
|
+
widget_style = widget_type == "metric" ? "both" : "values"
|
107
|
+
name = options[:name] || "#{metric_group.label} Dashboard"
|
108
|
+
|
109
|
+
dashboard = new(:name => name)
|
110
|
+
metrics.each.with_index do |metric, i|
|
111
|
+
metric_data = [metric.position, metric.name]
|
112
|
+
metric_data.push("rate") if metric.type == "ce_counter" || metric.type == "ce_counter_f"
|
113
|
+
widget = {:type => widget_type, :style => widget_style, :match => widget_match, :metric => {metric_group.name => [metric_data]}}
|
114
|
+
widget[:match_param] = identifiers if identifiers
|
115
|
+
dashboard.data["widgets"][i.to_s] = widget
|
116
|
+
end
|
117
|
+
dashboard.save
|
118
|
+
dashboard
|
119
|
+
end
|
120
|
+
|
121
|
+
def find_by_name(name)
|
122
|
+
find.detect {|dashboard| dashboard.name == name}
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def filter_metrics(metric_group, specified_metrics)
|
128
|
+
metrics = metric_group.metrics.map(&:name)
|
129
|
+
specified_metrics = specified_metrics.is_a?(Array) ? specified_metrics & metrics : (specified_metrics ? [specified_metrics] & metrics : [])
|
130
|
+
specified_metrics.empty? ? metrics : specified_metrics
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def set_data_order
|
137
|
+
@data["order"] = @data["widgets"].keys if @data["order"].empty?
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module CopperEgg
|
2
|
+
class MetricGroup
|
3
|
+
include CopperEgg::Mixins::Persistence
|
4
|
+
|
5
|
+
resource "metric_groups"
|
6
|
+
|
7
|
+
attr_accessor :name, :label, :frequency, :metrics
|
8
|
+
|
9
|
+
def initialize(attributes={})
|
10
|
+
load_attributes(attributes)
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_attributes(attributes)
|
14
|
+
@metrics = []
|
15
|
+
attributes.each do |name, value|
|
16
|
+
if name.to_s == "id"
|
17
|
+
@id = value
|
18
|
+
elsif !respond_to?("#{name}=")
|
19
|
+
next
|
20
|
+
elsif value.to_s == "metrics"
|
21
|
+
@metrics = value.map {|v| Metric.new(v)}
|
22
|
+
else
|
23
|
+
send "#{name}=", value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_hash
|
29
|
+
self.instance_variables.reduce({}) do |memo, variable|
|
30
|
+
value = instance_variable_get(variable)
|
31
|
+
if variable.to_s == "@metrics"
|
32
|
+
memo[variable.to_s.sub("@","")] = value.map(&:to_hash)
|
33
|
+
elsif variable.to_s != "@error"
|
34
|
+
memo[variable.to_s.sub("@","")] = value
|
35
|
+
end
|
36
|
+
memo
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def valid?
|
41
|
+
@error = nil
|
42
|
+
if self.name.nil? || self.name.to_s.strip.empty?
|
43
|
+
@error = "Name can't be blank."
|
44
|
+
elsif self.metrics.nil? || self.metrics.empty?
|
45
|
+
@error = "You must define at least one metric."
|
46
|
+
else
|
47
|
+
self.metrics = self.metrics.map {|metric| metric.is_a?(Hash) ? Metric.new(metric) : metric}
|
48
|
+
self.metrics.each do |metric|
|
49
|
+
if !metric.is_a?(Metric)
|
50
|
+
@error = "Metric expected."
|
51
|
+
break
|
52
|
+
elsif !metric.valid?
|
53
|
+
@error = metric.error
|
54
|
+
break
|
55
|
+
else
|
56
|
+
metric.send(:remove_instance_variable, :@position) if (metric.instance_variables.include?(:@position) || metric.instance_variables.include?("@position")) && !self.persisted?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
@error.nil?
|
61
|
+
end
|
62
|
+
|
63
|
+
class Metric
|
64
|
+
TYPES = %w(ce_gauge ce_gauge_f ce_counter ce_counter_f)
|
65
|
+
|
66
|
+
attr_accessor :name, :label, :type, :unit
|
67
|
+
attr_reader :error, :position
|
68
|
+
|
69
|
+
def initialize(attributes={})
|
70
|
+
attributes.each do |name, value|
|
71
|
+
if name.to_s == "position"
|
72
|
+
@position = value
|
73
|
+
elsif !respond_to?("#{name}=")
|
74
|
+
next
|
75
|
+
else
|
76
|
+
send "#{name}=", value
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_hash
|
82
|
+
self.instance_variables.reduce({}) do |memo, variable|
|
83
|
+
if variable.to_s != "@error"
|
84
|
+
value = instance_variable_get(variable)
|
85
|
+
memo[variable.to_s.sub("@","")] = value
|
86
|
+
end
|
87
|
+
memo
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def valid?
|
92
|
+
valid = false
|
93
|
+
@error = nil
|
94
|
+
if self.name.nil? || self.name.to_s.strip.empty?
|
95
|
+
@error = "Metric name cannot be blank."
|
96
|
+
elsif self.type.nil? || self.type.to_s.strip.empty?
|
97
|
+
@error = "Metric type must be defined."
|
98
|
+
elsif !TYPES.include?(self.type)
|
99
|
+
return "Invalid metric type #{self.type}."
|
100
|
+
else
|
101
|
+
valid = true
|
102
|
+
remove_instance_variable(:@error)
|
103
|
+
end
|
104
|
+
valid
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module CopperEgg
|
2
|
+
class MetricSample
|
3
|
+
include CopperEgg::Mixins::Persistence
|
4
|
+
|
5
|
+
resource "samples"
|
6
|
+
|
7
|
+
def self.save(group_name, identifier, timestamp, metric_values)
|
8
|
+
request(:id => group_name, :identifier => identifier, :timestamp => timestamp, :values => metric_values, :request_type => "post")
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.samples(group_name, metrics, starttime=nil, duration=nil, sample_size=nil)
|
12
|
+
metrics = [metrics] unless metrics.is_a?(Array)
|
13
|
+
params = {}
|
14
|
+
params[:starttime] = starttime if starttime
|
15
|
+
params[:duration] = duration if duration
|
16
|
+
params[:sample_size] = sample_size if sample_size
|
17
|
+
params[:queries] = {group_name => [{:metrics => metrics}]}
|
18
|
+
|
19
|
+
request(params.merge(:request_type => "get"))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module CopperEgg
|
2
|
+
class ValidationError < Exception; end
|
3
|
+
|
4
|
+
module Mixins
|
5
|
+
module Persistence
|
6
|
+
def self.included(klass)
|
7
|
+
klass.class_eval do
|
8
|
+
class << self
|
9
|
+
attr_reader :resource_name
|
10
|
+
|
11
|
+
def find(*args)
|
12
|
+
params = args.last.class == Hash ? args.pop : {}
|
13
|
+
id = args.first
|
14
|
+
response = request(params.merge(:request_type => "get", :id => id))
|
15
|
+
if response && response.is_a?(Array)
|
16
|
+
response.map {|resp| new(resp)}
|
17
|
+
elsif response
|
18
|
+
new(response)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def create(params)
|
23
|
+
params.delete(:id)
|
24
|
+
params.delete("id")
|
25
|
+
new(params).save
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete(id)
|
29
|
+
request(:id => id, :request_type => "delete")
|
30
|
+
end
|
31
|
+
|
32
|
+
def request(params={})
|
33
|
+
request_type = params.delete(:request_type)
|
34
|
+
raise "invalid type" if !%w(get post put delete).include?(request_type)
|
35
|
+
id = params.delete(:id)
|
36
|
+
|
37
|
+
uri = id ? URI.parse("#{Api.uri}/#{self.resource_name}/#{id}.json") : URI.parse("#{Api.uri}/#{self.resource_name}.json")
|
38
|
+
|
39
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
40
|
+
http.use_ssl = uri.scheme == 'https'
|
41
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if !Api.ssl_verify_peer
|
42
|
+
|
43
|
+
request = Net::HTTP.const_get(request_type.capitalize).new(uri.request_uri)
|
44
|
+
request.body = JSON.generate(params) unless params.empty?
|
45
|
+
request.basic_auth(Api.apikey, "U")
|
46
|
+
request["Content-Type"] = "application/json"
|
47
|
+
|
48
|
+
connect_try_count = 0
|
49
|
+
response = nil
|
50
|
+
begin
|
51
|
+
response = http.request(request)
|
52
|
+
rescue Exception => e
|
53
|
+
connect_try_count += 1
|
54
|
+
if connect_try_count > 1
|
55
|
+
log "#{e.inspect}"
|
56
|
+
raise e
|
57
|
+
end
|
58
|
+
sleep 0.5
|
59
|
+
retry
|
60
|
+
end
|
61
|
+
|
62
|
+
return nil if response.nil? || response.code != "200" || response.body.nil? || response.body.strip.empty?
|
63
|
+
|
64
|
+
JSON.parse(response.body)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def resource(value)
|
70
|
+
@resource_name = value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
attr_reader :id
|
77
|
+
|
78
|
+
def save
|
79
|
+
if valid?
|
80
|
+
attributes = persisted? ? update : create
|
81
|
+
load_attributes(attributes)
|
82
|
+
else
|
83
|
+
raise ValidationError.new(@error)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete
|
88
|
+
self.class.request(:id => @id, :request_type => "delete")
|
89
|
+
end
|
90
|
+
|
91
|
+
def persisted?
|
92
|
+
!@id.nil?
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def create
|
98
|
+
self.class.request(to_hash.merge(:request_type => "post"))
|
99
|
+
end
|
100
|
+
|
101
|
+
def update
|
102
|
+
self.class.request(to_hash.merge(:id => @id, :request_type => "put"))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/copperegg/ver.rb
CHANGED
@@ -0,0 +1,139 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "copperegg"
|
3
|
+
|
4
|
+
class CustomDashboardTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_name_accessor_and_setter
|
7
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
8
|
+
|
9
|
+
assert_equal "My Dashboard", dashboard.name
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_save_should_fail_if_name_is_not_set
|
13
|
+
dashboard = CopperEgg::CustomDashboard.new
|
14
|
+
|
15
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
16
|
+
assert_equal "Name can't be blank.", error.message
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_save_should_fail_for_an_invalid_widget_type
|
20
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
21
|
+
dashboard.data.widgets["0"] = {:type => "foo", :style => "value", :match => "tag", :match_param => ["test"],
|
22
|
+
:metric => {"my_metric_group" => [[0, "metric1"]]}}
|
23
|
+
|
24
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
25
|
+
assert_equal "Invalid widget type foo.", error.message
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_save_should_fail_for_an_invalid_widget_style
|
29
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
30
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "foo", :match => "tag", :match_param => ["test"],
|
31
|
+
:metric => {"my_metric_group" => [[0, "metric1"]]}}
|
32
|
+
|
33
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
34
|
+
assert_equal "Invalid widget style foo.", error.message
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_save_should_ail_for_an_invalidvwidget_match
|
38
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
39
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "foo", :match_param => ["test"],
|
40
|
+
:metric => {"my_metric_group" => [[0, "metric1"]]}}
|
41
|
+
|
42
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
43
|
+
assert_equal "Invalid widget match foo.", error.message
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_save_should_fail_for_a_missing_match_parameter
|
47
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
48
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "select", :metric => {"my_metric_group" => [[0, "metric1"]]}}
|
49
|
+
|
50
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
51
|
+
assert_equal "Missing match parameter.", error.message
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_save_should_fail_if_metric_is_not_a_hash
|
55
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
56
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => ["my_metric_group", 0, "metric1"]}
|
57
|
+
|
58
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
59
|
+
assert_equal "Invalid widget metric.", error.message
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_save_should_fail_if_metric_does_not_contain_an_array
|
63
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
64
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => "metric1"}}
|
65
|
+
|
66
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
67
|
+
assert_equal "Invalid widget metric.", error.message
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_save_should_fail_if_metric_contains_an_empty_array
|
71
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
72
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => []}}
|
73
|
+
|
74
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
75
|
+
assert_equal "Invalid widget metric.", error.message
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_save_should_fail_if_metric_contains_an_array_with_invalid_values
|
79
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
80
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => ["metric1"]}}
|
81
|
+
|
82
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
83
|
+
assert_equal "Invalid widget metric.", error.message
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_save_should_fail_if_metric_contains_an_array_with_an_invalid_position
|
87
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
88
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [["four", "metric1"]]}}
|
89
|
+
|
90
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
91
|
+
assert_equal "Invalid widget metric.", error.message
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_save_should_fail_if_metric_contains_an_array_with_no_metric_name
|
95
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
96
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [[0]]}}
|
97
|
+
|
98
|
+
error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
|
99
|
+
assert_equal "Invalid widget metric.", error.message
|
100
|
+
end
|
101
|
+
|
102
|
+
# def test_save_should_save_a_valid_dashboard
|
103
|
+
# CopperEgg::Api.apikey = "testapikey"
|
104
|
+
|
105
|
+
# request_headers = {
|
106
|
+
# 'Authorization' => "Basic #{Base64.encode64("testapikey:").gsub("\n",'')}",
|
107
|
+
# 'Content-Type' => 'application/json'
|
108
|
+
# }
|
109
|
+
|
110
|
+
# response_body = {:id => 1, :name => "My Dashboard", :data => {:widgets => [{:type => "metric", :style => "value", :match => "tag", :match_param => ["test"]}]},
|
111
|
+
# :order => ["0"]}
|
112
|
+
|
113
|
+
# ActiveResource::HttpMock.respond_to do |mock|
|
114
|
+
# mock.post "/v2/revealmetrics/dashboards.json", request_headers, {}, 200
|
115
|
+
# end
|
116
|
+
|
117
|
+
# dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
118
|
+
# dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [[1, "metric1"]]}}
|
119
|
+
|
120
|
+
# assert dashboard.save
|
121
|
+
# end
|
122
|
+
|
123
|
+
def test_to_hash
|
124
|
+
dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
|
125
|
+
dashboard.data.widgets["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [[1, "metric1"]]}}
|
126
|
+
|
127
|
+
assert dashboard.valid?
|
128
|
+
|
129
|
+
hash = dashboard.to_hash
|
130
|
+
|
131
|
+
assert_equal "My Dashboard", hash["name"]
|
132
|
+
assert_equal "metric", hash["data"]["widgets"]["0"]["type"]
|
133
|
+
assert_equal "value", hash["data"]["widgets"]["0"]["style"]
|
134
|
+
assert_equal "tag", hash["data"]["widgets"]["0"]["match"]
|
135
|
+
assert_equal ["test"], hash["data"]["widgets"]["0"]["match_param"]
|
136
|
+
assert_equal [[1, "metric1"]], hash["data"]["widgets"]["0"]["metric"]["my_metric_group"]
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "copperegg"
|
3
|
+
|
4
|
+
class MetricGroupTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_name_accessor_and_setter
|
7
|
+
metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group")
|
8
|
+
|
9
|
+
assert_equal "my_metric_group", metric_group.name
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_save_should_fail_if_name_is_blank
|
13
|
+
metric_group = CopperEgg::MetricGroup.new
|
14
|
+
|
15
|
+
error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
|
16
|
+
assert_equal "Name can't be blank.", error.message
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_save_should_fail_if_no_metrics_are_declared
|
20
|
+
metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group")
|
21
|
+
|
22
|
+
error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
|
23
|
+
assert_equal "You must define at least one metric.", error.message
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_save_should_fail_if_metrics_include_non_metric
|
27
|
+
metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group", :metrics => ["metric"])
|
28
|
+
|
29
|
+
error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
|
30
|
+
assert_equal "Metric expected.", error.message
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_save_should_fail_for_invalid_metrics
|
34
|
+
metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group", :metrics => [{:name => "test", :type => "invalid"}])
|
35
|
+
|
36
|
+
error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
|
37
|
+
assert_equal "Invalid metric type invalid.", error.message
|
38
|
+
end
|
39
|
+
|
40
|
+
# def test_save_should_retrieve_versioned_name_of_metric_group
|
41
|
+
# CopperEgg::Api.apikey = "testapikey"
|
42
|
+
|
43
|
+
# request_headers = {
|
44
|
+
# 'Authorization' => "Basic #{Base64.encode64("testapikey:").gsub("\n",'')}",
|
45
|
+
# 'Content-Type' => 'application/json'
|
46
|
+
# }
|
47
|
+
# response_body = {:id => "test_v2", :name => "test_v2", :label => "Test", :frequency => 5, :metrics => [{:name => "test", :type => "ce_counter", :position => 0}]}
|
48
|
+
|
49
|
+
# ActiveResource::HttpMock.respond_to do |mock|
|
50
|
+
# mock.post "/v2/revealmetrics/metric_groups.json", request_headers, response_body.to_json, 200
|
51
|
+
# end
|
52
|
+
|
53
|
+
# metric_group = CopperEgg::MetricGroup.new(:name => "test", :frequency => 5, :metrics => [{:name => "test", :type => "ce_counter"}])
|
54
|
+
|
55
|
+
# metric_group.save
|
56
|
+
|
57
|
+
# assert_equal "test_v2", metric_group.id
|
58
|
+
# assert_equal "test_v2", metric_group.name
|
59
|
+
# end
|
60
|
+
|
61
|
+
def test_to_hash
|
62
|
+
metric_group = CopperEgg::MetricGroup.new(:name => "test", :label => "Test Metric", :frequency => 5)
|
63
|
+
metric_group.metrics << {:type => "ce_counter", :name => "metric1", :label => "Metric 1", :unit => "ticks"}
|
64
|
+
metric_group.metrics << {:type => "ce_counter_f", :name => "metric2", :label => "Metric 2"}
|
65
|
+
|
66
|
+
assert metric_group.valid?
|
67
|
+
hash = metric_group.to_hash
|
68
|
+
|
69
|
+
assert_nil hash["id"]
|
70
|
+
assert_equal "test", hash["name"]
|
71
|
+
assert_equal "Test Metric", hash["label"]
|
72
|
+
assert_equal 5, hash["frequency"]
|
73
|
+
assert_equal "ce_counter", hash["metrics"].first["type"]
|
74
|
+
assert_equal "metric1", hash["metrics"].first["name"]
|
75
|
+
assert_equal "Metric 1", hash["metrics"].first["label"]
|
76
|
+
assert_equal "ticks", hash["metrics"].first["unit"]
|
77
|
+
assert_equal "ce_counter_f", hash["metrics"].last["type"]
|
78
|
+
assert_equal "metric2", hash["metrics"].last["name"]
|
79
|
+
assert_equal "Metric 2", hash["metrics"].last["label"]
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "copperegg"
|
3
|
+
|
4
|
+
class MetricSampleTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
# def test_save_should_post_a_sample
|
7
|
+
# CopperEgg::Api.apikey = "testapikey"
|
8
|
+
# request_headers = {
|
9
|
+
# 'Authorization' => "Basic #{Base64.encode64("testapikey:").gsub("\n",'')}",
|
10
|
+
# 'Content-Type' => 'application/json'
|
11
|
+
# }
|
12
|
+
|
13
|
+
# ActiveResource::HttpMock.respond_to do |mock|
|
14
|
+
# mock.post "/v2/revealmetrics/samples//test.json", request_headers, {}, 200
|
15
|
+
# end
|
16
|
+
|
17
|
+
# CopperEgg::MetricSample.save("test", "custom_object", Time.now.to_i, :key1 => "value1", :key2 => "value2")
|
18
|
+
# end
|
19
|
+
|
20
|
+
# def test_samples_should_return_the_json_response_body_upon_success
|
21
|
+
# CopperEgg::Api.apikey = "testapikey"
|
22
|
+
# request_headers = {
|
23
|
+
# 'Authorization' => "Basic #{Base64.encode64("testapikey:").gsub("\n",'')}",
|
24
|
+
# 'Accept' => 'application/json'
|
25
|
+
# }
|
26
|
+
|
27
|
+
# ActiveResource::HttpMock.respond_to do |mock|
|
28
|
+
# queries = {"queries" => {"metric_group" => [{"metrics" => ["metric1"]}]}}.to_param
|
29
|
+
|
30
|
+
# mock.get "/v2/revealmetrics/samples.json?#{queries}", request_headers, {"_ts" => Time.now.to_i, "object_count" => 0, "values" => {"metric_group" => []}}.to_json, 200
|
31
|
+
# end
|
32
|
+
|
33
|
+
# CopperEgg::MetricSample.samples("metric_group", "metric1")
|
34
|
+
# end
|
35
|
+
|
36
|
+
end
|
metadata
CHANGED
@@ -1,83 +1,108 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: copperegg
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: -764821022
|
5
|
+
prerelease: 6
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 6
|
9
|
+
- 0
|
10
|
+
- pre
|
11
|
+
version: 0.6.0.pre
|
6
12
|
platform: ruby
|
7
|
-
authors:
|
13
|
+
authors:
|
8
14
|
- Eric Anderson
|
9
15
|
autorequire:
|
10
16
|
bindir: bin
|
11
17
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: 1.3.0
|
22
|
-
type: :runtime
|
18
|
+
|
19
|
+
date: 2013-01-03 00:00:00 Z
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: json_pure
|
23
23
|
prerelease: false
|
24
|
-
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 7
|
33
|
+
- 6
|
34
|
+
version: 1.7.6
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
30
37
|
description: Library for using the CopperEgg REST API
|
31
38
|
email: anderson@copperegg.com
|
32
39
|
executables: []
|
40
|
+
|
33
41
|
extensions: []
|
42
|
+
|
34
43
|
extra_rdoc_files: []
|
35
|
-
|
44
|
+
|
45
|
+
files:
|
46
|
+
- ./copperegg.gemspec
|
36
47
|
- ./Gemfile
|
37
48
|
- ./Gemfile.lock
|
38
|
-
- ./
|
39
|
-
- ./
|
40
|
-
- ./
|
41
|
-
- ./copperegg
|
42
|
-
- ./copperegg
|
43
|
-
- ./copperegg-0.5.3.pre.gem
|
44
|
-
- ./copperegg-0.5.3.pre2.gem
|
45
|
-
- ./copperegg.gemspec
|
46
|
-
- ./examples/example.rb
|
47
|
-
- ./lib/copperegg/metrics.rb
|
48
|
-
- ./lib/copperegg/util.rb
|
49
|
+
- ./lib/copperegg/api.rb
|
50
|
+
- ./lib/copperegg/custom_dashboard.rb
|
51
|
+
- ./lib/copperegg/metric_group.rb
|
52
|
+
- ./lib/copperegg/metric_sample.rb
|
53
|
+
- ./lib/copperegg/mixins/persistence.rb
|
49
54
|
- ./lib/copperegg/ver.rb
|
50
55
|
- ./lib/copperegg.rb
|
51
|
-
- ./
|
56
|
+
- ./LICENSE
|
57
|
+
- ./Rakefile
|
58
|
+
- ./README.md
|
59
|
+
- ./test/custom_dashboard_test.rb
|
60
|
+
- ./test/metric_group_test.rb
|
61
|
+
- ./test/metric_sample_test.rb
|
62
|
+
- test/custom_dashboard_test.rb
|
63
|
+
- test/metric_group_test.rb
|
64
|
+
- test/metric_sample_test.rb
|
52
65
|
homepage: http://github.com/copperegg/copperegg-ruby
|
53
|
-
licenses:
|
66
|
+
licenses:
|
54
67
|
- ???
|
55
68
|
post_install_message:
|
56
|
-
rdoc_options:
|
69
|
+
rdoc_options:
|
57
70
|
- --line-numbers
|
58
71
|
- --inline-source
|
59
72
|
- --title
|
60
73
|
- copperegg-ruby
|
61
74
|
- --main
|
62
75
|
- README.md
|
63
|
-
require_paths:
|
76
|
+
require_paths:
|
64
77
|
- lib
|
65
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
79
|
none: false
|
67
|
-
requirements:
|
68
|
-
- -
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
|
71
|
-
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
88
|
none: false
|
73
|
-
requirements:
|
74
|
-
- -
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
|
89
|
+
requirements:
|
90
|
+
- - ">"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 25
|
93
|
+
segments:
|
94
|
+
- 1
|
95
|
+
- 3
|
96
|
+
- 1
|
97
|
+
version: 1.3.1
|
77
98
|
requirements: []
|
99
|
+
|
78
100
|
rubyforge_project:
|
79
101
|
rubygems_version: 1.8.24
|
80
102
|
signing_key:
|
81
103
|
specification_version: 3
|
82
104
|
summary: Library for using the CopperEgg REST API
|
83
|
-
test_files:
|
105
|
+
test_files:
|
106
|
+
- test/custom_dashboard_test.rb
|
107
|
+
- test/metric_group_test.rb
|
108
|
+
- test/metric_sample_test.rb
|
data/copperegg-0.5.2.1.gem
DELETED
Binary file
|
data/copperegg-0.5.2.gem
DELETED
Binary file
|
data/copperegg-0.5.3.pre.gem
DELETED
Binary file
|
data/copperegg-0.5.3.pre2.gem
DELETED
Binary file
|
data/examples/example.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'copperegg'
|
4
|
-
require 'redis'
|
5
|
-
require 'getoptlong'
|
6
|
-
|
7
|
-
apikey = "asdadasdasd"
|
8
|
-
|
9
|
-
rm = CopperEgg::Metrics.new(apikey)
|
10
|
-
|
11
|
-
puts rm.apikey
|
12
|
-
|
13
|
-
metrics = {}
|
14
|
-
time = Time.now.to_i
|
15
|
-
|
16
|
-
rm.store(metrics, time, "my_group_name")
|
17
|
-
|
18
|
-
data = rm.samples(time-300, time, "my_group_name", "metric_foo")
|
19
|
-
|
data/lib/copperegg/metrics.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
module CopperEgg
|
2
|
-
class Metrics
|
3
|
-
|
4
|
-
attr_accessor :apikey
|
5
|
-
|
6
|
-
def initialize(apikey, apihost=nil)
|
7
|
-
@apikey = apikey
|
8
|
-
@util = CopperEgg::Util.new(@apikey, "revealmetrics", apihost)
|
9
|
-
end
|
10
|
-
|
11
|
-
def store_sample(group_name, identifier, timestamp, metric_data)
|
12
|
-
return if identifier.nil?
|
13
|
-
return if group_name.nil?
|
14
|
-
return if timestamp.nil? || timestamp == 0
|
15
|
-
return if metric_data.nil?
|
16
|
-
|
17
|
-
payload = {}
|
18
|
-
payload["timestamp"] = timestamp
|
19
|
-
payload["identifier"] = identifier
|
20
|
-
payload["values"] = metric_data
|
21
|
-
|
22
|
-
response = @util.make_api_post_request("/samples/#{group_name}.json", @apikey, payload)
|
23
|
-
return
|
24
|
-
end
|
25
|
-
|
26
|
-
def samples(group_name, metricname, starttime=nil, duration=nil, sample_size=nil)
|
27
|
-
return if group_name.nil?
|
28
|
-
return if metricname.nil?
|
29
|
-
|
30
|
-
metric_name = []
|
31
|
-
metrics = {}
|
32
|
-
metric_gid = []
|
33
|
-
query = {}
|
34
|
-
params = {}
|
35
|
-
|
36
|
-
metric_name = [metricname]
|
37
|
-
metrics["metrics"] = metric_name
|
38
|
-
metric_gid = [metrics]
|
39
|
-
query[group_name] = metric_gid
|
40
|
-
params["queries"] = query
|
41
|
-
params["starttime"] = starttime if !starttime.nil?
|
42
|
-
params["duration"] = duration if !duration.nil?
|
43
|
-
params["sample_size"] = sample_size if !sample_size.nil?
|
44
|
-
|
45
|
-
samples = @util.make_api_get_request("/samples.json", @apikey, params)
|
46
|
-
return samples
|
47
|
-
end
|
48
|
-
|
49
|
-
def metric_groups
|
50
|
-
# return an array of metric groups
|
51
|
-
mgroup = @util.make_api_get_request("/metric_groups.json", @apikey, nil)
|
52
|
-
return mgroup
|
53
|
-
end
|
54
|
-
|
55
|
-
def metric_group(group_name)
|
56
|
-
mgroup = @util.make_api_get_request("/metric_groups/#{group_name}.json", @apikey, nil)
|
57
|
-
return mgroup
|
58
|
-
end
|
59
|
-
|
60
|
-
def metric_names(group_name)
|
61
|
-
# return an array of metric names in a metric group
|
62
|
-
mgroup = self.metric_group(group_name)
|
63
|
-
if !mgroup.nil?
|
64
|
-
# go through each and add to array
|
65
|
-
|
66
|
-
|
67
|
-
end
|
68
|
-
puts "NOT YET IMPLEMENTED"
|
69
|
-
end
|
70
|
-
|
71
|
-
def create_metric_group(group_name, group_definition)
|
72
|
-
response = @util.make_api_post_request("/metric_groups.json", @apikey, group_definition)
|
73
|
-
end
|
74
|
-
|
75
|
-
def dashboard(dashboard_name)
|
76
|
-
dashes = @util.make_api_get_request("/dashboards.json", @apikey, nil)
|
77
|
-
return nil if dashes.nil?
|
78
|
-
|
79
|
-
# dashboards = JSON.parse(dashes.body)
|
80
|
-
# modified 12-10-2012 ... get returns the body
|
81
|
-
dashboards = JSON.parse(dashes)
|
82
|
-
dashboards.each do |dash|
|
83
|
-
if dash["name"] == dashboard_name
|
84
|
-
return dash
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
return nil
|
89
|
-
end
|
90
|
-
|
91
|
-
def create_dashboard(dashcfg)
|
92
|
-
response = @util.make_api_post_request("/dashboards.json", @apikey, dashcfg)
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
|
98
|
-
end
|
99
|
-
end
|
data/lib/copperegg/util.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
|
3
|
-
module CopperEgg
|
4
|
-
class Util
|
5
|
-
|
6
|
-
attr_accessor :apikey
|
7
|
-
|
8
|
-
def initialize(apikey, product, apihost=nil)
|
9
|
-
@apikey = apikey
|
10
|
-
@product = product
|
11
|
-
if apihost
|
12
|
-
@apihost = apihost
|
13
|
-
else
|
14
|
-
@apihost = DEFAULTS[:apihost]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def make_api_get_request(api_cmd, apikey, params)
|
19
|
-
response = make_api_request("get", api_cmd, apikey, params)
|
20
|
-
return response
|
21
|
-
end
|
22
|
-
|
23
|
-
def make_api_post_request(api_cmd, apikey, body)
|
24
|
-
response = make_api_request("post", api_cmd, apikey, body)
|
25
|
-
return response
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def make_uri(api_cmd)
|
31
|
-
return URI.parse("#{@apihost}/#{API_VERSION}/#{@product}#{api_cmd}")
|
32
|
-
end
|
33
|
-
|
34
|
-
def make_api_request(type, api_cmd, apikey, params)
|
35
|
-
request = nil
|
36
|
-
uri = make_uri(api_cmd)
|
37
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
38
|
-
|
39
|
-
http.use_ssl = uri.scheme == 'https'
|
40
|
-
if !DEFAULTS[:ssl_verify_peer]
|
41
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
42
|
-
end
|
43
|
-
|
44
|
-
if type == "get"
|
45
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
46
|
-
request.body = MultiJson.dump(params)
|
47
|
-
else
|
48
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
49
|
-
request.body = MultiJson.dump(params)
|
50
|
-
end
|
51
|
-
|
52
|
-
request.basic_auth(apikey, "U")
|
53
|
-
request["Content-Type"] = "application/json"
|
54
|
-
|
55
|
-
connect_try_count = 0
|
56
|
-
response = nil
|
57
|
-
begin
|
58
|
-
response = http.request(request)
|
59
|
-
rescue Exception => e
|
60
|
-
connect_try_count += 1
|
61
|
-
if connect_try_count > 1
|
62
|
-
log "#{e.inspect}"
|
63
|
-
raise e
|
64
|
-
end
|
65
|
-
sleep 0.5
|
66
|
-
retry
|
67
|
-
end
|
68
|
-
|
69
|
-
if response == nil || response.code != "200"
|
70
|
-
return nil
|
71
|
-
end
|
72
|
-
if type == "get"
|
73
|
-
return response.body
|
74
|
-
else
|
75
|
-
return response
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
end
|
data/lib/test/test_copperegg.rb
DELETED
File without changes
|