kingkong 0.0.7 → 0.0.8
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/kingkong.gemspec +2 -0
- data/lib/kingkong.rb +1 -0
- data/lib/kingkong/ping.rb +12 -1
- data/lib/kingkong/pinger.rb +14 -23
- data/lib/kingkong/processor.rb +80 -0
- data/lib/kingkong/runner.rb +11 -17
- data/lib/kingkong/version.rb +1 -1
- data/spec/lib/kingkong/ping_spec.rb +4 -0
- data/spec/lib/kingkong/pinger_spec.rb +24 -24
- data/spec/lib/kingkong/runner_spec.rb +9 -3
- metadata +47 -26
- data/bin/kingkong-munin +0 -18
- data/bin/kingkong-server +0 -10
data/kingkong.gemspec
CHANGED
data/lib/kingkong.rb
CHANGED
data/lib/kingkong/ping.rb
CHANGED
@@ -70,7 +70,7 @@ module KingKong
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def to_s
|
73
|
-
"Ping(#{id}, :#{status})"
|
73
|
+
"Ping(#{id}, :#{status}#{", #{latency}s" if completed?})"
|
74
74
|
end
|
75
75
|
|
76
76
|
# Generates ids for pings
|
@@ -83,6 +83,17 @@ module KingKong
|
|
83
83
|
30 # 30 seconds that is!
|
84
84
|
end
|
85
85
|
|
86
|
+
# Bust out a hash so that we can encode it into JSON and make some magic happen.
|
87
|
+
def to_hash
|
88
|
+
{
|
89
|
+
'status' => status,
|
90
|
+
'latency' => latency,
|
91
|
+
'start_time' => start_time,
|
92
|
+
'end_time' => end_time,
|
93
|
+
'ttl' => ttl
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
86
97
|
private
|
87
98
|
# Give us the current time in seconds
|
88
99
|
def current_time
|
data/lib/kingkong/pinger.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'eventmachine'
|
2
2
|
require 'nosey'
|
3
|
+
require 'em-http-request'
|
4
|
+
require 'yajl'
|
5
|
+
require 'time'
|
3
6
|
|
4
7
|
module KingKong
|
8
|
+
# Executes pings within a specificed duration.
|
5
9
|
class Pinger
|
6
10
|
include Logging
|
7
|
-
include
|
8
|
-
|
11
|
+
include EventMachine::Deferrable
|
9
12
|
attr_reader :wait
|
10
13
|
|
11
14
|
def initialize(wait=5,&block)
|
@@ -27,22 +30,24 @@ module KingKong
|
|
27
30
|
@timer.cancel if @timer
|
28
31
|
end
|
29
32
|
|
33
|
+
# Fire this if when a ping completes
|
34
|
+
def on_ping(&block)
|
35
|
+
@on_ping = block
|
36
|
+
end
|
37
|
+
|
30
38
|
private
|
31
39
|
# Add all of the instrumentation callbacks into the ping so we can aggregate it later
|
32
40
|
def ping
|
33
41
|
ping = Ping::Deferrable.new(Ping.default_ttl, sequencer)
|
34
|
-
|
35
42
|
# Register the aggregator to process the ping
|
36
43
|
ping.callback {
|
37
|
-
logger.debug "Ping #{ping}
|
38
|
-
|
44
|
+
logger.debug "Ping #{ping}"
|
45
|
+
@on_ping.call(ping) if @on_ping
|
39
46
|
}
|
40
|
-
|
41
47
|
ping.errback {
|
42
|
-
logger.debug "Ping #{ping}
|
43
|
-
|
48
|
+
logger.debug "Ping #{ping}"
|
49
|
+
@on_ping.call(ping) if @on_ping
|
44
50
|
}
|
45
|
-
|
46
51
|
# Now pass the ping into the block so we can start/stop it
|
47
52
|
@block.call(ping, self)
|
48
53
|
end
|
@@ -51,19 +56,5 @@ module KingKong
|
|
51
56
|
def sequencer
|
52
57
|
@sequencer ||= Ping::Sequencer.new
|
53
58
|
end
|
54
|
-
|
55
|
-
# Process a stinkin ping and report aggregate stats to Nosey
|
56
|
-
def process(ping)
|
57
|
-
nosey.increment 'ping_count'
|
58
|
-
case ping.status
|
59
|
-
when :timed_out
|
60
|
-
nosey.increment 'ping_timed_out_count'
|
61
|
-
when :completed
|
62
|
-
nosey.increment 'ping_completed_count'
|
63
|
-
nosey.avg "ping_avg_latency", ping.latency
|
64
|
-
nosey.min "ping_min_latency", ping.latency
|
65
|
-
nosey.max "ping_max_latency", ping.latency
|
66
|
-
end
|
67
|
-
end
|
68
59
|
end
|
69
60
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'nosey'
|
2
|
+
|
3
|
+
module KingKong
|
4
|
+
module Processor
|
5
|
+
# Base class for processing pings
|
6
|
+
class Base
|
7
|
+
# Enable block configurations
|
8
|
+
def initialize(&block)
|
9
|
+
block.call(self) if block_given?
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def process(ping)
|
14
|
+
raise 'Not Implemented'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Nosey < Base
|
19
|
+
# include ::Nosey::Instrumentation
|
20
|
+
|
21
|
+
def initialize(host='/tmp/kingkong.socket',port=nil)
|
22
|
+
EventMachine::Nosey::SocketServer.start(nosey.report, host, port)
|
23
|
+
end
|
24
|
+
|
25
|
+
def process(ping,name)
|
26
|
+
nosey.increment "#{name}_ping_count"
|
27
|
+
case ping.status
|
28
|
+
when :timed_out
|
29
|
+
nosey.increment "#{name}_ping_timed_out_count"
|
30
|
+
when :completed
|
31
|
+
nosey.increment "#{name}_ping_completed_count"
|
32
|
+
nosey.avg "#{name}_ping_avg_latency", ping.latency
|
33
|
+
nosey.min "#{name}_ping_min_latency", ping.latency
|
34
|
+
nosey.max "#{name}_ping_max_latency", ping.latency
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def nosey
|
39
|
+
@nosey ||= ::Nosey::Probe::Set.new('pinger')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Cube < Base
|
44
|
+
include Logging
|
45
|
+
|
46
|
+
attr_accessor :url
|
47
|
+
|
48
|
+
# TODO use web sockets ...
|
49
|
+
def process(ping, name)
|
50
|
+
http = EM::HttpRequest.new(url).post({
|
51
|
+
:body => Yajl::Encoder.encode([cube_hash(ping, name)]),
|
52
|
+
:head => {
|
53
|
+
'content-type' => 'application/json'
|
54
|
+
}
|
55
|
+
})
|
56
|
+
http.callback{
|
57
|
+
case http.response_header.status
|
58
|
+
when 200..204
|
59
|
+
logger.debug "Successfully reported to Cube at #{url}"
|
60
|
+
else
|
61
|
+
logger.error "Could not report to Cube server: HTTP #{http.response_header.status} : #{http.response}"
|
62
|
+
end
|
63
|
+
}
|
64
|
+
http.errback{
|
65
|
+
logger.error "Could not connect to Cube at #{url}"
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
# Bust out a hash that cube will understand as JSON
|
71
|
+
def cube_hash(ping, name)
|
72
|
+
{
|
73
|
+
'type' => name.to_s,
|
74
|
+
'time' => Time.now.iso8601,
|
75
|
+
'data' => ping.to_hash
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/kingkong/runner.rb
CHANGED
@@ -8,19 +8,25 @@ module KingKong
|
|
8
8
|
# Array of pingers that we're running
|
9
9
|
def ping(name, &block)
|
10
10
|
DSL::Pinger.new(&block).completed do |pinger|
|
11
|
-
pinger.
|
11
|
+
pinger.on_ping do |ping|
|
12
|
+
process ping, name
|
13
|
+
end
|
12
14
|
pingers << pinger
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
#
|
17
|
-
def
|
18
|
-
@
|
18
|
+
# We use this method to pass our pings through a processor
|
19
|
+
def process(ping, name)
|
20
|
+
@processor.call(ping,name) if @processor
|
21
|
+
end
|
22
|
+
|
23
|
+
# Configure the processor that we use to report pings
|
24
|
+
def on_pong(&block)
|
25
|
+
@processor = block
|
19
26
|
end
|
20
27
|
|
21
28
|
# Start all of the pingers given the configurations
|
22
29
|
def start
|
23
|
-
start_socket
|
24
30
|
start_pingers
|
25
31
|
end
|
26
32
|
|
@@ -50,18 +56,6 @@ module KingKong
|
|
50
56
|
end
|
51
57
|
|
52
58
|
private
|
53
|
-
# Fire up the reporting server if a socket (and port, optionally) are given
|
54
|
-
def start_socket
|
55
|
-
EM::Nosey::SocketServer.start(nosey_report, @socket_host, @socket_port) if @socket_host
|
56
|
-
end
|
57
|
-
|
58
|
-
# Get us the nosey report that our nosey socket needs to get the job done son!
|
59
|
-
def nosey_report
|
60
|
-
Nosey::Report.new do |r|
|
61
|
-
r.probe_sets = pingers.map(&:nosey)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
59
|
# Fire up all the pingers
|
66
60
|
def start_pingers
|
67
61
|
pingers.each(&:start)
|
data/lib/kingkong/version.rb
CHANGED
@@ -6,6 +6,10 @@ describe KingKong::Ping do
|
|
6
6
|
KingKong::Ping.new.ttl.should eql(KingKong::Ping.default_ttl)
|
7
7
|
end
|
8
8
|
|
9
|
+
it "should return hash" do
|
10
|
+
KingKong::Ping.new.to_hash.keys.should include(*%w[status latency start_time end_time ttl])
|
11
|
+
end
|
12
|
+
|
9
13
|
context "active" do
|
10
14
|
before(:each) do
|
11
15
|
@ping = KingKong::Ping.new # Open up a pinger
|
@@ -1,29 +1,29 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
describe KingKong::Pinger do
|
4
|
+
include EM::Ventually
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
before(:all) do
|
7
|
+
@@pinged = false
|
8
|
+
@pinger = KingKong::Pinger.new(0.1) do |ping, pinger|
|
9
|
+
@@ping = ping
|
10
|
+
ping.start
|
11
|
+
ping.stop
|
12
|
+
pinger.stop
|
13
|
+
end
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
it "should ping" do
|
17
|
+
@pinger.start
|
18
|
+
ly(:completed) { @@ping.status }
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
it "should stop"
|
22
|
+
it "should start"
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
context "ping aggregation" do
|
25
|
+
it "should process timed-out"
|
26
|
+
it "should process successful"
|
27
|
+
it "should process errors"
|
28
|
+
end
|
29
|
+
end
|
@@ -8,8 +8,6 @@ describe KingKong::Runner do
|
|
8
8
|
@@google_pinged = @@twitter_pinged = false
|
9
9
|
|
10
10
|
@runner = KingKong::Runner.configure do |runner|
|
11
|
-
runner.socket '/tmp/king_kong_test.socket'
|
12
|
-
|
13
11
|
runner.ping(:google).every(0.1).seconds do |ping|
|
14
12
|
ping.start
|
15
13
|
ping.stop
|
@@ -30,8 +28,16 @@ describe KingKong::Runner do
|
|
30
28
|
end
|
31
29
|
|
32
30
|
it "should write data to socket" do
|
31
|
+
nosey = KingKong::Processor::Nosey.new('/tmp/king_kong_test.socket')
|
32
|
+
|
33
|
+
@runner.on_pong do |ping, name|
|
34
|
+
nosey.process ping, name
|
35
|
+
end
|
36
|
+
|
33
37
|
@runner.start
|
34
|
-
KingKong::Test::ReadSocket.start('/tmp/king_kong_test.socket')
|
38
|
+
c = KingKong::Test::ReadSocket.start('/tmp/king_kong_test.socket')
|
39
|
+
c.send_data("READ\nQUIT\n")
|
40
|
+
c.callback{|data|
|
35
41
|
@data = data
|
36
42
|
}
|
37
43
|
ly{ @data }.test{|data| data =~ /max/ }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kingkong
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-09-
|
12
|
+
date: 2011-09-21 00:00:00.000000000 -07:00
|
13
|
+
default_executable:
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: rspec
|
16
|
-
requirement: &
|
17
|
+
requirement: &70240307047860 !ruby/object:Gem::Requirement
|
17
18
|
none: false
|
18
19
|
requirements:
|
19
20
|
- - ! '>='
|
@@ -21,10 +22,10 @@ dependencies:
|
|
21
22
|
version: '0'
|
22
23
|
type: :development
|
23
24
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
+
version_requirements: *70240307047860
|
25
26
|
- !ruby/object:Gem::Dependency
|
26
27
|
name: guard-rspec
|
27
|
-
requirement: &
|
28
|
+
requirement: &70240307047440 !ruby/object:Gem::Requirement
|
28
29
|
none: false
|
29
30
|
requirements:
|
30
31
|
- - ! '>='
|
@@ -32,10 +33,10 @@ dependencies:
|
|
32
33
|
version: '0'
|
33
34
|
type: :development
|
34
35
|
prerelease: false
|
35
|
-
version_requirements: *
|
36
|
+
version_requirements: *70240307047440
|
36
37
|
- !ruby/object:Gem::Dependency
|
37
38
|
name: growl
|
38
|
-
requirement: &
|
39
|
+
requirement: &70240307047020 !ruby/object:Gem::Requirement
|
39
40
|
none: false
|
40
41
|
requirements:
|
41
42
|
- - ! '>='
|
@@ -43,10 +44,10 @@ dependencies:
|
|
43
44
|
version: '0'
|
44
45
|
type: :development
|
45
46
|
prerelease: false
|
46
|
-
version_requirements: *
|
47
|
+
version_requirements: *70240307047020
|
47
48
|
- !ruby/object:Gem::Dependency
|
48
49
|
name: rb-fsevent
|
49
|
-
requirement: &
|
50
|
+
requirement: &70240307046600 !ruby/object:Gem::Requirement
|
50
51
|
none: false
|
51
52
|
requirements:
|
52
53
|
- - ! '>='
|
@@ -54,10 +55,10 @@ dependencies:
|
|
54
55
|
version: '0'
|
55
56
|
type: :development
|
56
57
|
prerelease: false
|
57
|
-
version_requirements: *
|
58
|
+
version_requirements: *70240307046600
|
58
59
|
- !ruby/object:Gem::Dependency
|
59
60
|
name: em-ventually
|
60
|
-
requirement: &
|
61
|
+
requirement: &70240307046180 !ruby/object:Gem::Requirement
|
61
62
|
none: false
|
62
63
|
requirements:
|
63
64
|
- - ! '>='
|
@@ -65,10 +66,10 @@ dependencies:
|
|
65
66
|
version: '0'
|
66
67
|
type: :development
|
67
68
|
prerelease: false
|
68
|
-
version_requirements: *
|
69
|
+
version_requirements: *70240307046180
|
69
70
|
- !ruby/object:Gem::Dependency
|
70
71
|
name: timecop
|
71
|
-
requirement: &
|
72
|
+
requirement: &70240311723120 !ruby/object:Gem::Requirement
|
72
73
|
none: false
|
73
74
|
requirements:
|
74
75
|
- - ! '>='
|
@@ -76,10 +77,10 @@ dependencies:
|
|
76
77
|
version: '0'
|
77
78
|
type: :development
|
78
79
|
prerelease: false
|
79
|
-
version_requirements: *
|
80
|
+
version_requirements: *70240311723120
|
80
81
|
- !ruby/object:Gem::Dependency
|
81
82
|
name: ruby-debug19
|
82
|
-
requirement: &
|
83
|
+
requirement: &70240311722700 !ruby/object:Gem::Requirement
|
83
84
|
none: false
|
84
85
|
requirements:
|
85
86
|
- - ! '>='
|
@@ -87,10 +88,10 @@ dependencies:
|
|
87
88
|
version: '0'
|
88
89
|
type: :development
|
89
90
|
prerelease: false
|
90
|
-
version_requirements: *
|
91
|
+
version_requirements: *70240311722700
|
91
92
|
- !ruby/object:Gem::Dependency
|
92
93
|
name: eventmachine
|
93
|
-
requirement: &
|
94
|
+
requirement: &70240311722280 !ruby/object:Gem::Requirement
|
94
95
|
none: false
|
95
96
|
requirements:
|
96
97
|
- - ! '>='
|
@@ -98,10 +99,10 @@ dependencies:
|
|
98
99
|
version: '0'
|
99
100
|
type: :runtime
|
100
101
|
prerelease: false
|
101
|
-
version_requirements: *
|
102
|
+
version_requirements: *70240311722280
|
102
103
|
- !ruby/object:Gem::Dependency
|
103
104
|
name: nosey
|
104
|
-
requirement: &
|
105
|
+
requirement: &70240311721860 !ruby/object:Gem::Requirement
|
105
106
|
none: false
|
106
107
|
requirements:
|
107
108
|
- - ! '>='
|
@@ -109,16 +110,36 @@ dependencies:
|
|
109
110
|
version: '0'
|
110
111
|
type: :runtime
|
111
112
|
prerelease: false
|
112
|
-
version_requirements: *
|
113
|
+
version_requirements: *70240311721860
|
114
|
+
- !ruby/object:Gem::Dependency
|
115
|
+
name: yajl-ruby
|
116
|
+
requirement: &70240311721440 !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
type: :runtime
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: *70240311721440
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: em-http-request
|
127
|
+
requirement: &70240311721020 !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :runtime
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: *70240311721020
|
113
136
|
description: Have you ever wanted to shoot a message throught Twitter, have your app
|
114
137
|
pick it up, do some work on it, and report how long it takes? KingKong makes it
|
115
138
|
slightly easier to do this with a DSL for writing custom pings and by providing
|
116
139
|
basic reporting facilities that plug into graphing applications like Munin.
|
117
140
|
email:
|
118
141
|
- brad@bradgessler.com
|
119
|
-
executables:
|
120
|
-
- kingkong-munin
|
121
|
-
- kingkong-server
|
142
|
+
executables: []
|
122
143
|
extensions: []
|
123
144
|
extra_rdoc_files: []
|
124
145
|
files:
|
@@ -128,14 +149,13 @@ files:
|
|
128
149
|
- Guardfile
|
129
150
|
- README.md
|
130
151
|
- Rakefile
|
131
|
-
- bin/kingkong-munin
|
132
|
-
- bin/kingkong-server
|
133
152
|
- kingkong.gemspec
|
134
153
|
- lib/kingkong.rb
|
135
154
|
- lib/kingkong/cli.rb
|
136
155
|
- lib/kingkong/logging.rb
|
137
156
|
- lib/kingkong/ping.rb
|
138
157
|
- lib/kingkong/pinger.rb
|
158
|
+
- lib/kingkong/processor.rb
|
139
159
|
- lib/kingkong/runner.rb
|
140
160
|
- lib/kingkong/version.rb
|
141
161
|
- spec/lib/kingkong/ping_spec.rb
|
@@ -143,6 +163,7 @@ files:
|
|
143
163
|
- spec/lib/kingkong/runner_spec.rb
|
144
164
|
- spec/lib/kingkong_spec.rb
|
145
165
|
- spec/spec_helper.rb
|
166
|
+
has_rdoc: true
|
146
167
|
homepage: ''
|
147
168
|
licenses: []
|
148
169
|
post_install_message:
|
@@ -163,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
184
|
version: '0'
|
164
185
|
requirements: []
|
165
186
|
rubyforge_project: kingkong
|
166
|
-
rubygems_version: 1.
|
187
|
+
rubygems_version: 1.6.2
|
167
188
|
signing_key:
|
168
189
|
specification_version: 3
|
169
190
|
summary: Build complex network application health checks with Ruby and EventMachine
|
data/bin/kingkong-munin
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'socket'
|
4
|
-
require 'yaml'
|
5
|
-
|
6
|
-
puts case ARGV.first
|
7
|
-
when /config/
|
8
|
-
%(graph_title Result latency
|
9
|
-
graph_category App
|
10
|
-
graph_vlabel load
|
11
|
-
load.label load)
|
12
|
-
else
|
13
|
-
stats = YAML.load UNIXSocket.new("/tmp/kingkong.socket").gets("\r\n")
|
14
|
-
%(load.value #{stats[:avg]})
|
15
|
-
end
|
16
|
-
|
17
|
-
# TODO - Message throughput
|
18
|
-
# TODO - Message latency (min/max/avg)
|