copperegg-revealmetrics 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6fd0a9c916d336895ea615212e8fdff1c4e62e38
4
- data.tar.gz: 64fc8b11e3f72888a3e8f3afbd1e2ac3040d4a06
3
+ metadata.gz: 9ab876f0e7a6bdf9ea7c22ebbca19da8e231a581
4
+ data.tar.gz: a726222785b11573ec23ac80f701b1535ad604d1
5
5
  SHA512:
6
- metadata.gz: 85749a44833212b1ffc7259ac035e5fd200b0c49784ac0f4b3aff7be8320c391dcf6e1294bcae4efc838098d65f618511776757de3d08f463b42ccb2250e6b63
7
- data.tar.gz: fd3527fe79c80d13ba37e012d405840561e439c7e64fde985911966d10e887af7e173f243c987ac12b0ba29093cef5106d3ee6682b498ad5ce8bcc99975a727c
6
+ metadata.gz: 4f941a07e07e7f61b64ae58e177c597f935143e9cd121818d54d5736f9e6dd0c7f3467f77b496ed4e300d3e76eb58012880dfdf200b6e43e7734a9812fc997ea
7
+ data.tar.gz: 44b0d4aa25f277f5f343529f54743ccb123a1cbc2bd0cf1056c4a3dc9a59dae648e73f2ed878cb12de8b481055ffb725069e2f1415e270e5121ae4c5d9656a74
data/README.md CHANGED
@@ -13,8 +13,8 @@ gem install copperegg-revealmetrics
13
13
 
14
14
  Set up your API key:
15
15
  ``` ruby
16
- require 'copperegg'
17
- CopperEgg::Api.apikey = "sdf87xxxxxxxxxxxxxxxxxxxxx" # from the web UI
16
+ require 'copperegg/revealmetrics'
17
+ Copperegg::Revealmetrics::Api.apikey = "sdf87xxxxxxxxxxxxxxxxxxxxx" # from the web UI
18
18
  ```
19
19
 
20
20
  ## Metric Groups
@@ -22,19 +22,19 @@ CopperEgg::Api.apikey = "sdf87xxxxxxxxxxxxxxxxxxxxx" # from the web UI
22
22
  #### Get a metric group:
23
23
 
24
24
  ``` ruby
25
- metric_group = CopperEgg::MetricGroup.find("my_metric_group")
25
+ metric_group = Copperegg::Revealmetrics::MetricGroup.find("my_metric_group")
26
26
  metric_group.name
27
27
  # => "my_metric_group"
28
28
  metric_group.label
29
29
  # => "My Metric Group"
30
30
  metric_group.metrics
31
- # => [#<CopperEgg::MetricGroup::Metric:0x007fb43aab2570 @position=0, @type="ce_gauge", @name="metric1", @label="Metric 1", @unit="b">]
31
+ # => [#<Copperegg::Revealmetrics::MetricGroup::Metric:0x007fb43aab2570 @position=0, @type="ce_gauge", @name="metric1", @label="Metric 1", @unit="b">]
32
32
  ```
33
33
 
34
34
  #### Create a metric group:
35
35
 
36
36
  ``` ruby
37
- metric_group = CopperEgg::MetricGroup.new(:name => "my_new_metric_group", :label => "Cool New Group Visible Name", :frequency => 60) # data is sent every 60 seconds
37
+ metric_group = Copperegg::Revealmetrics::MetricGroup.new(:name => "my_new_metric_group", :label => "Cool New Group Visible Name", :frequency => 60) # data is sent every 60 seconds
38
38
  metric_group.metrics << {"type"=>"ce_gauge", "name"=>"active_connections", "unit"=>"Connections"}
39
39
  metric_group.metrics << {"type"=>"ce_gauge", "name"=>"connections_accepts", "unit"=>"Connections"}
40
40
  metric_group.metrics << {"type"=>"ce_gauge", "name"=>"connections_handled", "unit"=>"Connections"}
@@ -48,7 +48,7 @@ metric_group.save
48
48
  If a metric group by the same name already exists, that one will rather than creating a new one. In addition, if the metric group was previously removed it will be restored.
49
49
 
50
50
  ```ruby
51
- metric_group2 = CopperEgg::MetricGroup.new(:name => "my_new_metric_group", :label => "New Group Version 2", :frequency => 60)
51
+ metric_group2 = Copperegg::Revealmetrics::MetricGroup.new(:name => "my_new_metric_group", :label => "New Group Version 2", :frequency => 60)
52
52
  metric_group2.metrics << {"type"=>"ce_counter", "name"=>"active_connections", "unit"=>"Connections"}
