mongodb-graphite 0.1.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile.lock +8 -12
- data/README.md +35 -5
- data/bin/mongodb-graphite +31 -82
- data/lib/mongodb-graphite.rb +5 -0
- data/lib/mongodb-graphite/configuration.rb +39 -0
- data/lib/mongodb-graphite/instance.rb +101 -0
- data/lib/mongodb-graphite/instance_list.rb +46 -0
- data/mongodb-graphite.gemspec +3 -3
- metadata +65 -86
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 462cf3ab0ee602d4cdacff7c2c1f31b92551cdad
|
4
|
+
data.tar.gz: ecc40e1948680682b9f4ef968764f00657ff25c9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f5ee6b638028c2d35f662bdf15ce7217b2e19ad1711b17b0406c5c687c557c3304a1750e7146c6b1976d6c6125c034bb2dc81f4269b0f63c41e7078d58e537a7
|
7
|
+
data.tar.gz: be5acfc4bc778b4ce0e894b00c0551621047436bfeee66ec211df1420de237246770e6254f57bde69558b6243ffe128058f87387d2711b376287047207da6693
|
data/Gemfile.lock
CHANGED
@@ -1,23 +1,19 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mongodb-graphite (
|
5
|
-
|
4
|
+
mongodb-graphite (1.0.0)
|
5
|
+
daemons
|
6
6
|
mongo (>= 1.5.2)
|
7
|
+
simple-graphite (>= 2.1.0)
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: http://rubygems.org/
|
10
11
|
specs:
|
11
|
-
bson (1.
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
mongo (1.5.2)
|
17
|
-
bson (= 1.5.2)
|
18
|
-
rufus-scheduler (2.0.16)
|
19
|
-
tzinfo (>= 0.3.23)
|
20
|
-
tzinfo (0.3.31)
|
12
|
+
bson (1.8.6)
|
13
|
+
daemons (1.1.9)
|
14
|
+
mongo (1.8.6)
|
15
|
+
bson (~> 1.8.6)
|
16
|
+
simple-graphite (2.1.0)
|
21
17
|
|
22
18
|
PLATFORMS
|
23
19
|
ruby
|
data/README.md
CHANGED
@@ -1,12 +1,42 @@
|
|
1
1
|
Very simple gem to monitor a mongodb cluster and send data to a graphite server.
|
2
2
|
|
3
|
-
|
3
|
+
Usage :
|
4
4
|
|
5
|
-
|
5
|
+
You have to set an environment variable MONGODB_GRAPHITE_DIR (or it will use the config dir in the current directory).
|
6
|
+
Then write a yml file to contain basic settings:
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
```yaml
|
9
|
+
log_dir: log
|
10
|
+
pid_dir: pids
|
11
|
+
graphite: graphite.mydomain:3333
|
12
|
+
interval: 3
|
13
|
+
instances_file: 'config/instances.rb'
|
14
|
+
```
|
9
15
|
|
16
|
+
Then in config/instances.rb, you can set instances to monitor:
|
10
17
|
|
11
|
-
|
18
|
+
```ruby
|
19
|
+
instance 'mongoD' do
|
20
|
+
host 'onemongo.mydomain'
|
21
|
+
port '27021'
|
22
|
+
prefix_callback (lambda { |stats|
|
23
|
+
process_type = stats['process']
|
24
|
+
"production.onemongo.#{process_type}"
|
25
|
+
} )
|
26
|
+
end
|
12
27
|
|
28
|
+
instance 'mongoD' do
|
29
|
+
host 'anothermongo.mydomain'
|
30
|
+
port '27017'
|
31
|
+
prefix_callback (lambda { |stats|
|
32
|
+
process_type = stats['process']
|
33
|
+
'test.anothermongo.#{process_type}"
|
34
|
+
} )
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
Finally, you can use the gem as a service (start, status, stop)
|
39
|
+
|
40
|
+
```
|
41
|
+
mongodb-graphite start
|
42
|
+
```
|
data/bin/mongodb-graphite
CHANGED
@@ -1,93 +1,42 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
|
7
|
-
graphite_server = ARGV[1]
|
8
|
-
prefix_common = ARGV[0]+"."
|
9
|
-
puts graphite_server
|
10
|
-
g = Graphite::Logger.new(graphite_server)
|
11
|
-
|
12
|
-
to_ignore =[ "set", "repl", "time","qr|qw","ar|aw","conn"]
|
13
|
-
to_convert = ["mapped","vsize","res","netIn","netOut"]
|
14
|
-
output_average = ["mapped","vsize","res","locked","idxmiss"]
|
15
|
-
output_sum = ["netIn", "netOut","insert","query","update","delete","getmore","command","flushes","faults"]
|
16
|
-
|
17
|
-
def convert(s)
|
18
|
-
mul = case s[-1]
|
19
|
-
when "b"
|
20
|
-
1
|
21
|
-
when "k"
|
22
|
-
1024
|
23
|
-
when "m"
|
24
|
-
1024 * 1024
|
25
|
-
when "g"
|
26
|
-
1024 * 1024 *1024
|
27
|
-
when "t"
|
28
|
-
1024 * 1024 * 1024 *1024
|
29
|
-
else
|
30
|
-
raise "not convertible"
|
31
|
-
end
|
32
|
-
s[0..-1].to_f * mul
|
33
|
-
end
|
34
|
-
|
3
|
+
require 'mongodb-graphite'
|
4
|
+
require 'optparse'
|
5
|
+
require 'daemons'
|
6
|
+
require 'simple-graphite'
|
35
7
|
|
8
|
+
conf_dir = File.expand_path(ENV['MONGODB_GRAPHITE_DIR'] || '.')
|
36
9
|
|
10
|
+
config = MongodbGraphite::Configuration.new(conf_dir)
|
37
11
|
|
12
|
+
daemon_options = {
|
13
|
+
:multiple => false,
|
14
|
+
:monitor => true,
|
15
|
+
:backtrace => true,
|
16
|
+
:log_dir => config[:log_dir],
|
17
|
+
:log_output => true,
|
18
|
+
:dir_mode => :normal,
|
19
|
+
:dir => config[:pid_dir]
|
20
|
+
}
|
38
21
|
|
22
|
+
g_host, g_port = config[:graphite].split(':')
|
39
23
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
def treat_replicaset(g,to_ignore,to_convert, output_average, output_sum ,prefix_common,host,port, shard_name)
|
45
|
-
#puts "shard : ", host,port
|
46
|
-
connHost = Mongo::Connection.new(host, port)
|
47
|
-
slaves = Array.new
|
48
|
-
connHost["admin"].command({ "isMaster" => 1 } )["hosts"].each { |slave| slaves << slave}
|
49
|
-
slaves.each { |slave|
|
50
|
-
Process.fork do
|
51
|
-
host, port = slave.split(':')
|
52
|
-
timestamp = Time.now.getutc.to_i
|
53
|
-
result= `mongostat -n 60 --host #{host} --port #{port} `.split("\n")
|
54
|
-
#timestamp += Time.now.getutc.to_i
|
55
|
-
#timestamp /= 2
|
56
|
-
headers, values = result[1], result[2..-1]
|
57
|
-
headers = headers.gsub(' %','').gsub('*','').gsub('idx miss','idxmiss').split
|
58
|
-
values= values.delete_if {|line| line.start_with?('insert')}.map { |line| line.gsub('*','').split}
|
59
|
-
values = values.transpose
|
60
|
-
|
61
|
-
prefix = prefix_common +shard_name+"."+ host +"."+port+"."
|
62
|
-
headers = headers.map { |key| prefix+key }
|
63
|
-
metrics = Hash[headers.zip(values)]
|
64
|
-
to_ignore.each { |key| metrics.delete(prefix + key) }
|
65
|
-
to_convert.each { |key| metrics[prefix + key] = metrics[prefix+key].map {|val| convert(val)}}
|
66
|
-
output_average.each { |key| metrics[prefix+key] = metrics[prefix+key].inject(0.0) {|sum,el| sum+(el.to_i) } / metrics[prefix+key].size }
|
67
|
-
output_sum.each { |key| metrics[prefix+key] = metrics[prefix+key].inject(0) {|sum,el| sum+(el.to_i)} }
|
68
|
-
g.log(timestamp, metrics)
|
69
|
-
end
|
70
|
-
}
|
24
|
+
[:log_dir, :pid_dir].each do |d|
|
25
|
+
Dir.mkdir config[d] unless Dir.exist?(config[d])
|
71
26
|
end
|
72
27
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
@
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
Process.fork do
|
85
|
-
host,port = s.split(/,|\//)[1].split(':')
|
86
|
-
treat_replicaset(g,to_ignore,to_convert, output_average, output_sum ,prefix_common,host,port, s.split(/,|\//)[0])
|
28
|
+
Daemons.run_proc('mongodb-graphite', daemon_options) do
|
29
|
+
loop do
|
30
|
+
g = Graphite.new( :host => g_host, :port => g_port || '3333' )
|
31
|
+
@instance_list = MongodbGraphite::InstanceList.new(config)
|
32
|
+
@instance_list.each do |i|
|
33
|
+
begin
|
34
|
+
g.send_metrics(i.to_graphite)
|
35
|
+
rescue Exception => e
|
36
|
+
puts "Impossible to send metrics because of #{e}"
|
37
|
+
puts e.backtrace
|
38
|
+
end
|
87
39
|
end
|
88
|
-
|
89
|
-
|
90
|
-
puts "not mongos"
|
91
|
-
treat_replicaset(g,to_ignore,to_convert, output_average, output_sum ,prefix_common,hostt,portt, "direct")
|
40
|
+
sleep (config[:interval] || 5)
|
41
|
+
end
|
92
42
|
end
|
93
|
-
Process.wait
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module MongodbGraphite
|
4
|
+
class Configuration
|
5
|
+
def initialize(dir)
|
6
|
+
reload(dir)
|
7
|
+
end
|
8
|
+
|
9
|
+
def reload(dir)
|
10
|
+
@config = {
|
11
|
+
:log_dir => 'log',
|
12
|
+
:pid_dir => 'pids',
|
13
|
+
:graphite => 'localhost:3333',
|
14
|
+
:mongodb => 'localhost:27017',
|
15
|
+
:interval => 3, #in seconds
|
16
|
+
:instances_file => nil
|
17
|
+
}
|
18
|
+
|
19
|
+
config_file_path = File.join(dir, 'config', 'mongodb-graphite.yml')
|
20
|
+
if File.exist? config_file_path
|
21
|
+
config_file = YAML.load_file(config_file_path)
|
22
|
+
@config.keys.each do |key|
|
23
|
+
value = config_file[key.to_s]
|
24
|
+
@config[key] = value unless value.nil?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@config[:mongodb_graphite_dir] = dir
|
29
|
+
|
30
|
+
[:log_dir, :pid_dir, :instances_file].each do |k|
|
31
|
+
@config[k] = File.absolute_path(@config[k], dir)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def [](key)
|
36
|
+
@config[key]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
require 'simple-graphite'
|
3
|
+
|
4
|
+
module Enumerable
|
5
|
+
def merge_all
|
6
|
+
self.inject({}) { |h1, h2|
|
7
|
+
h1.merge! h2
|
8
|
+
}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module MongodbGraphite
|
13
|
+
class Instance
|
14
|
+
|
15
|
+
OPTIONS = [:host, :port, :prefix_callback, :fields_to_ignore]
|
16
|
+
|
17
|
+
def initialize(name)
|
18
|
+
@name = name
|
19
|
+
@port = 27017
|
20
|
+
@host = 'localhost'
|
21
|
+
@fields_to_ignore = %w(host version process pid uptimeMillis localTime extra_info.note backgroundFlushing.last_finished repl.setName repl.hosts repl.arbiters repl.primary repl.me ok)
|
22
|
+
@prefix_callback = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def reload(options)
|
26
|
+
OPTIONS.each do |opt|
|
27
|
+
val = instance_variable_get "@#{opt}"
|
28
|
+
if options[opt] != val and not options[opt].nil?
|
29
|
+
instance_variable_set "@#{opt}", options.delete(opt)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
OPTIONS.each do |opt|
|
35
|
+
define_method opt do
|
36
|
+
instance_variable_get "@#{opt}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
"#{@name} #{@host}:#{@port}, #{@prefix_callback.class}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_graphite
|
45
|
+
@stats = to_hash
|
46
|
+
with_prefix = Hash.new
|
47
|
+
@stats.each do |k,v|
|
48
|
+
with_prefix[ [prefix, k].join('.')] = to_i(v)
|
49
|
+
end
|
50
|
+
with_prefix.reject { |k,v| ignored_fields.include? k }
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def prefix
|
56
|
+
return @prefix_callback.call(@stats) unless @prefix_callback.nil?
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_i(v)
|
61
|
+
return v.to_i if v.respond_to?('to_i')
|
62
|
+
case v
|
63
|
+
when TrueClass
|
64
|
+
1
|
65
|
+
when FalseClass
|
66
|
+
0
|
67
|
+
else
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def ignored_fields
|
73
|
+
@fields_to_ignore.map { |f| [prefix,f].join('.') }
|
74
|
+
end
|
75
|
+
|
76
|
+
def connection
|
77
|
+
@connection ||= Mongo::MongoClient.new(host, port, :slave_ok => true, :connect_timeout => 5, :pool_timeout => 5)
|
78
|
+
end
|
79
|
+
|
80
|
+
def stats
|
81
|
+
connection['test'].command({ 'serverStatus' => 1})
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_hash
|
85
|
+
s = stats
|
86
|
+
@process = s['process']
|
87
|
+
json_descent([], s).flatten.merge_all
|
88
|
+
end
|
89
|
+
|
90
|
+
def json_descent(pre, json)
|
91
|
+
json.map do |k,v|
|
92
|
+
key = pre + [k]
|
93
|
+
if v.is_a? BSON::OrderedHash
|
94
|
+
json_descent(key, v)
|
95
|
+
else
|
96
|
+
{key.join('.') => v }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module MongodbGraphite
|
2
|
+
class InstanceList
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_accessor :instances
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
@instances = {}
|
10
|
+
reload
|
11
|
+
end
|
12
|
+
|
13
|
+
def reload
|
14
|
+
@instances = {}
|
15
|
+
|
16
|
+
file = @config[:instances_file]
|
17
|
+
if not file.nil?
|
18
|
+
#puts "Reading instance file from #{file}"
|
19
|
+
instance_eval(File.read(file),file)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def instance(name)
|
24
|
+
@options = {}
|
25
|
+
yield
|
26
|
+
@instances[name] ||= Instance.new(name)
|
27
|
+
@instances[name].reload(@options)
|
28
|
+
@options = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
#dynamic definition of properties to have a nice dsl
|
32
|
+
Instance::OPTIONS.each do |opt|
|
33
|
+
define_method opt do |v|
|
34
|
+
@options[opt] = v
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def each
|
40
|
+
@instances.each do |name,i|
|
41
|
+
yield i
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
data/mongodb-graphite.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "mongodb-graphite"
|
6
|
-
s.version = '0.
|
6
|
+
s.version = '1.0.0'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Grégoire Seux"]
|
9
9
|
s.email = ["g.seux@criteo.com"]
|
@@ -16,6 +16,6 @@ Gem::Specification.new do |s|
|
|
16
16
|
#s.require_paths = ["lib"]
|
17
17
|
|
18
18
|
s.add_dependency "mongo", ">= 1.5.2"
|
19
|
-
s.add_dependency "graphite", ">=
|
20
|
-
s.add_dependency
|
19
|
+
s.add_dependency "simple-graphite", ">= 2.1.0"
|
20
|
+
s.add_dependency 'daemons'
|
21
21
|
end
|
metadata
CHANGED
@@ -1,116 +1,95 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongodb-graphite
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 5
|
10
|
-
version: 0.1.5
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
13
|
-
-
|
6
|
+
authors:
|
7
|
+
- Grégoire Seux
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2013-06-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
21
14
|
name: mongo
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 7
|
29
|
-
segments:
|
30
|
-
- 1
|
31
|
-
- 5
|
32
|
-
- 2
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
33
19
|
version: 1.5.2
|
34
20
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: graphite
|
38
21
|
prerelease: false
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.5.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: simple-graphite
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.1.0
|
50
34
|
type: :runtime
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
53
|
-
name: peach
|
54
35
|
prerelease: false
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: daemons
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
65
48
|
type: :runtime
|
66
|
-
|
67
|
-
|
68
|
-
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: ''
|
56
|
+
email:
|
69
57
|
- g.seux@criteo.com
|
70
|
-
executables:
|
58
|
+
executables:
|
71
59
|
- mongodb-graphite
|
72
60
|
extensions: []
|
73
|
-
|
74
61
|
extra_rdoc_files: []
|
75
|
-
|
76
|
-
files:
|
62
|
+
files:
|
77
63
|
- Gemfile
|
78
64
|
- Gemfile.lock
|
79
65
|
- README.md
|
80
66
|
- bin/mongodb-graphite
|
67
|
+
- lib/mongodb-graphite.rb
|
68
|
+
- lib/mongodb-graphite/configuration.rb
|
69
|
+
- lib/mongodb-graphite/instance.rb
|
70
|
+
- lib/mongodb-graphite/instance_list.rb
|
81
71
|
- mongodb-graphite.gemspec
|
82
72
|
homepage: https://github.com/kamaradclimber/mongodb-graphite
|
83
73
|
licenses: []
|
84
|
-
|
74
|
+
metadata: {}
|
85
75
|
post_install_message:
|
86
76
|
rdoc_options: []
|
87
|
-
|
88
|
-
require_paths:
|
77
|
+
require_paths:
|
89
78
|
- lib
|
90
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
none: false
|
101
|
-
requirements:
|
102
|
-
- - ">="
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
hash: 3
|
105
|
-
segments:
|
106
|
-
- 0
|
107
|
-
version: "0"
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
108
89
|
requirements: []
|
109
|
-
|
110
90
|
rubyforge_project:
|
111
|
-
rubygems_version:
|
91
|
+
rubygems_version: 2.0.3
|
112
92
|
signing_key:
|
113
|
-
specification_version:
|
114
|
-
summary:
|
93
|
+
specification_version: 4
|
94
|
+
summary: ''
|
115
95
|
test_files: []
|
116
|
-
|