amqp-tools 0.0.2
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/amqp-tools.gemspec +23 -0
- data/bin/amqp-json-udp-acceptor +89 -0
- data/bin/amqp-linux-health-monitor +69 -0
- data/bin/amqp-send +124 -0
- metadata +64 -0
data/amqp-tools.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "amqp-tools"
|
6
|
+
s.version = "0.0.2"
|
7
|
+
s.date = Date.today.to_s
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Paul Asmuth"]
|
10
|
+
s.email = ["paul@paulasmuth.com"]
|
11
|
+
s.homepage = "http://github.com/paulasmuth/amqp-tools"
|
12
|
+
s.summary = %q{command line tools for AMQP/RabbitMQ}
|
13
|
+
s.description = %q{command line tools for AMQP/RabbitMQ}
|
14
|
+
s.licenses = ["MIT"]
|
15
|
+
|
16
|
+
s.add_dependency "amqp", ">= 0.8.9"
|
17
|
+
|
18
|
+
s.bindir = "bin"
|
19
|
+
s.executables = ["amqp-send", "amqp-linux-health-monitor", "amqp-json-udp-acceptor"]
|
20
|
+
s.files = `git ls-files`.split("\n") - [".gitignore", ".rspec", ".travis.yml"]
|
21
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "amqp"
|
6
|
+
rescue LoadError
|
7
|
+
puts "can't require amqp gem, please run"
|
8
|
+
puts
|
9
|
+
puts " $ gem install amqp"
|
10
|
+
puts
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
require "eventmachine"
|
15
|
+
require "json"
|
16
|
+
|
17
|
+
class UDPAcceptor < EventMachine::Connection
|
18
|
+
|
19
|
+
def self.run(opts = {})
|
20
|
+
EventMachine.run do
|
21
|
+
error_handler = proc do |*args|
|
22
|
+
log("[error] AMQP Error")
|
23
|
+
shutdown(1)
|
24
|
+
end
|
25
|
+
|
26
|
+
amqp_opts = {
|
27
|
+
:host => opts[:amqp_host],
|
28
|
+
:port => (opts[:amqp_port] || 5672),
|
29
|
+
:timeout => 1,
|
30
|
+
:on_possible_authentication_failure => error_handler,
|
31
|
+
:on_tcp_connection_failure => error_handler
|
32
|
+
}
|
33
|
+
|
34
|
+
begin
|
35
|
+
$amqp = AMQP.start(amqp_opts)
|
36
|
+
rescue AMQP::PossibleAuthenticationFailureError, AMQP::TCPConnectionFailed
|
37
|
+
shutdown(1)
|
38
|
+
end
|
39
|
+
|
40
|
+
EventMachine.open_datagram_socket(
|
41
|
+
"0.0.0.0", opts[:listen_port], self)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.log(msg)
|
46
|
+
puts "[#{Time.now.strftime("%F %T")}] #{msg}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.shutdown(code = 0)
|
50
|
+
if EventMachine.reactor_running?
|
51
|
+
EventMachine.stop{ exit(code) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def post_init
|
56
|
+
@amqp_channel = AMQP::Channel.new($amqp)
|
57
|
+
@amqp_exchange = @amqp_channel.default_exchange
|
58
|
+
self.class.log("Listening...")
|
59
|
+
end
|
60
|
+
|
61
|
+
def receive_data(chunk)
|
62
|
+
if chunk[0] == '{'
|
63
|
+
channel = JSON.parse(chunk)["channel"] rescue nil
|
64
|
+
return unless channel
|
65
|
+
self.class.log "#{channel} => #{chunk}"
|
66
|
+
@amqp_exchange.publish chunk, :routing_key => channel
|
67
|
+
else
|
68
|
+
self.class.log "[error] not a json object: #{chunk[0..60]}"
|
69
|
+
return
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
unless ENV["LISTEN_PORT"] && ENV["AMQP_HOST"]
|
76
|
+
puts "usage: [ENV] #{$0}"
|
77
|
+
puts
|
78
|
+
puts "Environment Variables:"
|
79
|
+
puts " AMQP_HOST=<addr> amqp server address (mandatory)"
|
80
|
+
puts " AMQP_PORT=<port> amqp server port"
|
81
|
+
puts " LISTEN_PORT=<port> start udp listener on this port (mandatory)"
|
82
|
+
puts
|
83
|
+
exit 1
|
84
|
+
end
|
85
|
+
|
86
|
+
UDPAcceptor.run(
|
87
|
+
:amqp_host => "firehose",
|
88
|
+
:amqp_port => "5672",
|
89
|
+
:listen_port => 2323)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# This scripts sends a JSON message containing system health
|
4
|
+
# information to an AMQP broker.
|
5
|
+
#
|
6
|
+
# Usage:
|
7
|
+
# $ ./linux_health_monitor.sh [amqp-send options]
|
8
|
+
# e.g.
|
9
|
+
# $ ./linux_health_monitor.sh -h localhost --routing-key serverhealth
|
10
|
+
#
|
11
|
+
# The JSON body will look like this:
|
12
|
+
# {
|
13
|
+
# "hostname": "my-hostname",
|
14
|
+
# "uptime": 1231523,
|
15
|
+
# "load_avg": [0.32, 0.16, 0.13],
|
16
|
+
# "mem": { "total": 4069, "free": 1096 },
|
17
|
+
# "swap": { "total": 0, "free": 0 },
|
18
|
+
# "disk_usage": "43%"
|
19
|
+
# }
|
20
|
+
|
21
|
+
if [[ $# -lt 1 ]]; then
|
22
|
+
echo "usage: $0 [amqp-send options]"
|
23
|
+
exit 1
|
24
|
+
fi
|
25
|
+
|
26
|
+
for cmd in df wc nc sed grep amqp-send; do
|
27
|
+
which $cmd &> /dev/null
|
28
|
+
|
29
|
+
if [ $? != 0 ]; then
|
30
|
+
echo "error: command not found: $cmd"
|
31
|
+
exit 1
|
32
|
+
fi
|
33
|
+
done
|
34
|
+
|
35
|
+
data=$(
|
36
|
+
|
37
|
+
# hostname
|
38
|
+
echo "\"hostname\": \"$(hostname)\","
|
39
|
+
|
40
|
+
# uptime
|
41
|
+
cat /proc/uptime | \
|
42
|
+
sed -e 's/^\([0-9]\+\.[0-9]\+\).*/"uptime": \1,/'
|
43
|
+
|
44
|
+
# load_avg
|
45
|
+
cat /proc/loadavg | \
|
46
|
+
sed -e 's/^\([0-9]\+\.[0-9]\+\) \([0-9]\+\.[0-9]\+\) \([0-9]\+\.[0-9]\+\).*/"load_avg": [\1, \2, \3],/'
|
47
|
+
|
48
|
+
# mem usage
|
49
|
+
cat /proc/meminfo | \
|
50
|
+
grep -E '^(MemTotal|MemFree)' | \
|
51
|
+
sed -e 's/Mem//' -e 's/Total:[^0-9]\+\([0-9]\+\).*/"mem": { "total": \1,/' \
|
52
|
+
-e 's/Free:[^0-9]\+\([0-9]\+\).*/"free": \1 },/'
|
53
|
+
|
54
|
+
# swap_usage
|
55
|
+
cat /proc/meminfo | \
|
56
|
+
grep -E '^(SwapTotal|SwapFree)' | \
|
57
|
+
sed -e 's/Swap//' -e 's/Total:[^0-9]\+\([0-9]\+\).*/"swap": { "total": \1,/' \
|
58
|
+
-e 's/Free:[^0-9]\+\([0-9]\+\).*/"free": \1 },/'
|
59
|
+
|
60
|
+
# disk usage
|
61
|
+
df | grep -E '\/$' | \
|
62
|
+
sed -e 's/.* \([0-9]\+%\) .*/"disk_usage": "\1"/'
|
63
|
+
|
64
|
+
)
|
65
|
+
|
66
|
+
echo "{ $data }" | sed -e ':x;N;$!bx;s/\n/ /g' | \
|
67
|
+
amqp-send $@
|
68
|
+
|
69
|
+
exit $?
|
data/bin/amqp-send
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "amqp"
|
6
|
+
rescue LoadError
|
7
|
+
puts "can't require amqp gem, please run"
|
8
|
+
puts
|
9
|
+
puts " $ gem install amqp"
|
10
|
+
puts
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
require "eventmachine"
|
15
|
+
require 'optparse'
|
16
|
+
|
17
|
+
opts = {
|
18
|
+
:host => ENV["AMQP_HOST"],
|
19
|
+
:port => ENV["AMQP_PORT"]
|
20
|
+
}
|
21
|
+
|
22
|
+
opt_parser = OptionParser.new do |base|
|
23
|
+
|
24
|
+
base.on("-h", "--host HOST", "AMQP server host (mandatory)") do |arg|
|
25
|
+
opts[:host] = arg
|
26
|
+
end
|
27
|
+
|
28
|
+
base.on("-p", "--port PORT", "AMQP server port") do |arg|
|
29
|
+
opts[:port] = arg
|
30
|
+
end
|
31
|
+
|
32
|
+
base.on("--routing-key KEY", "AMQP routing key (mandatory)") do |arg|
|
33
|
+
opts[:routing_key] = arg
|
34
|
+
end
|
35
|
+
|
36
|
+
#base.on("--exchange EXCHANGE", "AMQP exchange") do |arg|
|
37
|
+
# opts[:exchange] = arg
|
38
|
+
#end
|
39
|
+
|
40
|
+
base.on("-f", "--file FILE", "read payload from file") do |arg|
|
41
|
+
opts[:file] = arg
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
opt_parser.parse!
|
47
|
+
|
48
|
+
examples = %Q{
|
49
|
+
$ echo "fnord" | amqpsend -h localhost --routing-key my_channel
|
50
|
+
$ amqpsend -h localhost --routing-key my_channel -f /tmp/somefile
|
51
|
+
}
|
52
|
+
|
53
|
+
mandatory_opts = %w(host routing_key)
|
54
|
+
mandatory_opts.each do |opt|
|
55
|
+
unless opts[opt.to_sym]
|
56
|
+
puts "[error] missing option: #{opt}\n\n"
|
57
|
+
puts "Usage: #{$0} [options]\n\nOptions:\n"
|
58
|
+
puts opt_parser.summarize
|
59
|
+
puts "\nThe following environment variables may also be set:"
|
60
|
+
puts " AMQP_HOST, AMQP_PORT"
|
61
|
+
puts "\nIf no -f option is specified the payload will be read from STDIN\n\n"
|
62
|
+
puts "Examples: #{examples}"
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
error_handler = proc do |*args|
|
68
|
+
puts("[error] AMQP Error")
|
69
|
+
exit 1
|
70
|
+
end
|
71
|
+
|
72
|
+
amqp_opts = {
|
73
|
+
:host => opts[:host],
|
74
|
+
:port => opts[:port] || 5672,
|
75
|
+
:timeout => 1,
|
76
|
+
:on_possible_authentication_failure => error_handler,
|
77
|
+
:on_tcp_connection_failure => error_handler
|
78
|
+
}
|
79
|
+
|
80
|
+
publish_opts = {
|
81
|
+
:routing_key => opts[:routing_key],
|
82
|
+
:auto_delete => true
|
83
|
+
}
|
84
|
+
|
85
|
+
payload = if opts[:file]
|
86
|
+
IO.read(opts[:file])
|
87
|
+
else
|
88
|
+
unless IO.select([STDIN], [], [], 0.01)
|
89
|
+
puts "Reading from STDIN..."
|
90
|
+
end
|
91
|
+
|
92
|
+
STDIN.read
|
93
|
+
end
|
94
|
+
|
95
|
+
if !payload || payload.size == 0
|
96
|
+
puts("[error] no payload (read from STDIN)")
|
97
|
+
exit 1
|
98
|
+
end
|
99
|
+
|
100
|
+
EventMachine.run do
|
101
|
+
amqp = AMQP.start(amqp_opts)
|
102
|
+
amqp_channel = AMQP::Channel.new(amqp)
|
103
|
+
amqp_exchange = amqp_channel.default_exchange
|
104
|
+
|
105
|
+
amqp_exchange.publish(payload, publish_opts) do
|
106
|
+
amqp.close { exit 0 }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
unless ENV["LISTEN_PORT"] && ENV["AMQP_HOST"]
|
111
|
+
puts "usage: [ENV] #{$0}"
|
112
|
+
puts
|
113
|
+
puts "Environment Variables:"
|
114
|
+
puts " AMQP_HOST=<addr> amqp server address (mandatory)"
|
115
|
+
puts " AMQP_PORT=<port> amqp server port"
|
116
|
+
puts " AMQP_RKEY=<key> amqp routing key (mandatory)"
|
117
|
+
puts
|
118
|
+
exit 1
|
119
|
+
end
|
120
|
+
|
121
|
+
UDPAcceptor.run(
|
122
|
+
:amqp_host => "firehose",
|
123
|
+
:amqp_port => "5672",
|
124
|
+
:listen_port => 2323)
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: amqp-tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Paul Asmuth
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: amqp
|
16
|
+
requirement: &13890980 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.8.9
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *13890980
|
25
|
+
description: command line tools for AMQP/RabbitMQ
|
26
|
+
email:
|
27
|
+
- paul@paulasmuth.com
|
28
|
+
executables:
|
29
|
+
- amqp-send
|
30
|
+
- amqp-linux-health-monitor
|
31
|
+
- amqp-json-udp-acceptor
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- amqp-tools.gemspec
|
36
|
+
- bin/amqp-json-udp-acceptor
|
37
|
+
- bin/amqp-linux-health-monitor
|
38
|
+
- bin/amqp-send
|
39
|
+
homepage: http://github.com/paulasmuth/amqp-tools
|
40
|
+
licenses:
|
41
|
+
- MIT
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.8.17
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: command line tools for AMQP/RabbitMQ
|
64
|
+
test_files: []
|