logstash-input-jmx 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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjBjMmYyMjIxMDgzNzU4ZTMzOTBjZTkzOGExYTdlYjU5ZGNlZWIyZA==
5
+ data.tar.gz: !binary |-
6
+ NDNiMThkMmRiYTQ5YzY4M2E3OWYzNzJlNjc5MTc2YzQ1OTBiNDMyMw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NmYxY2I1MTBhMDJhOWY1OTViZGZkOWRjODE0MWY1NzI3Y2U5ODg1ZjFhM2Zl
10
+ MzgwN2YyYTZiNGExNzUxMTM0NzczMTg1NDU3NzU2MTc0N2EwM2Q1YjA2ZjQ3
11
+ NDc5MmQzZDkxYTEyNzc5NTY5MzEzNTU1ODE1MGI0NGIxNGNjZGQ=
12
+ data.tar.gz: !binary |-
13
+ ODQ4MzRjZjcyNjYzM2E1NGM5NDI4YTExZmZkMzk0YmQ1ZWMxODk2YTJlY2M0
14
+ MWEwODFmZDBiMDNkMDNkZjI3NDY3MTZhY2Y4NjY5YjQyNDU0NDNkZWQzNzc2
15
+ ZmI0NjljMDk1OTE4OGJiNDU3YTkwZjY2NTRlNmZmYmU0ZDI1ZjI=
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ Gemfile.lock
3
+ .bundle
4
+ vendor
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+ gem 'rake'
3
+ gem 'gem_publisher'
4
+ gem 'archive-tar-minitar'
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2012-2014 Elasticsearch <http://www.elasticsearch.org>
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ @files=[]
2
+
3
+ task :default do
4
+ system("rake -T")
5
+ end
6
+
@@ -0,0 +1,294 @@
1
+ # Permits to retrieve metrics from jmx.
2
+ class LogStash::Inputs::Jmx < LogStash::Inputs::Base
3
+ # TODO add documentation
4
+ config_name 'jmx'
5
+ milestone 1
6
+
7
+ #Class Var
8
+ attr_accessor :regexp_group_alias_object
9
+ attr_accessor :queue_conf
10
+
11
+ # Path where json conf files are stored
12
+ config :path, :validate => :string, :required => true
13
+
14
+ # Indicate interval between to jmx metrics retrieval
15
+ # (in s)
16
+ config :polling_frequency, :validate => :number, :default => 60
17
+
18
+ # Indicate number of thread launched to retrieve metrics
19
+ config :nb_thread, :validate => :number, :default => 4
20
+
21
+ # Read and parse json conf
22
+ private
23
+ def read_conf(file_conf)
24
+ require 'json'
25
+
26
+ @logger.debug("Parse json #{file_conf} to ruby data structure")
27
+ json = File.read(file_conf)
28
+ JSON.parse(json)
29
+ end
30
+
31
+ # Verify that all required parameter are present in the conf_hash
32
+ private
33
+ def check_conf(conf_hash,file_conf)
34
+ #Check required parameters
35
+ @logger.debug("Check that required parameters are define with good types in #{conf_hash}")
36
+ parameter = {'host' => 'String'.class, 'port' => 1.class, 'queries' => [].class}
37
+ parameter.each_key do |param|
38
+ if conf_hash.has_key?(param)
39
+ unless conf_hash[param].instance_of?(parameter[param])
40
+ @logger.error("Bad syntax for conf file #{file_conf}. Bad types for parameter #{param}, expecting #{parameter[param]}, found #{conf_hash[param].class}.")
41
+ return false
42
+ end
43
+ else
44
+ @logger.error("Bad syntax for conf file #{file_conf}. Missing parameter #{param}.")
45
+ return false
46
+ end
47
+ end
48
+
49
+ @logger.debug('Check optional parameters types')
50
+ parameter = {'alias' => 'String'.class}
51
+ parameter.each_key do |param|
52
+ if conf_hash.has_key?(param)
53
+ unless conf_hash[param].instance_of?(parameter[param])
54
+ @logger.error("Bad syntax for conf file #{file_conf}. Bad types for parameter #{param}, expecting #{parameter[param]}, found #{conf_hash[param].class}.")
55
+ return false
56
+ end
57
+ end
58
+ end
59
+
60
+ @logger.debug('Check that required parameters are define with good types for queries')
61
+ parameter = {'object_name' => 'String'.class}
62
+ parameter.each_key do |param|
63
+ conf_hash['queries'].each do |query|
64
+ if query.has_key?(param)
65
+ unless query[param].instance_of?(parameter[param])
66
+ @logger.error("Bad syntax for conf file #{file_conf}. Bad types for parameter #{param} in query #{query}, expecting #{parameter[param]}, found #{conf_hash[param].class}.")
67
+ return false
68
+ end
69
+ else
70
+ @logger.error("Bad syntax for conf file #{file_conf} in query #{query}. Missing parameter #{param}.")
71
+ return false
72
+ end
73
+ end
74
+ end
75
+
76
+ @logger.debug('Check optional parameters types for queries')
77
+ parameter = {'object_alias' => 'String'.class, 'attributes' => [].class}
78
+ parameter.each_key do |param|
79
+ conf_hash['queries'].each do |query|
80
+ if query.has_key?(param)
81
+ unless query[param].instance_of?(parameter[param])
82
+ @logger.error("Bad syntax for conf file #{file_conf} in query #{query}. Bad types for parameter #{param}, expecting #{parameter[param]}, found #{conf_hash[param].class}.")
83
+ return false
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ true
90
+ end
91
+
92
+ private
93
+ def replace_alias_object(r_alias_object,object_name)
94
+ @logger.debug("Replace ${.*} variables from #{r_alias_object} using #{object_name}")
95
+ group_alias = @regexp_group_alias_object.match(r_alias_object)
96
+ if group_alias
97
+ r_alias_object = r_alias_object.gsub('${'+group_alias[1]+'}',object_name.split(group_alias[1]+'=')[1].split(',')[0])
98
+ r_alias_object = replace_alias_object(r_alias_object,object_name)
99
+ end
100
+ r_alias_object
101
+ end
102
+
103
+ private
104
+ def send_event_to_queue(queue,host,metric_path,metric_value)
105
+ @logger.debug('Send event to queue to be processed by filters/outputs')
106
+ event = LogStash::Event.new
107
+ event['host'] = host
108
+ event['path'] = @path
109
+ event['type'] = @type
110
+ number_type = [Fixnum, Bignum, Float]
111
+ boolean_type = [TrueClass, FalseClass]
112
+ metric_path_substituted = metric_path.gsub(' ','_').gsub('"','')
113
+ if number_type.include?(metric_value.class)
114
+ @logger.debug("The value #{metric_value} is of type number: #{metric_value.class}")
115
+ event['metric_path'] = metric_path_substituted
116
+ event['metric_value_number'] = metric_value
117
+ elsif boolean_type.include?(metric_value.class)
118
+ @logger.debug("The value #{metric_value} is of type boolean: #{metric_value.class}")
119
+ event['metric_path'] = metric_path_substituted+'_bool'
120
+ event['metric_value_number'] = metric_value ? 1 : 0
121
+ else
122
+ @logger.debug("The value #{metric_value} is not of type number: #{metric_value.class}")
123
+ event['metric_path'] = metric_path_substituted
124
+ event['metric_value_string'] = metric_value.to_s
125
+ end
126
+ queue << event
127
+ end
128
+
129
+ # Thread function to retrieve metrics from JMX
130
+ private
131
+ def thread_jmx(queue_conf,queue)
132
+ require 'jmx4r'
133
+
134
+ while true
135
+ begin
136
+ @logger.debug('Wait config to retrieve from queue conf')
137
+ thread_hash_conf = queue_conf.pop
138
+ @logger.debug("Retrieve config #{thread_hash_conf} from queue conf")
139
+
140
+ @logger.debug('Check if jmx connection need a user/password')
141
+ if thread_hash_conf.has_key?('username') and thread_hash_conf.has_key?('password')
142
+ @logger.debug("Connect to #{thread_hash_conf['host']}:#{thread_hash_conf['port']} with user #{thread_hash_conf['username']}")
143
+ jmx_connection = JMX::MBean.connection :host => thread_hash_conf['host'],
144
+ :port => thread_hash_conf['port'],
145
+ :username => thread_hash_conf['username'],
146
+ :password => thread_hash_conf['password']
147
+ else
148
+ @logger.debug("Connect to #{thread_hash_conf['host']}:#{thread_hash_conf['port']}")
149
+ jmx_connection = JMX::MBean.connection :host => thread_hash_conf['host'],
150
+ :port => thread_hash_conf['port']
151
+ end
152
+
153
+
154
+ if thread_hash_conf.has_key?('alias')
155
+ @logger.debug("Set base_metric_path to alias: #{thread_hash_conf['alias']}")
156
+ base_metric_path = thread_hash_conf['alias']
157
+ else
158
+ @logger.debug("Set base_metric_path to host_port: #{thread_hash_conf['host']}_#{thread_hash_conf['port']}")
159
+ base_metric_path = "#{thread_hash_conf['host']}_#{thread_hash_conf['port']}"
160
+ end
161
+
162
+
163
+ @logger.debug("Treat queries #{thread_hash_conf['queries']}")
164
+ thread_hash_conf['queries'].each do |query|
165
+ @logger.debug("Find all objects name #{query['object_name']}")
166
+ jmx_object_name_s = JMX::MBean.find_all_by_name(query['object_name'], :connection => jmx_connection)
167
+
168
+ if jmx_object_name_s.length > 0
169
+ jmx_object_name_s.each do |jmx_object_name|
170
+ if query.has_key?('object_alias')
171
+ object_name = replace_alias_object(query['object_alias'],jmx_object_name.object_name.to_s)
172
+ @logger.debug("Set object_name to object_alias: #{object_name}")
173
+ else
174
+ object_name = jmx_object_name.object_name.to_s
175
+ @logger.debug("Set object_name to jmx object_name: #{object_name}")
176
+ end
177
+
178
+ if query.has_key?('attributes')
179
+ @logger.debug("Retrieves attributes #{query['attributes']} to #{jmx_object_name.object_name}")
180
+ query['attributes'].each do |attribute|
181
+ begin
182
+ jmx_attribute_value = jmx_object_name.send(attribute.snake_case)
183
+ if jmx_attribute_value.instance_of? Java::JavaxManagementOpenmbean::CompositeDataSupport
184
+ @logger.debug('The jmx value is a composite_data one')
185
+ jmx_attribute_value.each do |jmx_attribute_value_composite|
186
+ @logger.debug("Get jmx value #{jmx_attribute_value[jmx_attribute_value_composite]} for attribute #{attribute}.#{jmx_attribute_value_composite} to #{jmx_object_name.object_name}")
187
+ send_event_to_queue(queue, thread_hash_conf['host'], "#{base_metric_path}.#{object_name}.#{attribute}.#{jmx_attribute_value_composite}", jmx_attribute_value[jmx_attribute_value_composite])
188
+ end
189
+ else
190
+ @logger.debug("Get jmx value #{jmx_attribute_value} for attribute #{attribute} to #{jmx_object_name.object_name}")
191
+ send_event_to_queue(queue, thread_hash_conf['host'], "#{base_metric_path}.#{object_name}.#{attribute}", jmx_attribute_value)
192
+ end
193
+ rescue Exception => ex
194
+ @logger.warn("Failed retrieving metrics for attribute #{attribute} on object #{jmx_object_name.object_name}")
195
+ @logger.warn(ex.message)
196
+ end
197
+ end
198
+ else
199
+ @logger.debug("No attribute to retrieve define on #{jmx_object_name.object_name}, will retrieve all")
200
+ jmx_object_name.attributes.each_key do |attribute|
201
+ begin
202
+ jmx_attribute_value = jmx_object_name.send(attribute)
203
+ if jmx_attribute_value.instance_of? Java::JavaxManagementOpenmbean::CompositeDataSupport
204
+ @logger.debug('The jmx value is a composite_data one')
205
+ jmx_attribute_value.each do |jmx_attribute_value_composite|
206
+ @logger.debug("Get jmx value #{jmx_attribute_value[jmx_attribute_value_composite]} for attribute #{jmx_object_name.attributes[attribute]}.#{jmx_attribute_value_composite} to #{jmx_object_name.object_name}")
207
+ send_event_to_queue(queue, thread_hash_conf['host'], "#{base_metric_path}.#{object_name}.#{jmx_object_name.attributes[attribute]}.#{jmx_attribute_value_composite}", jmx_attribute_value[jmx_attribute_value_composite])
208
+ end
209
+ else
210
+ @logger.debug("Get jmx value #{jmx_attribute_value} for attribute #{jmx_object_name.attributes[attribute]} to #{jmx_object_name.object_name}")
211
+ send_event_to_queue(queue, thread_hash_conf['host'], "#{base_metric_path}.#{object_name}.#{jmx_object_name.attributes[attribute]}", jmx_attribute_value)
212
+ end
213
+ rescue Exception => ex
214
+ @logger.warn("Failed retrieving metrics for attribute #{attribute} on object #{jmx_object_name.object_name}")
215
+ @logger.warn(ex.message)
216
+ end
217
+ end
218
+ end
219
+ end
220
+ else
221
+ @logger.warn("No jmx object found for #{query['object_name']}")
222
+ end
223
+ end
224
+ jmx_connection.close
225
+ rescue Exception => ex
226
+ @logger.error(ex.message)
227
+ @logger.error(ex.backtrace.join("\n"))
228
+ end
229
+ end
230
+ end
231
+
232
+ public
233
+ def register
234
+ @logger.info('Registering files in', :path => @path)
235
+
236
+ @logger.info('Create queue conf used to send jmx conf to jmx collector threads')
237
+ @queue_conf = Queue.new
238
+
239
+ @logger.info('Compile regexp for group alias object replacement')
240
+ @regexp_group_alias_object = Regexp.new('(?:\${(.*?)})+')
241
+ end
242
+
243
+ public
244
+ def run(queue)
245
+ require 'thread'
246
+
247
+ begin
248
+ threads = []
249
+ @logger.info("Init #{@nb_thread} jmx collector threads")
250
+ @nb_thread.times do
251
+ threads << Thread.new { thread_jmx(@queue_conf,queue) }
252
+ end
253
+
254
+ while true
255
+ @logger.info("Load conf files in #{@path}")
256
+ Dir.foreach(@path) do |item|
257
+ begin
258
+ next if item == '.' or item == '..'
259
+ file_conf = File.join(@path, item)
260
+ @logger.debug("Load conf file #{file_conf}")
261
+ conf_hash = read_conf(file_conf)
262
+ if check_conf(conf_hash,file_conf)
263
+ @logger.debug("Add conf #{conf_hash} to the queue conf")
264
+ @queue_conf << conf_hash
265
+ end
266
+ rescue Exception => ex
267
+ @logger.warn("Issue parsing file #{file_conf}")
268
+ @logger.warn(ex.message)
269
+ @logger.warn(ex.backtrace.join("\n"))
270
+ next
271
+ end
272
+ end
273
+ @logger.debug('Wait until the queue conf is empty')
274
+ delta=0
275
+ until @queue_conf.empty?
276
+ @logger.debug("There are still #{@queue_conf.size} messages in the queue conf. Sleep 1s.")
277
+ delta=delta+1
278
+ sleep(1)
279
+ end
280
+ wait_time=@polling_frequency-delta
281
+ if wait_time>0
282
+ @logger.debug("Wait #{wait_time}s (#{@polling_frequency}-#{delta}(seconds wait until queue conf empty)) before to launch again a new jmx metrics collection")
283
+ sleep(wait_time)
284
+ else
285
+ @logger.warn("The time taken to retrieve metrics is more important than the retrieve_interval time set.
286
+ \nYou must adapt nb_thread, retrieve_interval to the number of jvm/metrics you want to retrieve.")
287
+ end
288
+ end
289
+ rescue Exception => ex
290
+ @logger.error(ex.message)
291
+ @logger.error(ex.backtrace.join("\n"))
292
+ end
293
+ end
294
+ end
@@ -0,0 +1,28 @@
1
+ Gem::Specification.new do |s|
2
+
3
+ s.name = 'logstash-input-jmx'
4
+ s.version = '0.1.0'
5
+ s.licenses = ['Apache License (2.0)']
6
+ s.summary = "Retrieve metrics from jmx."
7
+ s.description = "Retrieve metrics from jmx."
8
+ s.authors = ["Elasticsearch"]
9
+ s.email = 'richard.pijnenburg@elasticsearch.com'
10
+ s.homepage = "http://logstash.net/"
11
+ s.require_paths = ["lib"]
12
+
13
+ # Files
14
+ s.files = `git ls-files`.split($\)+::Dir.glob('vendor/*')
15
+
16
+ # Tests
17
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
+
19
+ # Special flag to let us know this is actually a logstash plugin
20
+ s.metadata = { "logstash_plugin" => "true", "group" => "input" }
21
+
22
+ # Gem dependencies
23
+ s.add_runtime_dependency 'logstash', '>= 1.4.0', '< 2.0.0'
24
+
25
+ s.add_runtime_dependency 'jmx4r'
26
+
27
+ end
28
+
@@ -0,0 +1,9 @@
1
+ require "gem_publisher"
2
+
3
+ desc "Publish gem to RubyGems.org"
4
+ task :publish_gem do |t|
5
+ gem_file = Dir.glob(File.expand_path('../*.gemspec',File.dirname(__FILE__))).first
6
+ gem = GemPublisher.publish_if_updated(gem_file, :rubygems)
7
+ puts "Published #{gem}" if gem
8
+ end
9
+
@@ -0,0 +1,169 @@
1
+ require "net/http"
2
+ require "uri"
3
+ require "digest/sha1"
4
+
5
+ def vendor(*args)
6
+ return File.join("vendor", *args)
7
+ end
8
+
9
+ directory "vendor/" => ["vendor"] do |task, args|
10
+ mkdir task.name
11
+ end
12
+
13
+ def fetch(url, sha1, output)
14
+
15
+ puts "Downloading #{url}"
16
+ actual_sha1 = download(url, output)
17
+
18
+ if actual_sha1 != sha1
19
+ fail "SHA1 does not match (expected '#{sha1}' but got '#{actual_sha1}')"
20
+ end
21
+ end # def fetch
22
+
23
+ def file_fetch(url, sha1)
24
+ filename = File.basename( URI(url).path )
25
+ output = "vendor/#{filename}"
26
+ task output => [ "vendor/" ] do
27
+ begin
28
+ actual_sha1 = file_sha1(output)
29
+ if actual_sha1 != sha1
30
+ fetch(url, sha1, output)
31
+ end
32
+ rescue Errno::ENOENT
33
+ fetch(url, sha1, output)
34
+ end
35
+ end.invoke
36
+
37
+ return output
38
+ end
39
+
40
+ def file_sha1(path)
41
+ digest = Digest::SHA1.new
42
+ fd = File.new(path, "r")
43
+ while true
44
+ begin
45
+ digest << fd.sysread(16384)
46
+ rescue EOFError
47
+ break
48
+ end
49
+ end
50
+ return digest.hexdigest
51
+ ensure
52
+ fd.close if fd
53
+ end
54
+
55
+ def download(url, output)
56
+ uri = URI(url)
57
+ digest = Digest::SHA1.new
58
+ tmp = "#{output}.tmp"
59
+ Net::HTTP.start(uri.host, uri.port, :use_ssl => (uri.scheme == "https")) do |http|
60
+ request = Net::HTTP::Get.new(uri.path)
61
+ http.request(request) do |response|
62
+ fail "HTTP fetch failed for #{url}. #{response}" if [200, 301].include?(response.code)
63
+ size = (response["content-length"].to_i || -1).to_f
64
+ count = 0
65
+ File.open(tmp, "w") do |fd|
66
+ response.read_body do |chunk|
67
+ fd.write(chunk)
68
+ digest << chunk
69
+ if size > 0 && $stdout.tty?
70
+ count += chunk.bytesize
71
+ $stdout.write(sprintf("\r%0.2f%%", count/size * 100))
72
+ end
73
+ end
74
+ end
75
+ $stdout.write("\r \r") if $stdout.tty?
76
+ end
77
+ end
78
+
79
+ File.rename(tmp, output)
80
+
81
+ return digest.hexdigest
82
+ rescue SocketError => e
83
+ puts "Failure while downloading #{url}: #{e}"
84
+ raise
85
+ ensure
86
+ File.unlink(tmp) if File.exist?(tmp)
87
+ end # def download
88
+
89
+ def untar(tarball, &block)
90
+ require "archive/tar/minitar"
91
+ tgz = Zlib::GzipReader.new(File.open(tarball))
92
+ # Pull out typesdb
93
+ tar = Archive::Tar::Minitar::Input.open(tgz)
94
+ tar.each do |entry|
95
+ path = block.call(entry)
96
+ next if path.nil?
97
+ parent = File.dirname(path)
98
+
99
+ mkdir_p parent unless File.directory?(parent)
100
+
101
+ # Skip this file if the output file is the same size
102
+ if entry.directory?
103
+ mkdir path unless File.directory?(path)
104
+ else
105
+ entry_mode = entry.instance_eval { @mode } & 0777
106
+ if File.exists?(path)
107
+ stat = File.stat(path)
108
+ # TODO(sissel): Submit a patch to archive-tar-minitar upstream to
109
+ # expose headers in the entry.
110
+ entry_size = entry.instance_eval { @size }
111
+ # If file sizes are same, skip writing.
112
+ next if stat.size == entry_size && (stat.mode & 0777) == entry_mode
113
+ end
114
+ puts "Extracting #{entry.full_name} from #{tarball} #{entry_mode.to_s(8)}"
115
+ File.open(path, "w") do |fd|
116
+ # eof? check lets us skip empty files. Necessary because the API provided by
117
+ # Archive::Tar::Minitar::Reader::EntryStream only mostly acts like an
118
+ # IO object. Something about empty files in this EntryStream causes
119
+ # IO.copy_stream to throw "can't convert nil into String" on JRuby
120
+ # TODO(sissel): File a bug about this.
121
+ while !entry.eof?
122
+ chunk = entry.read(16384)
123
+ fd.write(chunk)
124
+ end
125
+ #IO.copy_stream(entry, fd)
126
+ end
127
+ File.chmod(entry_mode, path)
128
+ end
129
+ end
130
+ tar.close
131
+ File.unlink(tarball) if File.file?(tarball)
132
+ end # def untar
133
+
134
+ def ungz(file)
135
+
136
+ outpath = file.gsub('.gz', '')
137
+ tgz = Zlib::GzipReader.new(File.open(file))
138
+ begin
139
+ File.open(outpath, "w") do |out|
140
+ IO::copy_stream(tgz, out)
141
+ end
142
+ File.unlink(file)
143
+ rescue
144
+ File.unlink(outpath) if File.file?(outpath)
145
+ raise
146
+ end
147
+ tgz.close
148
+ end
149
+
150
+ desc "Process any vendor files required for this plugin"
151
+ task "vendor" do |task, args|
152
+
153
+ @files.each do |file|
154
+ download = file_fetch(file['url'], file['sha1'])
155
+ if download =~ /.tar.gz/
156
+ prefix = download.gsub('.tar.gz', '').gsub('vendor/', '')
157
+ untar(download) do |entry|
158
+ if !file['files'].nil?
159
+ next unless file['files'].include?(entry.full_name.gsub(prefix, ''))
160
+ out = entry.full_name.split("/").last
161
+ end
162
+ File.join('vendor', out)
163
+ end
164
+ elsif download =~ /.gz/
165
+ ungz(download)
166
+ end
167
+ end
168
+
169
+ end
@@ -0,0 +1 @@
1
+ require 'spec_helper'
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-input-jmx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Elasticsearch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logstash
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.0
20
+ - - <
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.4.0
30
+ - - <
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: jmx4r
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ description: Retrieve metrics from jmx.
48
+ email: richard.pijnenburg@elasticsearch.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE
56
+ - Rakefile
57
+ - lib/logstash/inputs/jmx.rb
58
+ - logstash-input-jmx.gemspec
59
+ - rakelib/publish.rake
60
+ - rakelib/vendor.rake
61
+ - spec/inputs/jmx_spec.rb
62
+ homepage: http://logstash.net/
63
+ licenses:
64
+ - Apache License (2.0)
65
+ metadata:
66
+ logstash_plugin: 'true'
67
+ group: input
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.4.1
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: Retrieve metrics from jmx.
88
+ test_files:
89
+ - spec/inputs/jmx_spec.rb