logstash-input-ganglia 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +4 -4
- data/lib/logstash/inputs/ganglia.rb +22 -24
- data/logstash-input-ganglia.gemspec +7 -4
- data/spec/inputs/ganglia_spec.rb +66 -1
- data/spec/spec_helper.rb +48 -0
- data/spec/support/client.rb +21 -0
- metadata +42 -18
- data/.gitignore +0 -4
- data/Rakefile +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71cfd820410aba1f3fcee3e1d1cd963192d863c1
|
4
|
+
data.tar.gz: 80457ceb8255e222c9a4263205b4f180359d69ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04113be3367ca462c08d3a69b79aede4eecc09d97f0619c8cddb7f0663d7effa2a29a7d752f05abd6fa6c61cd53093d0d7a3d33d7f15e5349056e6f3b1f221b3
|
7
|
+
data.tar.gz: 46ab77ddc51305944c38dd511e3307fcb7a97f74bcb6c04f6313ede4ce1e3da22e6a0fb9e165066e3c18ece35e60ea4d1d899dabed5cdd61b630adaad859785d
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Logstash Plugin
|
2
2
|
|
3
|
-
This is a plugin for [Logstash](https://github.com/
|
3
|
+
This is a plugin for [Logstash](https://github.com/elastic/logstash).
|
4
4
|
|
5
5
|
It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
|
6
6
|
|
7
7
|
## Documentation
|
8
8
|
|
9
|
-
Logstash provides infrastructure to automatically generate documentation for this plugin. We use the asciidoc format to write documentation so any comments in the source code will be first converted into asciidoc and then into html. All plugin documentation are placed under one [central location](http://www.
|
9
|
+
Logstash provides infrastructure to automatically generate documentation for this plugin. We use the asciidoc format to write documentation so any comments in the source code will be first converted into asciidoc and then into html. All plugin documentation are placed under one [central location](http://www.elastic.co/guide/en/logstash/current/).
|
10
10
|
|
11
11
|
- For formatting code or config example, you can use the asciidoc `[source,ruby]` directive
|
12
|
-
- For more asciidoc formatting tips, see the excellent reference here https://github.com/
|
12
|
+
- For more asciidoc formatting tips, see the excellent reference here https://github.com/elastic/docs#asciidoc-guide
|
13
13
|
|
14
14
|
## Need Help?
|
15
15
|
|
@@ -83,4 +83,4 @@ Programming is not a required skill. Whatever you've seen about open source and
|
|
83
83
|
|
84
84
|
It is more important to the community that you are able to contribute.
|
85
85
|
|
86
|
-
For more information about contributing, see the [CONTRIBUTING](https://github.com/
|
86
|
+
For more information about contributing, see the [CONTRIBUTING](https://github.com/elastic/logstash/blob/master/CONTRIBUTING.md) file.
|
@@ -1,11 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "date"
|
3
|
-
require "logstash/filters/grok"
|
4
|
-
require "logstash/filters/date"
|
5
3
|
require "logstash/inputs/ganglia/gmondpacket"
|
6
4
|
require "logstash/inputs/base"
|
7
5
|
require "logstash/namespace"
|
8
6
|
require "socket"
|
7
|
+
require "stud/interval"
|
9
8
|
|
10
9
|
# Read ganglia packets from the network via udp
|
11
10
|
#
|
@@ -24,7 +23,6 @@ class LogStash::Inputs::Ganglia < LogStash::Inputs::Base
|
|
24
23
|
public
|
25
24
|
def initialize(params)
|
26
25
|
super
|
27
|
-
@shutdown_requested = false
|
28
26
|
BasicSocket.do_not_reverse_lookup = true
|
29
27
|
end # def initialize
|
30
28
|
|
@@ -37,11 +35,11 @@ class LogStash::Inputs::Ganglia < LogStash::Inputs::Base
|
|
37
35
|
begin
|
38
36
|
udp_listener(output_queue)
|
39
37
|
rescue => e
|
40
|
-
if
|
38
|
+
if !stop?
|
41
39
|
@logger.warn("ganglia udp listener died",
|
42
40
|
:address => "#{@host}:#{@port}", :exception => e,
|
43
41
|
:backtrace => e.backtrace)
|
44
|
-
|
42
|
+
Stud.stoppable_sleep(5) { stop? }
|
45
43
|
retry
|
46
44
|
end
|
47
45
|
end # begin
|
@@ -51,17 +49,24 @@ class LogStash::Inputs::Ganglia < LogStash::Inputs::Base
|
|
51
49
|
def udp_listener(output_queue)
|
52
50
|
@logger.info("Starting ganglia udp listener", :address => "#{@host}:#{@port}")
|
53
51
|
|
54
|
-
if @udp
|
55
|
-
@udp.close_read
|
56
|
-
@udp.close_write
|
57
|
-
end
|
52
|
+
@udp.close if @udp
|
58
53
|
|
59
54
|
@udp = UDPSocket.new(Socket::AF_INET)
|
60
55
|
@udp.bind(@host, @port)
|
61
56
|
|
62
57
|
@metadata = Hash.new if @metadata.nil?
|
63
|
-
|
64
|
-
packet
|
58
|
+
while !stop?
|
59
|
+
packet = ""
|
60
|
+
begin
|
61
|
+
packet, client = @udp.recvfrom_nonblock(9000)
|
62
|
+
rescue IO::WaitReadable
|
63
|
+
# The socket is still not active and readable so the
|
64
|
+
# read operation fails
|
65
|
+
packet = ""
|
66
|
+
end
|
67
|
+
# recvfrom_nonblock return packet == String.empty? when no data is in the buffers,
|
68
|
+
# we reused this same error code for IO:WaitReadable exception handler.
|
69
|
+
next if packet.empty?
|
65
70
|
# TODO(sissel): make this a codec...
|
66
71
|
e = parse_packet(packet)
|
67
72
|
unless e.nil?
|
@@ -77,19 +82,16 @@ class LogStash::Inputs::Ganglia < LogStash::Inputs::Base
|
|
77
82
|
private
|
78
83
|
|
79
84
|
public
|
80
|
-
def
|
81
|
-
@shutdown_requested = true
|
85
|
+
def stop
|
82
86
|
close_udp
|
83
|
-
finished
|
84
87
|
end
|
85
88
|
|
86
89
|
private
|
87
90
|
def close_udp
|
88
91
|
if @udp
|
89
|
-
@udp.
|
90
|
-
@udp
|
92
|
+
@udp.close
|
93
|
+
@udp = nil
|
91
94
|
end
|
92
|
-
@udp = nil
|
93
95
|
end
|
94
96
|
|
95
97
|
public
|
@@ -109,15 +111,11 @@ class LogStash::Inputs::Ganglia < LogStash::Inputs::Base
|
|
109
111
|
|
110
112
|
# Check if it was a valid data request
|
111
113
|
return nil unless data
|
112
|
-
|
113
|
-
event=LogStash::Event.new
|
114
|
-
|
115
|
-
data["program"] = "ganglia"
|
116
|
-
event["log_host"] = data["hostname"]
|
114
|
+
props={ "program" => "ganglia", "log_host" => data["hostname"] }
|
117
115
|
%w{dmax tmax slope type units}.each do |info|
|
118
|
-
|
116
|
+
props[info] = @metadata[data["name"]][info]
|
119
117
|
end
|
120
|
-
return
|
118
|
+
return LogStash::Event.new(props)
|
121
119
|
else
|
122
120
|
# Skipping unknown packet types
|
123
121
|
return nil
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-input-ganglia'
|
4
|
-
s.version = '
|
4
|
+
s.version = '2.0.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Read ganglia packets from the network via udp"
|
7
7
|
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.require_paths = ["lib"]
|
12
12
|
|
13
13
|
# Files
|
14
|
-
s.files =
|
14
|
+
s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
|
15
15
|
|
16
16
|
# Tests
|
17
17
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
@@ -20,9 +20,12 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "input" }
|
21
21
|
|
22
22
|
# Gem dependencies
|
23
|
-
s.add_runtime_dependency "logstash-core",
|
24
|
-
|
23
|
+
s.add_runtime_dependency "logstash-core", "~> 2.0.0.snapshot"
|
24
|
+
s.add_runtime_dependency 'stud', '~> 0.0.22'
|
25
25
|
s.add_runtime_dependency 'logstash-codec-plain'
|
26
|
+
|
26
27
|
s.add_development_dependency 'logstash-devutils'
|
28
|
+
s.add_development_dependency 'gmetric'
|
29
|
+
|
27
30
|
end
|
28
31
|
|
data/spec/inputs/ganglia_spec.rb
CHANGED
@@ -1 +1,66 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "../spec_helper"
|
3
|
+
require "logstash/plugin"
|
4
|
+
require "logstash/event"
|
5
|
+
|
6
|
+
describe LogStash::Inputs::Ganglia do
|
7
|
+
|
8
|
+
let(:properties) { {:name => "foo" } }
|
9
|
+
let(:event) { LogStash::Event.new(properties) }
|
10
|
+
|
11
|
+
it "should register without errors" do
|
12
|
+
plugin = LogStash::Plugin.lookup("input", "ganglia").new({})
|
13
|
+
expect { plugin.register }.to_not raise_error
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "when interrupting the plugin" do
|
17
|
+
it_behaves_like "an interruptible input plugin" do
|
18
|
+
let(:config) { {} }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "connection" do
|
23
|
+
let(:nevents) { 10 }
|
24
|
+
let(:port) { rand(1024..65532) }
|
25
|
+
|
26
|
+
let(:conf) do
|
27
|
+
<<-CONFIG
|
28
|
+
input {
|
29
|
+
ganglia {
|
30
|
+
port => #{port}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
CONFIG
|
34
|
+
end
|
35
|
+
let(:data) do
|
36
|
+
{ :name => 'pageviews',
|
37
|
+
:units => 'req/min',
|
38
|
+
:type => 'uint8',
|
39
|
+
:value => 7000,
|
40
|
+
:tmax => 60,
|
41
|
+
:dmax => 300,
|
42
|
+
:group => 'test' }
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:client) { GangliaClient.new("0.0.0.0", port) }
|
46
|
+
|
47
|
+
let(:events) do
|
48
|
+
input(conf, nevents) do
|
49
|
+
nevents.times do |value|
|
50
|
+
client.send(data)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:event) { events[0] }
|
56
|
+
|
57
|
+
it "should receive and generate proper number of events" do
|
58
|
+
expect(events.count).to be(nevents)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should receive the correct data" do
|
62
|
+
expect(event["tmax"]).to eq(60)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/devutils/rspec/spec_helper"
|
3
|
+
require "logstash/inputs/ganglia"
|
4
|
+
require "support/client"
|
5
|
+
|
6
|
+
module GangliaHelpers
|
7
|
+
|
8
|
+
def setup_clients(number_of_clients, port)
|
9
|
+
number_of_clients.times.inject([]) do |clients|
|
10
|
+
clients << GangliaClient.new(localhost, port)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def input(config, size, &block)
|
15
|
+
pipeline = LogStash::Pipeline.new(config)
|
16
|
+
queue = Queue.new
|
17
|
+
|
18
|
+
pipeline.instance_eval do
|
19
|
+
# create closure to capture queue
|
20
|
+
@output_func = lambda { |event| queue << event }
|
21
|
+
|
22
|
+
# output_func is now a method, call closure
|
23
|
+
def output_func(event)
|
24
|
+
@output_func.call(event)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
pipeline_thread = Thread.new { pipeline.run }
|
29
|
+
sleep 0.1 while !pipeline.ready?
|
30
|
+
|
31
|
+
block.call
|
32
|
+
sleep 0.1 while queue.size != size
|
33
|
+
|
34
|
+
result = size.times.inject([]) do |acc|
|
35
|
+
acc << queue.pop
|
36
|
+
end
|
37
|
+
|
38
|
+
pipeline.shutdown
|
39
|
+
pipeline_thread.join
|
40
|
+
|
41
|
+
result
|
42
|
+
end # def input
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
RSpec.configure do |c|
|
47
|
+
c.include GangliaHelpers
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "socket"
|
3
|
+
require "gmetric"
|
4
|
+
|
5
|
+
class GangliaClient
|
6
|
+
|
7
|
+
attr_reader :addr, :port, :socket
|
8
|
+
|
9
|
+
def initialize(addr, port)
|
10
|
+
@addr = addr
|
11
|
+
@port = port
|
12
|
+
@socket = UDPSocket.new
|
13
|
+
socket.connect(addr, port)
|
14
|
+
end
|
15
|
+
|
16
|
+
def send(data={})
|
17
|
+
g = Ganglia::GMetric.pack(data)
|
18
|
+
@socket.send(g[0], 0)
|
19
|
+
@socket.send(g[1], 0)
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,82 +1,104 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-ganglia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ~>
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 2.0.0.snapshot
|
14
19
|
name: logstash-core
|
20
|
+
prerelease: false
|
21
|
+
type: :runtime
|
15
22
|
version_requirements: !ruby/object:Gem::Requirement
|
16
23
|
requirements:
|
17
|
-
- -
|
24
|
+
- - ~>
|
18
25
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 2.0.0
|
26
|
+
version: 2.0.0.snapshot
|
27
|
+
- !ruby/object:Gem::Dependency
|
23
28
|
requirement: !ruby/object:Gem::Requirement
|
24
29
|
requirements:
|
25
|
-
- -
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: 1.4.0
|
28
|
-
- - <
|
30
|
+
- - ~>
|
29
31
|
- !ruby/object:Gem::Version
|
30
|
-
version:
|
32
|
+
version: 0.0.22
|
33
|
+
name: stud
|
31
34
|
prerelease: false
|
32
35
|
type: :runtime
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.0.22
|
33
41
|
- !ruby/object:Gem::Dependency
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
34
47
|
name: logstash-codec-plain
|
48
|
+
prerelease: false
|
49
|
+
type: :runtime
|
35
50
|
version_requirements: !ruby/object:Gem::Requirement
|
36
51
|
requirements:
|
37
52
|
- - '>='
|
38
53
|
- !ruby/object:Gem::Version
|
39
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
40
56
|
requirement: !ruby/object:Gem::Requirement
|
41
57
|
requirements:
|
42
58
|
- - '>='
|
43
59
|
- !ruby/object:Gem::Version
|
44
60
|
version: '0'
|
45
|
-
prerelease: false
|
46
|
-
type: :runtime
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
61
|
name: logstash-devutils
|
62
|
+
prerelease: false
|
63
|
+
type: :development
|
49
64
|
version_requirements: !ruby/object:Gem::Requirement
|
50
65
|
requirements:
|
51
66
|
- - '>='
|
52
67
|
- !ruby/object:Gem::Version
|
53
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
54
70
|
requirement: !ruby/object:Gem::Requirement
|
55
71
|
requirements:
|
56
72
|
- - '>='
|
57
73
|
- !ruby/object:Gem::Version
|
58
74
|
version: '0'
|
75
|
+
name: gmetric
|
59
76
|
prerelease: false
|
60
77
|
type: :development
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
61
83
|
description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
|
62
84
|
email: info@elastic.co
|
63
85
|
executables: []
|
64
86
|
extensions: []
|
65
87
|
extra_rdoc_files: []
|
66
88
|
files:
|
67
|
-
- .gitignore
|
68
89
|
- CHANGELOG.md
|
69
90
|
- CONTRIBUTORS
|
70
91
|
- Gemfile
|
71
92
|
- LICENSE
|
72
93
|
- NOTICE.TXT
|
73
94
|
- README.md
|
74
|
-
- Rakefile
|
75
95
|
- lib/logstash/inputs/ganglia.rb
|
76
96
|
- lib/logstash/inputs/ganglia/gmondpacket.rb
|
77
97
|
- lib/logstash/inputs/ganglia/xdr.rb
|
78
98
|
- logstash-input-ganglia.gemspec
|
79
99
|
- spec/inputs/ganglia_spec.rb
|
100
|
+
- spec/spec_helper.rb
|
101
|
+
- spec/support/client.rb
|
80
102
|
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
81
103
|
licenses:
|
82
104
|
- Apache License (2.0)
|
@@ -99,9 +121,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
121
|
version: '0'
|
100
122
|
requirements: []
|
101
123
|
rubyforge_project:
|
102
|
-
rubygems_version: 2.
|
124
|
+
rubygems_version: 2.4.8
|
103
125
|
signing_key:
|
104
126
|
specification_version: 4
|
105
127
|
summary: Read ganglia packets from the network via udp
|
106
128
|
test_files:
|
107
129
|
- spec/inputs/ganglia_spec.rb
|
130
|
+
- spec/spec_helper.rb
|
131
|
+
- spec/support/client.rb
|
data/.gitignore
DELETED