53
53
  metric_group2.save # this will perform an update to change the type of the metric 'active_connections' from 'ce_gauge' to 'ce_counter'
54
54
 
@@ -86,20 +86,20 @@ metric_group.delete
86
86
  #### Post samples for a metric group
87
87
 
88
88
  ```ruby
89
- CopperEgg::MetricSample.save(metric_group.name, "custom_identifier1", Time.now.to_i, "active_connections" => 2601, "connections_accepts" => 154, "connections_handled" => 128, "connections_requested" => 1342, ...)
89
+ Copperegg::Revealmetrics::MetricSample.save(metric_group.name, "custom_identifier1", Time.now.to_i, "active_connections" => 2601, "connections_accepts" => 154, "connections_handled" => 128, "connections_requested" => 1342, ...)
90
90
  ```
91
91
 
92
92
  #### Get samples
93
93
 
94
94
  ```ruby
95
95
  # Get the most recent samples for a single metric
96
- CopperEgg::MetricSample.samples(metric_group.name, "connections_accepts")
96
+ Copperegg::Revealmetrics::MetricSample.samples(metric_group.name, "connections_accepts")
97
97
 
98
98
  # Get the most recent samples for multiple metrics
99
- CopperEgg::MetricSample.samples(metric_group.name, ["connections_accepts", "connections_handled", "reading", "writing"])
99
+ Copperegg::Revealmetrics::MetricSample.samples(metric_group.name, ["connections_accepts", "connections_handled", "reading", "writing"])
100
100
 
101
101
  # Specify a start time and duration
102
- CopperEgg::MetricSample.samples(metric_group.name, ["connections_accepts", "connections_handled", "reading", "writing"], :starttime => 4.hours.ago, :duration => 15.minutes)
102
+ Copperegg::Revealmetrics::MetricSample.samples(metric_group.name, ["connections_accepts", "connections_handled", "reading", "writing"], :starttime => 4.hours.ago, :duration => 15.minutes)
103
103
  ```
104
104
 
105
105
  The raw JSON response is returned as specified in the [API docs][sample_docs].
@@ -112,37 +112,37 @@ By default, the dashboard created will be named "_MetricGroupLabel_ Dashboard" a
112
112
 
113
113
  ```ruby
114
114
  # Creates a dashboard named "My Metric Group Dashboard"
115
- dashboard = CopperEgg::CustomDashboard.create(metric_group)
115
+ dashboard = Copperegg::Revealmetrics::CustomDashboard.create(metric_group)
116
116
  ```
117
117
 
118
118
  You can pass an option to specify the name of the dashboard.
119
119
 
120
120
  ```ruby
121
- dashboard = CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers")
121
+ dashboard = Copperegg::Revealmetrics::CustomDashboard.create(metric_group, :name => "Cloud Servers")
122
122
  ```
123
123
 
124
124
  If a single identifier is specified, the dashboard will be created having one value widget per metric matching the single identifier.
125
125
 
126
126
  ```ruby
127
- dashboard = CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => "custom_identifier1")
127
+ dashboard = Copperegg::Revealmetrics::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => "custom_identifier1")
128
128
  ```
129
129
 
130
130
  If an array of identifiers is specified, the dashboard will be created having one timeline widget per metric matching each identifier.
131
131
 
132
132
  ```ruby
133
- dashboard = CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => ["custom_identifier1", "custom_identifier2"])
133
+ dashboard = Copperegg::Revealmetrics::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => ["custom_identifier1", "custom_identifier2"])
134
134
  ```
135
135
 
136
136
  You can limit the widgets created by metric.
137
137
 
138
138
  ```ruby
139
- dashboard = CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => ["custom_identifier1", "custom_identifier2"], :metrics => ["reading", "writing", "waiting"])
139
+ dashboard = Copperegg::Revealmetrics::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => ["custom_identifier1", "custom_identifier2"], :metrics => ["reading", "writing", "waiting"])
140
140
  ```
141
141
 
142
142
  #### Get a dashboard
143
143
 
144
144
  ```ruby
145
- dashboard = CopperEgg::CustomDashboard.find_by_name("My Metric Group Dashboard")
145
+ dashboard = Copperegg::Revealmetrics::CustomDashboard.find_by_name("My Metric Group Dashboard")
146
146
  ```
147
147
 
148
148
  #### Delete a dashboard
@@ -158,14 +158,14 @@ dashboard.delete
158
158
  #### Get all or specific tags
159
159
 
