uptimr 0.1.0

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 ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ uptimr (0.1.0)
5
+ httparty
6
+ multi_json (~> 1.7.9)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (4.0.0)
12
+ i18n (~> 0.6, >= 0.6.4)
13
+ minitest (~> 4.2)
14
+ multi_json (~> 1.3)
15
+ thread_safe (~> 0.1)
16
+ tzinfo (~> 0.3.37)
17
+ atomic (1.1.13)
18
+ coderay (1.0.9)
19
+ httparty (0.11.0)
20
+ multi_json (~> 1.0)
21
+ multi_xml (>= 0.5.2)
22
+ i18n (0.6.5)
23
+ metaclass (0.0.1)
24
+ method_source (0.8.1)
25
+ minitest (4.7.5)
26
+ mocha (0.14.0)
27
+ metaclass (~> 0.0.1)
28
+ multi_json (1.7.9)
29
+ multi_xml (0.5.5)
30
+ pry (0.9.12.2)
31
+ coderay (~> 1.0.5)
32
+ method_source (~> 0.8)
33
+ slop (~> 3.4)
34
+ rake (10.1.0)
35
+ shoulda (3.5.0)
36
+ shoulda-context (~> 1.0, >= 1.0.1)
37
+ shoulda-matchers (>= 1.4.1, < 3.0)
38
+ shoulda-context (1.1.5)
39
+ shoulda-matchers (2.3.0)
40
+ activesupport (>= 3.0.0)
41
+ slop (3.4.4)
42
+ test-unit (2.5.5)
43
+ thread_safe (0.1.2)
44
+ atomic
45
+ tzinfo (0.3.37)
46
+
47
+ PLATFORMS
48
+ ruby
49
+
50
+ DEPENDENCIES
51
+ mocha (~> 0.14.0)
52
+ pry
53
+ rake
54
+ shoulda (~> 3.5.0)
55
+ test-unit
56
+ uptimr!
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # Uptimr
2
+
3
+ Uptimr is a *very* basic Ruby wrapper for the most excellent [Uptime](https://github.com/fzaninotto/uptime), a Node.js remote application monitoring tool. This wrapper is designed to import data using Uptime's API and transform points more familiar Ruby types
4
+
5
+ ## Installation
6
+
7
+ ```ruby
8
+ gem install uptimr
9
+ ```
10
+
11
+ or put it in your Gemfile
12
+
13
+ ```ruby
14
+ gem "uptimr"
15
+ ```
16
+
17
+ Then initialize Uptimr to point to your Uptime API
18
+
19
+ ```ruby
20
+ Uptimr.config |config| do
21
+ config.base_url = "https://yoursite.com/status"
22
+ end
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ To download your entire list of checks and its associated data
28
+
29
+ ```ruby
30
+ Uptimr::Check.list
31
+ ```
32
+
33
+ This will return an array of check objects with the following attributes
34
+
35
+ * id (String) API id for check
36
+ * is_up (Boolean) Indicates if service currently responds to ping
37
+ * first_tested (Time) Time when this check was first tested
38
+ * last_tested (Time) Time when this check was last tested
39
+ * name (String) Name of the check
40
+ * url (String) URL of the check
41
+ * count (Number) Number of samples taken to calculate statistical data
42
+ * responsiveness (Number) % responsiveness of service in a number ranging 0..1
43
+ * response_time (Number) The mean response time in ms
44
+ * availability (Number) % uptime of service in a number ranging 0..1
45
+
46
+ Note that this wrapper doesn't currently pull hourly, daily or monthly data yet
47
+
48
+ To look up an individual check by id number, use the following
49
+
50
+ ```ruby
51
+ Uptimr::Check.find(id)
52
+ ```
53
+
54
+ ## Todo
55
+
56
+ * Allow for basic HTTP authentication
57
+ * Pull hourly, daily & monthly data on checks
58
+
59
+ ## License
60
+
61
+ MIT
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/test*.rb']
7
+ t.verbose = true
8
+ end
@@ -0,0 +1,55 @@
1
+ require 'time'
2
+
3
+ module Uptimr
4
+ class Check
5
+ attr_accessor :id, :is_up, :last_tested, :name, :responsiveness,
6
+ :response_time, :availability, :url, :count,
7
+ :daily_stats, :hourly_stats, :monthly_stats, :first_tested
8
+
9
+ def initialize(params)
10
+ @id = params[:_id]
11
+ @is_up = params[:isUp]
12
+ @first_tested = Time.iso8601(params[:firstTested]).localtime
13
+ @last_tested = Time.iso8601(params[:lastTested]).localtime
14
+ @name = params[:name]
15
+ @url = params[:url]
16
+ @responsiveness = params[:qos][:responsiveness].to_f
17
+ @response_time = params[:qos][:responseTime].to_f
18
+ @availability = params[:qos][:availability].to_f
19
+ @count = params[:qos][:count]
20
+ end
21
+
22
+ def self.list
23
+ response = Uptimr.request "/api/checks", method: :get
24
+ response.map { |check| self.new check }
25
+ end
26
+
27
+ def self.find(id)
28
+ self.new Uptimr.request "/api/checks/#{id}", method: :get
29
+ end
30
+
31
+ def get_hourly_stats(from=0, to=Time.now)
32
+ @hourly_stats ||= Uptimr.request "/api/checks/#{@id}/stats/hour?begin=#{to_ms from}&end=#{to_ms to}", method: :get
33
+ end
34
+
35
+ def get_daily_stats(from=0, to=Time.now)
36
+ @daily_stats ||= Uptimr.request "/api/checks/#{@id}/stats/day?begin=#{to_ms from}&end=#{to_ms to}", method: :get
37
+ end
38
+
39
+ def get_monthly_stats(from=0, to=Time.now)
40
+ @monthly_stats ||= Uptimr.request "/api/checks/#{@id}/stats/month?begin=#{to_ms from}&end=#{to_ms to}", method: :get
41
+ end
42
+
43
+ def reload_stats
44
+ get_hourly_stats if @hourly_stats.nil?
45
+ get_daily_stats if @daily_stats.nil?
46
+ get_monthly_stats if @monthly_stats.nil?
47
+ end
48
+
49
+ private
50
+
51
+ def to_ms(time)
52
+ time.to_i * 1000
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ module Uptimr
2
+ class UptimrError < StandardError
3
+
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ module Uptimr
2
+ class Util
3
+
4
+ def self.keys_to_sym(raw)
5
+ case raw
6
+ when Hash
7
+ temp = {}
8
+ raw.each do |key, value|
9
+ key = (key.to_sym rescue key) || key
10
+ temp[key] = keys_to_sym value
11
+ end
12
+ temp
13
+ when Array
14
+ raw.map { |elem| keys_to_sym(elem) }
15
+ else
16
+ raw
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Uptimr
2
+ VERSION = '0.1.0'
3
+ end
data/lib/uptimr.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'httparty'
2
+ require 'multi_json'
3
+ require 'uri'
4
+ require 'cgi'
5
+
6
+ require 'uptimr/version'
7
+ require 'uptimr/error'
8
+ require 'uptimr/util'
9
+ require 'uptimr/check'
10
+
11
+ module Uptimr
12
+ class << self
13
+ attr_accessor :base_url
14
+ end
15
+
16
+ def self.config
17
+ yield self
18
+ end
19
+
20
+ def self.request(path, options={})
21
+ handle_error "You have not set your API url" if base_url.nil?
22
+ handle_error "Invalid HTTP method" unless %w(get post).include? options[:method].to_s
23
+
24
+ options.merge! url: "#{base_url}#{path}"
25
+
26
+ puts "About to request: #{options[:url]}"
27
+ response = generate_request(options)
28
+
29
+ parse response.body
30
+ end
31
+
32
+ def self.parse(raw_json)
33
+ begin
34
+ Util.keys_to_sym MultiJson.load(raw_json)
35
+ rescue MultiJson::DecodeError => e
36
+ handle_error("JSON is buggered")
37
+ end
38
+ end
39
+
40
+ def self.handle_error(error)
41
+ raise Uptimr::UptimrError.new(error)
42
+ end
43
+
44
+ private
45
+
46
+ def self.generate_request(options)
47
+ HTTParty.send options[:method], options[:url], options
48
+ end
49
+ end
@@ -0,0 +1 @@
1
+ {"__v":0,"_id":"521e420d4473195a11000229","firstTested":"2013-08-28T18:31:52.242Z","isUp":true,"lastChanged":"2013-08-31T15:21:04.062Z","lastTested":"2013-08-31T17:09:06.199Z","name":"Website","type":"https","url":"https://ideal-postcodes.co.uk/","downtime":0,"uptime":6482137,"isPaused":false,"tags":[],"errorCount":2,"alertTreshold":2,"maxTime":1500,"interval":60000}
@@ -0,0 +1 @@
1
+ [{"__v":0,"_id":"521e420d4473195a11000229","firstTested":"2013-08-28T18:31:52.242Z","isUp":true,"lastChanged":"2013-08-31T15:21:04.062Z","lastTested":"2013-08-31T16:41:05.574Z","name":"Website","qos":{"check":"521e420d4473195a11000229","timestamp":1377880892640,"count":1440,"responsiveness":0.9951388888888889,"responseTime":174.45625,"downtime":0,"availability":1},"type":"https","url":"https://ideal-postcodes.co.uk/","downtime":0,"uptime":4801512,"isPaused":false,"tags":[],"errorCount":2,"alertTreshold":2,"maxTime":1500,"interval":60000},{"__v":0,"_id":"521e42264473195a1100022e","firstTested":"2013-08-28T18:32:07.218Z","isUp":true,"lastChanged":"2013-08-31T10:44:12.765Z","lastTested":"2013-08-31T16:41:20.638Z","name":"API","qos":{"check":"521e42264473195a1100022e","timestamp":1377880892640,"count":1440,"responsiveness":0.9958333333333333,"responseTime":95.44097222222223,"downtime":0,"availability":1},"type":"https","url":"https://api.ideal-postcodes.co.uk/","downtime":0,"uptime":21427873,"isPaused":false,"tags":[],"errorCount":2,"alertTreshold":2,"maxTime":1500,"interval":60000}]
@@ -0,0 +1,41 @@
1
+ require 'test/unit'
2
+ require 'mocha/setup'
3
+ require 'uptimr'
4
+ require 'shoulda'
5
+
6
+ module UpTimr
7
+ attr_accessor :mock
8
+
9
+ def self.mock=(mock)
10
+ @mock = mock
11
+ end
12
+
13
+ def self.generate_request(options)
14
+ @mock.execute options[:method], options
15
+ end
16
+ end
17
+
18
+ def test_response(body, status=200)
19
+ body = MultiJson.dump(body)
20
+ m = mock
21
+ m.instance_variable_set('@instance_vals', { code: status, body: body})
22
+ def m.body; @instance_vals[:body]; end
23
+ def m.code; @instance_vals[:code]; end
24
+ m
25
+ end
26
+
27
+ def checks
28
+ File.read(File.expand_path('../test_data/checks.json', __FILE__))
29
+ end
30
+
31
+ def check
32
+ File.read(File.expand_path('../test_data/check.json', __FILE__))
33
+ end
34
+
35
+ def pings
36
+
37
+ end
38
+
39
+ def events
40
+
41
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+
4
+ class TestUptimr < Test::Unit::TestCase
5
+ context "Utils" do
6
+ test_data = {
7
+ "ping" => "pong",
8
+ "ping" => ["pong", "pong", "pong"],
9
+ "ping" => {
10
+ "pong" => "pang",
11
+ "pong" => "pang"
12
+ }
13
+ }
14
+
15
+ expected_result = {
16
+ ping: "pong",
17
+ ping: ["pong", "pong", "pong"],
18
+ ping: {
19
+ pong: "pang",
20
+ pong: "pang"
21
+ }
22
+ }
23
+
24
+ should "convert keys to symbols" do
25
+ result = Uptimr::Util.keys_to_sym test_data
26
+ assert_equal expected_result, result
27
+ end
28
+ end
29
+
30
+ context "Invalid request attributes" do
31
+ should "throw an error if invalid http method" do
32
+ assert_raises Uptimr::UptimrError do
33
+ Uptimr::Check.list
34
+ end
35
+ end
36
+ end
37
+
38
+ context "API with valid credential" do
39
+ setup do
40
+ Uptimr.config do |config|
41
+ config.base_url = "status.ideal-postcodes.co.uk"
42
+ end
43
+ end
44
+
45
+ teardown do
46
+ Uptimr.config do |config|
47
+ config.base_url = nil
48
+ end
49
+ end
50
+
51
+ should "throw an error if no URL" do
52
+ assert_raises Uptimr::UptimrError do
53
+ Uptimr::Check.list
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ end
data/uptimr.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+
3
+ require 'uptimr/version'
4
+
5
+ spec = Gem::Specification.new do |s|
6
+ s.name = 'uptimr'
7
+ s.version = Uptimr::VERSION
8
+ s.summary = 'Wrapper for the Uptime'
9
+ s.description = 'Wrapper for the Uptime, a great remote monitoring tool written in node.js. See https://github.com/fzaninotto/uptime'
10
+ s.authors = ['Chris Blanchard']
11
+ s.email = ['cablanchard@gmail.com']
12
+ s.homepage = 'https://github.com/cblanc/uptimr'
13
+
14
+ s.add_dependency('httparty')
15
+ s.add_dependency('multi_json', '~> 1.7.9')
16
+
17
+ s.add_development_dependency('mocha', '~> 0.14.0')
18
+ s.add_development_dependency('test-unit')
19
+ s.add_development_dependency('shoulda', '~> 3.5.0')
20
+ s.add_development_dependency('rake')
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- test/*`.split("\n")
24
+ s.require_paths = ['lib']
25
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uptimr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Blanchard
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: multi_json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.7.9
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.7.9
46
+ - !ruby/object:Gem::Dependency
47
+ name: mocha
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.14.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.14.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: test-unit
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: shoulda
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 3.5.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 3.5.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Wrapper for the Uptime, a great remote monitoring tool written in node.js.
111
+ See https://github.com/fzaninotto/uptime
112
+ email:
113
+ - cablanchard@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - Gemfile
119
+ - Gemfile.lock
120
+ - README.md
121
+ - Rakefile
122
+ - lib/uptimr.rb
123
+ - lib/uptimr/check.rb
124
+ - lib/uptimr/error.rb
125
+ - lib/uptimr/util.rb
126
+ - lib/uptimr/version.rb
127
+ - test/test_data/check.json
128
+ - test/test_data/checks.json
129
+ - test/test_helper.rb
130
+ - test/test_uptimr.rb
131
+ - uptimr.gemspec
132
+ homepage: https://github.com/cblanc/uptimr
133
+ licenses: []
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 1.8.24
153
+ signing_key:
154
+ specification_version: 3
155
+ summary: Wrapper for the Uptime
156
+ test_files:
157
+ - test/test_data/check.json
158
+ - test/test_data/checks.json
159
+ - test/test_helper.rb
160
+ - test/test_uptimr.rb