undertaker 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.
@@ -0,0 +1,6 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
6
+ examples/*
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ config.yml
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Waine Kerr
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,42 @@
1
+ undertaker
2
+ ===========
3
+
4
+ periodic websites status checker storing in redis
5
+
6
+ ## Install
7
+
8
+ (sudo) gem install undertaker
9
+
10
+ ## Configuration
11
+
12
+ It's easy- look at the [example]("http://github.com/wainekerr/undertaker/blob/master/examples/config.yml") :)
13
+
14
+ ## Run it
15
+
16
+ Currently, the only way to do it is manually (which is useless) or in a crontab. A 5-minutes crontab is a good deal:
17
+
18
+ `*/5 * * * * undertaker /path/to/config.yml`
19
+
20
+ ## What it does
21
+
22
+ It makes an HTTP request on the configured websites, then store the result as a JSON Array in redis e.g :
23
+
24
+ `undertaker:hostname => [http_code, http_message]`
25
+
26
+ If the requests returns an exception, the `http_code` will be -999 and `http_message` the exception.
27
+
28
+ After, it's up to you do to what you want to do with that data, not the job of undertaker :-)
29
+
30
+ ## Command-line options
31
+
32
+ You can add theses options after the `/path/to/config.yml` when launching `undertaker` :
33
+
34
+ * _verbose_ enable verbosity
35
+ * _report_ display an ASCII formatted results of the last test
36
+ * _jsonreport_ returns the results of the last test on JSON format
37
+ * _reset_ reset the content
38
+ * _unlock_ unlock undertaker (to prevent multiple instances running at the same time)
39
+
40
+ ## Copyright
41
+
42
+ Copyright (c) 2010 Waine Kerr. See LICENSE for details.
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "undertaker"
8
+ gem.summary = %Q{Periodic HTTP status checker, stored in Redis}
9
+ gem.description = %Q{Small utility who checks HTTP status of websites, and store the results in Redis.}
10
+ gem.email = "wk@heldscalla.org"
11
+ gem.homepage = "http://wainekerr.github.com/undertaker/"
12
+ gem.authors = ["Waine Kerr"]
13
+ gem.add_dependency "redis-namespace", ">= 0.10.0"
14
+ gem.add_dependency "json", ">= 1.4.6"
15
+ gem.add_dependency "terminal-table", ">= 1.4.2"
16
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
17
+ gem.add_development_dependency "yard", ">= 0"
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/test_*.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/test_*.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+ task :test => :check_dependencies
45
+
46
+ task :default => :test
47
+
48
+ begin
49
+ require 'yard'
50
+ YARD::Rake::YardocTask.new
51
+ rescue LoadError
52
+ task :yardoc do
53
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
54
+ end
55
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Runner for Undertaker
4
+
5
+ (puts "Usage: undertaker config.yml [report|json_report|verbose|unlock|reset]" ; exit 1) if ARGV[0].nil?
6
+
7
+ require File.dirname(__FILE__) + '/../lib/undertaker'
8
+
9
+ begin
10
+ verbose = ARGV[1]=='verbose' ? true : false
11
+ @undertaker = Undertaker.new(ARGV[0], verbose)
12
+ if ARGV[1]=="unlock"
13
+ @undertaker.unlock
14
+ exit 0
15
+ elsif ARGV[1]=="report"
16
+ @undertaker.report
17
+ elsif ARGV[1]=="json_report"
18
+ @undertaker.json_report
19
+ elsif ARGV[1]=="reset"
20
+ @undertaker.reset
21
+ else
22
+ puts "[INFO ] Undertaker starting- #{@undertaker.config['websites'].size} websites to test!" if verbose
23
+ @undertaker.check!
24
+ @undertaker.report if verbose
25
+ end
26
+ rescue
27
+ puts "[OH NOES ] #{$!}"
28
+ exit 1
29
+ end
@@ -0,0 +1,88 @@
1
+ %w{redis/namespace net/http uri yaml json terminal-table/import}.each {|r| require r }
2
+
3
+ class Undertaker
4
+ attr_reader :config
5
+
6
+ def initialize(config_file, verbose=false)
7
+ raise "Configuration file not found" unless File.exists?(config_file)
8
+ @verbose = verbose
9
+ @config = YAML.load_file(config_file)
10
+ @redis = Redis::Namespace.new("#{@config['redis']['namespace']}", :redis => Redis.new(@config['redis']))
11
+ end
12
+
13
+ def lock
14
+ @redis.set "locked", "true"
15
+ end
16
+
17
+ def unlock
18
+ @redis.set "locked", nil
19
+ end
20
+
21
+ def check!
22
+ raise "Looks like another instance is running. Exiting." if @redis.get("locked")=="true"
23
+ lock
24
+ @threads = []
25
+ @config['websites'].each do |website|
26
+ @threads << Thread.new { check(website) }
27
+ end
28
+ @threads.each { |th| th.join }
29
+ unlock
30
+ end
31
+
32
+ def check(website)
33
+ begin
34
+ url = URI.parse(website)
35
+ puts "[TEST ] Starting request on #{website}" if @verbose
36
+ req = Net::HTTP::Get.new(url.path)
37
+ res = Net::HTTP.start(url.host, url.port) {|http|
38
+ http.request(req)
39
+ }
40
+ @redis.set url.host, [res.code.to_i, res.message, Time.now.strftime('%s').to_i].to_json
41
+ @redis.expire url.host, @config['redis']['expires']
42
+ puts "[TESTED ] #{url} => #{res.code}, #{res.message}" if @verbose
43
+ rescue
44
+ @redis.set url.host, [0, $!, Time.now.strftime('%s').to_i].to_json
45
+ @redis.expire url.host, @config['redis']['expires']
46
+ puts "[FAILED ] #{url} => #{$!}" if @verbose
47
+ end
48
+ end
49
+
50
+ def report
51
+ @website_table = table do |t|
52
+ t.headings = 'Website', 'Code', 'Message'
53
+ @config['websites'].each do |website|
54
+ url = URI.parse(website)
55
+ result = @redis.get url.host
56
+ if result
57
+ result = JSON.parse(result)
58
+ t << [website, result[0], result[1]]
59
+ else
60
+ t << [website, "N/A", "No Info"]
61
+ end
62
+ end
63
+ end
64
+ puts @website_table
65
+ end
66
+
67
+ def json_report
68
+ @array = []
69
+ @config['websites'].each do |website|
70
+ url = URI.parse(website)
71
+ result = @redis.get url.host
72
+ if result
73
+ result = JSON.parse(result)
74
+ @array << [website, result[0], result[1]]
75
+ else
76
+ @array << [website, "N/A", "No Info"]
77
+ end
78
+ end
79
+ puts @array.to_json
80
+ end
81
+
82
+ def reset
83
+ @config['websites'].each do |website|
84
+ url = URI.parse(website)
85
+ result = @redis.del url.host
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'undertaker'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestUndertaker < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: undertaker
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Waine Kerr
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-08-28 00:00:00 +02:00
18
+ default_executable: undertaker
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: redis-namespace
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 10
30
+ - 0
31
+ version: 0.10.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: json
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 4
44
+ - 6
45
+ version: 1.4.6
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: terminal-table
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 1
57
+ - 4
58
+ - 2
59
+ version: 1.4.2
60
+ type: :runtime
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: thoughtbot-shoulda
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ type: :development
73
+ version_requirements: *id004
74
+ - !ruby/object:Gem::Dependency
75
+ name: yard
76
+ prerelease: false
77
+ requirement: &id005 !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ type: :development
85
+ version_requirements: *id005
86
+ description: Small utility who checks HTTP status of websites, and store the results in Redis.
87
+ email: wk@heldscalla.org
88
+ executables:
89
+ - undertaker
90
+ extensions: []
91
+
92
+ extra_rdoc_files:
93
+ - LICENSE
94
+ - README.md
95
+ files:
96
+ - .document
97
+ - .gitignore
98
+ - LICENSE
99
+ - README.md
100
+ - Rakefile
101
+ - VERSION
102
+ - bin/undertaker
103
+ - lib/undertaker.rb
104
+ - test/helper.rb
105
+ - test/test_undertaker.rb
106
+ has_rdoc: true
107
+ homepage: http://wainekerr.github.com/undertaker/
108
+ licenses: []
109
+
110
+ post_install_message:
111
+ rdoc_options:
112
+ - --charset=UTF-8
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ segments:
127
+ - 0
128
+ version: "0"
129
+ requirements: []
130
+
131
+ rubyforge_project:
132
+ rubygems_version: 1.3.6
133
+ signing_key:
134
+ specification_version: 3
135
+ summary: Periodic HTTP status checker, stored in Redis
136
+ test_files:
137
+ - test/helper.rb
138
+ - test/test_undertaker.rb