160
160
  ```ruby
161
- tags_list = CopperEgg::Tag.find
162
- tag = CopperEgg::Tag.find_by_name("my-tag")
161
+ tags_list = Copperegg::Revealmetrics::Tag.find
162
+ tag = Copperegg::Revealmetrics::Tag.find_by_name("my-tag")
163
163
  ```
164
164
 
165
165
  #### Create a tag
166
166
 
167
167
  ```ruby
168
- tag = CopperEgg::Tag.new({:name => "my-tag"})
168
+ tag = Copperegg::Revealmetrics::Tag.new({:name => "my-tag"})
169
169
  tag.objects = ["object-identifier-1", "object-identifier-2"]
170
170
  tag.save
171
171
  ```
@@ -0,0 +1,17 @@
1
+ require "net/http"
2
+ require "net/https"
3
+ require "uri"
4
+ require "json/pure"
5
+
6
+ require "copperegg/revealmetrics/mixins/persistence"
7
+ require "copperegg/revealmetrics/metric_group"
8
+ require "copperegg/revealmetrics/custom_dashboard"
9
+ require "copperegg/revealmetrics/metric_sample"
10
+ require "copperegg/revealmetrics/tag"
11
+ require "copperegg/revealmetrics/api"
12
+
13
+ module Copperegg
14
+ module Revealmetrics
15
+
16
+ end
17
+ end
@@ -0,0 +1,28 @@
1
+ module Copperegg
2
+ module Revealmetrics
3
+
4
+ class Api
5
+ class << self
6
+ attr_accessor :apikey
7
+ attr_reader :ssl_verify_peer, :timeout
8
+
9
+ def host=(host)
10
+ @uri = URI.join(host, "/v2/revealmetrics/").to_s
11
+ end
12
+
13
+ def uri
14
+ @uri || "https://api.copperegg.com/v2/revealmetrics/"
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
+
27
+ end
28
+ end
@@ -0,0 +1,142 @@
1
+ module Copperegg
2
+ module Revealmetrics
3
+
4
+ class CustomDashboard
5
+ include Copperegg::Revealmetrics::Mixins::Persistence
6
+
7
+ WIDGET_TYPES = %w(metric metric_list timeline)
8
+ WIDGET_STYLES = %w(value timeline both list values)
9
+ WIDGET_MATCHES = %w(select multi tag all)
10
+
11
+ resource "dashboards"
12
+
13
+ attr_accessor :name, :label, :data
14
+
15
+ def load_attributes(attributes)
16
+ @data = {"widgets" => {}, "order" => []}
17
+ attributes.each do |name, value|
18
+ if name.to_s == "id"
19
+ @id = value
20
+ elsif name.to_s == "data"
21
+ attributes[name].each do |data_name, data_value|
22
+ if data_name.to_s == "order"
23
+ data["order"] = data_value
24
+ else
25
+ data["widgets"] = data_value
26
+ end
27
+ end
28
+ elsif !respond_to?("#{name}=")
29
+ next
30
+ else
31
+ send "#{name}=", value
32
+ end
33
+ end
34
+ end
35
+
36
+ def valid?
37
+ @error = nil
38
+ if self.name.nil? || self.name.to_s.strip.empty?
39
+ @error = "Name can't be blank."
40
+ else
41
+ self.data["widgets"].values.each do |widget|
42
+ widget.each do |key, value|
43
+ if key.to_s == "type" && !WIDGET_TYPES.include?(value)
44
+ @error = "Invalid widget type #{value}."
45
+ elsif key.to_s == "style" && !WIDGET_STYLES.include?(value)
46
+ @error = "Invalid widget style #{value}."
47
+ elsif key.to_s == "match" && !WIDGET_MATCHES.include?(value)
48
+ @error = "Invalid widget match #{value}."
49
+ elsif key.to_s == "metric" && (!value.is_a?(Hash) || value.keys.size == 0)
50
+ @error = "Invalid widget metric. #{value}"
51
+ else
52
+ (widget["metric"] || widget[:metric]).each do |metric_group_name, metric_group_value|
53
+ if !metric_group_value.is_a?(Array)
54
+ @error = "Invalid widget metric. #{metric_group_value}"
55
+ elsif metric_group_value.length == 0
56
+ @error = "Invalid widget metric. #{metric_group_value}"
57
+ else
58
+ metric_group_value.each do |metric_data|
59
+ if !metric_data.is_a?(Array)
60
+ @error = "Invalid widget metric. #{metric_group_value}"
61
+ elsif metric_data.length < 2
62
+ @error = "Invalid widget metric. #{metric_group_value}"
63
+ elsif (/^\d+$/ =~ metric_data.first.to_s).nil?
64
+ @error = "Invalid widget metric. #{metric_group_value}"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ match_param = widget["match_param"] || widget[:match_param]
72
+ if (widget["match"] || widget[:match]) != "all" && (match_param.nil? || match_param.to_s.strip.empty?)
73
+ @error = "Missing match parameter."
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::Revealmetrics::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
+
141
+ end
142
+ end
@@ -0,0 +1,127 @@
1
+ module Copperegg
2
+ module Revealmetrics
3
+
4
+ class MetricGroup
5
+ include Copperegg::Revealmetrics::Mixins::Persistence
6
+
7
+ resource "metric_groups"
8
+
9
+ attr_accessor :name, :label, :frequency, :metrics
10
+
11
+ def load_attributes(attributes)
12
+ @metrics = []
13
+ attributes.each do |name, value|
14
+ if name.to_s == "id"
15
+ @id = value
16
+ elsif !respond_to?("#{name}=")
17
+ next
18
+ elsif value.to_s == "metrics"
19
+ @metrics = value.map { |v| Metric.new(v) }
20
+ else
21
+ send "#{name}=", value
22
+ end
23
+ end
24
+ end
25
+
26
+ def to_hash
27
+ self.instance_variables.reduce({}) do |memo, variable|
28
+ value = instance_variable_get(variable)
29
+ if variable.to_s == "@metrics"
30
+ memo[variable.to_s.sub("@", "")] = value.map(&:to_hash)
31
+ elsif variable.to_s != "@error"
32
+ memo[variable.to_s.sub("@", "")] = value
33
+ end
34
+ memo
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
+ elsif self.metrics.nil? || self.metrics.empty?
43
+ @error = "You must define at least one metric."
44
+ else
45
+ self.metrics = self.metrics.map { |metric| metric.is_a?(Hash) ? Metric.new(metric) : metric }
46
+ self.metrics.each do |metric|
47
+ if !metric.is_a?(Metric)
48
+ @error = "Metric expected."
49
+ break
50
+ elsif !metric.valid?
51
+ @error = metric.error
52
+ break
53
+ else
54
+ metric.send(:remove_instance_variable, :@position) if (metric.instance_variables.include?(:@position) || metric.instance_variables.include?("@position")) && !self.persisted?
55
+ end
56
+ end
57
+ end
58
+ @error.nil?
59
+ end
60
+
61
+ private
62
+
63
+ def create
64
+ response = self.class.request(:request_type => "get", :id => self.name, :show_hidden => true)
65
+ if response.code == "200"
66
+ json = JSON.parse(response.body)
67
+ metric_group = self.class.new(json)
68
+ @id = self.name
69
+ # needs_update = self.label != metric_group.label || self.frequency != metric_group.frequency || self.metrics.length != metric_group.metrics.length || self.metrics.map(&:name).sort != metric_group.metrics.map {|m| m["name"]}.sort
70
+ if true #needs_update
71
+ self.class.request(self.to_hash.merge(:id => @id, :is_hidden => 0, :request_type => "put", :show_hidden => true))
72
+ else
73
+ response
74
+ end
75
+ else
76
+ self.class.request(self.to_hash.merge(:request_type => "post"))
77
+ end
78
+ end
79
+
80
+ class Metric
81
+ TYPES = %w(ce_gauge ce_gauge_f ce_counter ce_counter_f)
82
+
83
+ attr_accessor :name, :label, :type, :unit
84
+ attr_reader :error, :position
85
+
86
+ def initialize(attributes={})
87
+ attributes.each do |name, value|
88
+ if name.to_s == "position"
89
+ @position = value
90
+ elsif !respond_to?("#{name}=")
91
+ next
92
+ else
93
+ send "#{name}=", value
94
+ end
95
+ end
96
+ end
97
+
98
+ def to_hash
99
+ self.instance_variables.reduce({}) do |memo, variable|
100
+ if variable.to_s != "@error"
101
+ value = instance_variable_get(variable)
102
+ memo[variable.to_s.sub("@", "")] = value
103
+ end
104
+ memo
105
+ end
106
+ end
107
+
108
+ def valid?
109
+ valid = false
110
+ @error = nil
111
+ if self.name.nil? || self.name.to_s.strip.empty?
112
+ @error = "Metric name cannot be blank."
113
+ elsif self.type.nil? || self.type.to_s.strip.empty?
114
+ @error = "Metric type must be defined."
115
+ elsif !TYPES.include?(self.type)
116
+ @error = "Invalid metric type #{self.type}."
117
+ else
118
+ valid = true
119
+ remove_instance_variable(:@error)
120
+ end
121
+ valid
122
+ end
123
+ end
124
+ end
125
+
126
+ end
127
+ end