zabbix_receiver 0.0.1 → 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.
- checksums.yaml +4 -4
- data/bin/zabbix_receiver +3 -0
- data/lib/zabbix_receiver/cli.rb +70 -0
- data/lib/zabbix_receiver/output/stdout.rb +16 -0
- data/lib/zabbix_receiver/server.rb +7 -103
- data/lib/zabbix_receiver/version.rb +1 -1
- data/lib/zabbix_receiver/worker.rb +80 -0
- data/lib/zabbix_receiver.rb +2 -0
- data/zabbix_receiver.gemspec +2 -0
- metadata +22 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9b18abfc85a6f0c988942665b7764545131a0e5
|
4
|
+
data.tar.gz: e4ff56edf7bbfd4ba960881f25db18ab9156cbda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39fcb740b7dc74ea719ac4dc330e52f28aa9202db534669527eb1b4b7f80aee4d3319f49dbdf6808518fe9a0d091c369d092c5cdbf113275e562e745beba5356
|
7
|
+
data.tar.gz: 4d755551630c848207a7174b93804c9ef63244197666da6d7109a597e21d41bc7df077a8e372e641d616d4d00950641dc7a2d3df2986b4a5d158810db22023ea
|
data/bin/zabbix_receiver
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'zabbix_receiver'
|
2
|
+
require 'serverengine'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
module ZabbixReceiver
|
6
|
+
class CLI
|
7
|
+
REQUIRED_OPTIONS = %i(daemonize workers proxy_to_host proxy_to_port bind port)
|
8
|
+
|
9
|
+
def self.start(argv)
|
10
|
+
self.new(argv).start
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(argv)
|
14
|
+
load_options(argv)
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
options = {
|
19
|
+
worker_type: 'process',
|
20
|
+
}.merge(@options)
|
21
|
+
|
22
|
+
se = ServerEngine.create(Server, Worker, options)
|
23
|
+
se.run
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def load_options(argv)
|
29
|
+
argv_for_main, argv_for_output = argv.slice_before('--').to_a
|
30
|
+
argv_for_output.shift
|
31
|
+
|
32
|
+
@options = {
|
33
|
+
daemonize: false,
|
34
|
+
workers: 1,
|
35
|
+
bind: '0.0.0.0',
|
36
|
+
port: 10051,
|
37
|
+
proxy_to_port: 10051,
|
38
|
+
to: 'stdout',
|
39
|
+
}
|
40
|
+
|
41
|
+
parser = OptionParser.new
|
42
|
+
parser.on('--daemonize') {|v| @options[:daemonize] = true }
|
43
|
+
parser.on('--log=VAL', 'default: STDERR') {|v| @options[:log] = v }
|
44
|
+
parser.on('--pid-path=VAL') {|v| @options[:pid_path] = v }
|
45
|
+
parser.on('--workers=VAL') {|v| @options[:worker] = v }
|
46
|
+
parser.on('--bind=VAL') {|v| @options[:bind] = v }
|
47
|
+
parser.on('--port=VAL') {|v| @options[:port] = v }
|
48
|
+
parser.on('--proxy-to-host=VAL') {|v| @options[:proxy_to_host] = v }
|
49
|
+
parser.on('--proxy-to-port=VAL') {|v| @options[:proxy_to_port] = v }
|
50
|
+
parser.on('--to=VAL') {|v| @options[:to] = v }
|
51
|
+
parser.on('--log-level=VAL') {|v| @options[:log_level] = v }
|
52
|
+
parser.parse!(argv_for_main)
|
53
|
+
|
54
|
+
REQUIRED_OPTIONS.each do |key|
|
55
|
+
unless @options.has_key?(key)
|
56
|
+
raise "--#{key.to_s.split('_').join('-')} option is required."
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
@options[:output_class] = output_class
|
61
|
+
@options[:output_options] = @options[:output_class].parse_options(argv_for_output)
|
62
|
+
end
|
63
|
+
|
64
|
+
def output_class
|
65
|
+
require "zabbix_receiver/output/#{@options[:to]}"
|
66
|
+
class_name = @options[:to].split('_').map {|v| v.capitalize }.join
|
67
|
+
ZabbixReceiver::Output.const_get(class_name)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -1,110 +1,14 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'logger'
|
3
|
-
|
4
1
|
module ZabbixReceiver
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(options = {})
|
9
|
-
@options = {
|
10
|
-
proxy_to: {
|
11
|
-
port: 10051,
|
12
|
-
},
|
13
|
-
}.merge(options)
|
14
|
-
|
15
|
-
validate_options
|
16
|
-
|
17
|
-
@logger = options[:logger] || Logger.new(StringIO.new)
|
18
|
-
|
19
|
-
@blocks_on_receive_sender_data = []
|
20
|
-
end
|
21
|
-
|
22
|
-
def on_receive_sender_data(&block)
|
23
|
-
@blocks_on_receive_sender_data << block
|
24
|
-
end
|
25
|
-
|
26
|
-
def start(address, port)
|
27
|
-
server = TCPServer.open(address, port)
|
28
|
-
|
29
|
-
while true
|
30
|
-
Thread.start(server.accept) do |f|
|
31
|
-
accept(f)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def accept(f)
|
37
|
-
request = parse(f)
|
38
|
-
|
39
|
-
@logger.debug "Request: #{request}"
|
40
|
-
|
41
|
-
request_type = request['request']
|
2
|
+
module Server
|
3
|
+
attr_reader :sock
|
42
4
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
when 'sender data'
|
47
|
-
@blocks_on_receive_sender_data.each do |block|
|
48
|
-
block.call(request)
|
49
|
-
end
|
5
|
+
def before_run
|
6
|
+
bind = config[:bind]
|
7
|
+
port = config[:port]
|
50
8
|
|
51
|
-
|
52
|
-
|
53
|
-
respond_with(f, {
|
54
|
-
"response" => "success",
|
55
|
-
"info" => "Processed #{count} Failed 0 Total #{count} Seconds spent 0.000000"
|
56
|
-
})
|
57
|
-
else
|
58
|
-
@logger.error "Unknown request type (#{request_type})"
|
59
|
-
end
|
60
|
-
ensure
|
61
|
-
f && f.close
|
62
|
-
end
|
63
|
-
|
64
|
-
def proxy_request(f)
|
65
|
-
f.seek(0)
|
66
|
-
|
67
|
-
socket = TCPSocket.open(
|
68
|
-
@options[:proxy_to][:host],
|
69
|
-
@options[:proxy_to][:port],
|
70
|
-
)
|
71
|
-
socket.write(f.read)
|
72
|
-
f.write(socket.read)
|
73
|
-
ensure
|
74
|
-
socket && socket.close
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def parse(f)
|
80
|
-
f.seek(0)
|
81
|
-
|
82
|
-
unless f.read(5) == ZABBIX_HEADER
|
83
|
-
@logger.error "Invalid Zabbix request"
|
84
|
-
return
|
85
|
-
end
|
86
|
-
|
87
|
-
length = f.read(8).unpack('q').first
|
88
|
-
body = f.read
|
89
|
-
unless body.size == length
|
90
|
-
@logger.error "Length mismatch"
|
91
|
-
return
|
92
|
-
end
|
93
|
-
|
94
|
-
JSON.parse(body)
|
95
|
-
end
|
96
|
-
|
97
|
-
def respond_with(f, payload)
|
98
|
-
payload = payload.to_json
|
99
|
-
f.write(ZABBIX_HEADER + [payload.bytesize].pack('q') + payload)
|
100
|
-
end
|
9
|
+
logger.info "Listening on #{bind}:#{port}..."
|
101
10
|
|
102
|
-
|
103
|
-
[:host, :port].each do |k|
|
104
|
-
unless @options[:proxy_to][k]
|
105
|
-
raise "options[:proxy_to][:#{k}] is required."
|
106
|
-
end
|
107
|
-
end
|
11
|
+
@sock = TCPServer.open(bind, port)
|
108
12
|
end
|
109
13
|
end
|
110
14
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module ZabbixReceiver
|
4
|
+
module Worker
|
5
|
+
ZABBIX_HEADER = "ZBXD\x01"
|
6
|
+
|
7
|
+
def run
|
8
|
+
@output = config[:output_class].new(logger, config[:output_options])
|
9
|
+
|
10
|
+
until @stop
|
11
|
+
process(server.sock.accept)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def stop
|
16
|
+
@stop = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def process(c)
|
20
|
+
request_body = c.read
|
21
|
+
request = parse(request_body)
|
22
|
+
logger.debug "Request: #{request}"
|
23
|
+
request_type = request['request']
|
24
|
+
|
25
|
+
case request_type
|
26
|
+
when 'active checks'
|
27
|
+
c.write(proxy_request(request_body))
|
28
|
+
when 'sender data'
|
29
|
+
@output.receive_sender_data(request)
|
30
|
+
|
31
|
+
count = request['data'].size
|
32
|
+
|
33
|
+
respond_with(c, {
|
34
|
+
"response" => "success",
|
35
|
+
"info" => "Processed #{count} Failed 0 Total #{count} Seconds spent 0.000000"
|
36
|
+
})
|
37
|
+
else
|
38
|
+
logger.error "Unknown request type (#{request_type})"
|
39
|
+
end
|
40
|
+
ensure
|
41
|
+
c.close
|
42
|
+
end
|
43
|
+
|
44
|
+
def proxy_request(request_body)
|
45
|
+
socket = TCPSocket.open(
|
46
|
+
config[:proxy_to_host],
|
47
|
+
config[:proxy_to_port],
|
48
|
+
)
|
49
|
+
socket.write(request_body)
|
50
|
+
socket.read
|
51
|
+
ensure
|
52
|
+
socket && socket.close
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def parse(request_body)
|
58
|
+
request = StringIO.new(request_body)
|
59
|
+
|
60
|
+
unless request.read(5) == ZABBIX_HEADER
|
61
|
+
logger.error "Invalid Zabbix request"
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
65
|
+
length = request.read(8).unpack('q').first
|
66
|
+
body = request.read
|
67
|
+
unless body.size == length
|
68
|
+
logger.error "Length mismatch"
|
69
|
+
return
|
70
|
+
end
|
71
|
+
|
72
|
+
JSON.parse(body)
|
73
|
+
end
|
74
|
+
|
75
|
+
def respond_with(f, payload)
|
76
|
+
payload = payload.to_json
|
77
|
+
f.write(ZABBIX_HEADER + [payload.bytesize].pack('q') + payload)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/zabbix_receiver.rb
CHANGED
data/zabbix_receiver.gemspec
CHANGED
@@ -17,6 +17,8 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
+
spec.add_development_dependency "serverengine"
|
21
|
+
|
20
22
|
spec.add_development_dependency "bundler", "~> 1.7"
|
21
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
22
24
|
spec.add_development_dependency "rspec"
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zabbix_receiver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryota Arai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: serverengine
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -55,7 +69,8 @@ dependencies:
|
|
55
69
|
description:
|
56
70
|
email:
|
57
71
|
- ryota-arai@cookpad.com
|
58
|
-
executables:
|
72
|
+
executables:
|
73
|
+
- zabbix_receiver
|
59
74
|
extensions: []
|
60
75
|
extra_rdoc_files: []
|
61
76
|
files:
|
@@ -65,9 +80,13 @@ files:
|
|
65
80
|
- LICENSE.txt
|
66
81
|
- README.md
|
67
82
|
- Rakefile
|
83
|
+
- bin/zabbix_receiver
|
68
84
|
- lib/zabbix_receiver.rb
|
85
|
+
- lib/zabbix_receiver/cli.rb
|
86
|
+
- lib/zabbix_receiver/output/stdout.rb
|
69
87
|
- lib/zabbix_receiver/server.rb
|
70
88
|
- lib/zabbix_receiver/version.rb
|
89
|
+
- lib/zabbix_receiver/worker.rb
|
71
90
|
- spec/spec_helper.rb
|
72
91
|
- spec/zabbix_receiver/server_spec.rb
|
73
92
|
- zabbix_receiver.gemspec
|