copperegg 0.5.3 → 0.6.0.pre
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 +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
|