uptimr 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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