ostrichpoll 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +22 -0
- data/.rvmrc +81 -0
- data/Gemfile +4 -0
- data/LICENSE.md +14 -0
- data/README.md +85 -0
- data/Rakefile +2 -0
- data/bin/ostrichpoll +4 -0
- data/exampleconfigs/firehose.yml +0 -0
- data/lib/ostrichpoll/config_parser.rb +74 -0
- data/lib/ostrichpoll/exit_codes.rb +8 -0
- data/lib/ostrichpoll/ostrich_validator.rb +175 -0
- data/lib/ostrichpoll/string.rb +6 -0
- data/lib/ostrichpoll/version.rb +3 -0
- data/lib/ostrichpoll.rb +77 -0
- data/ostrichPoll.gemspec +20 -0
- metadata +85 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
+
# development environment upon cd'ing into the directory
|
5
|
+
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
|
7
|
+
environment_id="ruby-1.9.2-p290"
|
8
|
+
|
9
|
+
#
|
10
|
+
# Uncomment the following lines if you want to verify rvm version per project
|
11
|
+
#
|
12
|
+
# rvmrc_rvm_version="1.10.1" # 1.10.1 seams as a safe start
|
13
|
+
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
14
|
+
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
15
|
+
# return 1
|
16
|
+
# }
|
17
|
+
#
|
18
|
+
|
19
|
+
#
|
20
|
+
# Uncomment following line if you want options to be set only for given project.
|
21
|
+
#
|
22
|
+
# PROJECT_JRUBY_OPTS=( --1.9 )
|
23
|
+
#
|
24
|
+
# The variable PROJECT_JRUBY_OPTS requires the following to be run in shell:
|
25
|
+
#
|
26
|
+
# chmod +x ${rvm_path}/hooks/after_use_jruby_opts
|
27
|
+
#
|
28
|
+
|
29
|
+
#
|
30
|
+
# First we attempt to load the desired environment directly from the environment
|
31
|
+
# file. This is very fast and efficient compared to running through the entire
|
32
|
+
# CLI and selector. If you want feedback on which environment was used then
|
33
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
34
|
+
#
|
35
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
36
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
37
|
+
then
|
38
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
39
|
+
|
40
|
+
if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
|
41
|
+
then
|
42
|
+
. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
|
43
|
+
fi
|
44
|
+
else
|
45
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
46
|
+
if ! rvm --create "$environment_id"
|
47
|
+
then
|
48
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
49
|
+
return 1
|
50
|
+
fi
|
51
|
+
fi
|
52
|
+
|
53
|
+
#
|
54
|
+
# If you use an RVM gemset file to install a list of gems (*.gems), you can have
|
55
|
+
# it be automatically loaded. Uncomment the following and adjust the filename if
|
56
|
+
# necessary.
|
57
|
+
#
|
58
|
+
# filename=".gems"
|
59
|
+
# if [[ -s "$filename" ]]
|
60
|
+
# then
|
61
|
+
# rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
|
62
|
+
# fi
|
63
|
+
|
64
|
+
# If you use bundler, this might be useful to you:
|
65
|
+
# if [[ -s Gemfile ]] && ! command -v bundle >/dev/null
|
66
|
+
# then
|
67
|
+
# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
|
68
|
+
# gem install bundler
|
69
|
+
# fi
|
70
|
+
# if [[ -s Gemfile ]] && command -v bundle
|
71
|
+
# then
|
72
|
+
# bundle install
|
73
|
+
# fi
|
74
|
+
|
75
|
+
if [[ $- == *i* ]] # check for interactive shells
|
76
|
+
then
|
77
|
+
echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
|
78
|
+
else
|
79
|
+
echo "Using: $GEM_HOME" # don't use colors in interactive shells
|
80
|
+
fi
|
81
|
+
|
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
Copyright 2012, Tumblr Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Ostrichpoll
|
2
|
+
|
3
|
+
Ostrichpoll is a tiny utility for monitoring Twitter Ostrich services.
|
4
|
+
Effectively it can monitor any service which exposes internal metrics in JSON
|
5
|
+
over HTTP.
|
6
|
+
|
7
|
+
Features:
|
8
|
+
|
9
|
+
* not a daemon: Ostrichpoll is intended to be run by `monit` or similar tool on a regular basis.
|
10
|
+
* validate multiple endpoints in a single execution
|
11
|
+
* specify normal ranges for metrics and gauges through YAML configuration
|
12
|
+
* support for "rate" measurements, specifying acceptable change per second for
|
13
|
+
a metric. (useful for counters and other monotonic metrics)
|
14
|
+
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
$ gem install ostrichpoll
|
19
|
+
|
20
|
+
## Execution
|
21
|
+
|
22
|
+
Ostrichpoll may be executed with a simple `ostrichpoll` which will ensure a 200 response
|
23
|
+
is given from `127.0.0.1:9900/stats.json`.
|
24
|
+
|
25
|
+
You may change the endpoint:
|
26
|
+
|
27
|
+
ostrichpoll -u devbox:9999/stats.json
|
28
|
+
|
29
|
+
The interesting part of Ostrichpoll is when you give a configuration file
|
30
|
+
that specifies normal ranges for individual metrics:
|
31
|
+
|
32
|
+
ostrichpoll -c pollconfig.yml
|
33
|
+
|
34
|
+
Use `-d` to enable extra logging for debugging.
|
35
|
+
|
36
|
+
## Configuration
|
37
|
+
|
38
|
+
Configuration is specified in the format:
|
39
|
+
|
40
|
+
---
|
41
|
+
- url: 127.0.0.1:9900/stats.txt?period=10
|
42
|
+
rate_file: /tmp/parmesan-http-ostrich-rate.yml
|
43
|
+
validations:
|
44
|
+
counters/KafkaEventSink_messageDropped:
|
45
|
+
rate: true
|
46
|
+
normal_range: [0, 5]
|
47
|
+
missing: ignore
|
48
|
+
exit_code: 2
|
49
|
+
metrics/KafkaEventSink_append_msec/p99:
|
50
|
+
normal_range: [0, 10]
|
51
|
+
missing: error
|
52
|
+
exit_code: 3
|
53
|
+
- url: 127.0.0.1:9901/stats.txt
|
54
|
+
...
|
55
|
+
|
56
|
+
### Options
|
57
|
+
|
58
|
+
* `url` - an endpoint which exposes JSON stats. If this endpoint is not available, Ostrichpoll will exit with `-1` (really `255`).
|
59
|
+
* `rate_file` - where to store rate measurements between executions of Ostrichpoll.
|
60
|
+
* `validations` - a list of validations to execute with the following options:
|
61
|
+
* the key is the name of the metric. Nested metrics are supported through the `/` notation.
|
62
|
+
* `rate` when set to true, compute the change per second since this value was last seen. You must specify a `rate_file` for this to work. Obviously, on the first execution of Ostrichpoll this validation will be ignored.
|
63
|
+
* `normal_range` an array specifying the minimum and maximum (inclusive) values which are acceptable for this metric
|
64
|
+
* `missing` behavior if the metric is not seen in the output at all. (error by default)
|
65
|
+
* `exit_code` what value Ostrichpoll should exit with if this error is seen.
|
66
|
+
|
67
|
+
### Notes
|
68
|
+
Ostrichpoll is setup to execute all validations on each execution, even if one of the early validations fails, the output from all validations is logged to stderr. However, the exit code is the exit code from the first erroring validation.
|
69
|
+
|
70
|
+
|
71
|
+
## License
|
72
|
+
|
73
|
+
Copyright 2012, Tumblr Inc.
|
74
|
+
|
75
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
76
|
+
you may not use this file except in compliance with the License.
|
77
|
+
You may obtain a copy of the License at
|
78
|
+
|
79
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
80
|
+
|
81
|
+
Unless required by applicable law or agreed to in writing, software
|
82
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
83
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
84
|
+
See the License for the specific language governing permissions and
|
85
|
+
limitations under the License.
|
data/Rakefile
ADDED
data/bin/ostrichpoll
ADDED
File without changes
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'ostrichpoll/ostrich_validator'
|
2
|
+
|
3
|
+
module OstrichPoll
|
4
|
+
# traverses a nested hashmap (the parsed config YAML)
|
5
|
+
# returning a set of hosts and validators
|
6
|
+
class ConfigParser
|
7
|
+
def self.parse(map)
|
8
|
+
hosts = []
|
9
|
+
|
10
|
+
map.each do |host_config|
|
11
|
+
host = Host.new
|
12
|
+
host_config.each do |key,value|
|
13
|
+
case key
|
14
|
+
when 'url'
|
15
|
+
host.url = value
|
16
|
+
|
17
|
+
when 'rate_file'
|
18
|
+
host.rate_file = value
|
19
|
+
|
20
|
+
when 'validations'
|
21
|
+
validations = parse_validations(value)
|
22
|
+
|
23
|
+
validations.each do |v|
|
24
|
+
v.host_instance = host
|
25
|
+
end
|
26
|
+
|
27
|
+
host.validations = validations
|
28
|
+
|
29
|
+
else
|
30
|
+
Log.warn "Unknown key: #{key}. Ignoring."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
hosts << host
|
34
|
+
end
|
35
|
+
|
36
|
+
hosts
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse_validations(validations)
|
40
|
+
return [] unless validations
|
41
|
+
|
42
|
+
validations.map do |name, v|
|
43
|
+
self.parse_validation name, v
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.parse_validation(name, map)
|
48
|
+
validator = Validator.new
|
49
|
+
validator.metric = name
|
50
|
+
map.each do |key,value|
|
51
|
+
case key
|
52
|
+
when 'rate'
|
53
|
+
validator.rate = value
|
54
|
+
|
55
|
+
when 'normal_range'
|
56
|
+
# FIXME validate normal range (min <= max, etc.)
|
57
|
+
validator.normal_range = value
|
58
|
+
|
59
|
+
when 'missing'
|
60
|
+
validator.missing = value.to_sym
|
61
|
+
|
62
|
+
when 'exit_code'
|
63
|
+
validator.exit_code = value
|
64
|
+
|
65
|
+
else
|
66
|
+
Log.warn "Unknown key for validation: #{key}. Ignoring."
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
validator.verify!
|
71
|
+
validator
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
#
|
2
|
+
# implements the actual validators
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'json'
|
6
|
+
require 'yaml'
|
7
|
+
require 'net/http'
|
8
|
+
|
9
|
+
module OstrichPoll
|
10
|
+
class Host
|
11
|
+
attr_accessor :url
|
12
|
+
attr_accessor :rate_file
|
13
|
+
attr_accessor :validations
|
14
|
+
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
validations = []
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_accessor :stored_values
|
21
|
+
attr_accessor :stored_timestamp
|
22
|
+
|
23
|
+
def validate
|
24
|
+
uri = URI.parse url
|
25
|
+
response = Net::HTTP.get uri
|
26
|
+
|
27
|
+
# parse response
|
28
|
+
json = JSON.parse(response) rescue (
|
29
|
+
Log.error "Invalid JSON response: #{response}"
|
30
|
+
return EXIT_ERROR
|
31
|
+
)
|
32
|
+
|
33
|
+
@stored_values = {}
|
34
|
+
if rate_file
|
35
|
+
# read in rate-file
|
36
|
+
@stored_values = YAML.load_file(rate_file) rescue (
|
37
|
+
Log.warn "Could not parse rate file: #{rate_file}"
|
38
|
+
{}
|
39
|
+
)
|
40
|
+
|
41
|
+
@stored_timestamp = stored_values['ostrichpoll.timestamp']
|
42
|
+
unless @stored_timestamp
|
43
|
+
Log.warn "No 'ostrichpoll.timestamp' found in rate file: #{rate_file}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# write out new rate file
|
47
|
+
json['ostrichpoll.timestamp'] = Time.now.to_i
|
48
|
+
File.open(rate_file, 'w') do |f|
|
49
|
+
f.puts json.to_yaml
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# execute each validations:
|
54
|
+
retval = false
|
55
|
+
if validations
|
56
|
+
validations.each do |v|
|
57
|
+
value = v.check(find_value(json, v.metric))
|
58
|
+
retval = value unless retval
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
retval
|
63
|
+
end
|
64
|
+
|
65
|
+
def previous_reading(key)
|
66
|
+
return stored_timestamp, find_value(stored_values, key)
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_value(map, key)
|
70
|
+
tree = map
|
71
|
+
key.split('/').each do |selector|
|
72
|
+
return nil unless tree.kind_of? Hash
|
73
|
+
tree = tree[selector]
|
74
|
+
end
|
75
|
+
|
76
|
+
tree
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# this is a pretty weak and limiting definition of a validator,
|
81
|
+
# but it's quick to develop and clear how to extend
|
82
|
+
class Validator
|
83
|
+
attr_accessor :host_instance
|
84
|
+
|
85
|
+
attr_accessor :metric
|
86
|
+
attr_accessor :rate
|
87
|
+
attr_accessor :normal_range
|
88
|
+
attr_accessor :missing
|
89
|
+
attr_accessor :exit_code
|
90
|
+
|
91
|
+
def init
|
92
|
+
@rate = false
|
93
|
+
@exit_code = 1
|
94
|
+
@missing = :ignore
|
95
|
+
end
|
96
|
+
|
97
|
+
def verify!
|
98
|
+
Log.warn "Invalid metric #{metric.inspect}" unless metric.is_a? String
|
99
|
+
Log.warn "Invalid exit code: #{exit_code.inspect}" unless exit_code.is_a? Integer
|
100
|
+
|
101
|
+
if normal_range
|
102
|
+
Log.warn "Invalid normal range: #{normal_range.inspect}" unless normal_range.is_a? Array
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def check (value)
|
107
|
+
Log.debug "#{host_instance.url} | Given: #{metric}=#{value}"
|
108
|
+
|
109
|
+
# error on missing value unless we ignore missing
|
110
|
+
unless value
|
111
|
+
unless missing == :ignore
|
112
|
+
Log.warn "#{metric}: value missing, treating as error; exit code #{exit_code}"
|
113
|
+
return exit_code
|
114
|
+
else
|
115
|
+
Log.debug "#{host_instance.url} | missing value, but set to ignore"
|
116
|
+
# not an error, but you can't check anything else
|
117
|
+
return false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# compute rate
|
122
|
+
if rate
|
123
|
+
timestamp, previous = host_instance.previous_reading(metric)
|
124
|
+
|
125
|
+
if previous
|
126
|
+
Log.debug "#{host_instance.url} | last seen: #{previous} @ #{timestamp}"
|
127
|
+
|
128
|
+
# change since last measure
|
129
|
+
value -= previous
|
130
|
+
|
131
|
+
# divide by seconds elapsed
|
132
|
+
value /= Time.now.to_i - timestamp
|
133
|
+
|
134
|
+
Log.debug "#{host_instance.url} | computed rate: #{value}"
|
135
|
+
|
136
|
+
else
|
137
|
+
# let it pass
|
138
|
+
Log.info "#{metric}: no previous reading for rate"
|
139
|
+
return false
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# ensure value is within normal range
|
144
|
+
if normal_range
|
145
|
+
Log.debug "#{host_instance.url} | normal range: #{normal_range.inspect}"
|
146
|
+
case normal_range.size
|
147
|
+
when 1 # max
|
148
|
+
hi = normal_range.first
|
149
|
+
|
150
|
+
when 2 # min
|
151
|
+
lo = normal_range.first
|
152
|
+
hi = normal_range.last
|
153
|
+
|
154
|
+
else
|
155
|
+
# whatever, ignore
|
156
|
+
# the yaml deserializer shouldn't let this happen
|
157
|
+
end
|
158
|
+
|
159
|
+
if lo && value < lo
|
160
|
+
Log.warn "#{metric}: read value #{value} is below normal range minimum #{lo}; exit code #{exit_code}"
|
161
|
+
return exit_code
|
162
|
+
end
|
163
|
+
|
164
|
+
if hi && value > hi
|
165
|
+
Log.warn "#{metric}: read value #{value} is above normal range maximum #{hi}; exit code #{exit_code}"
|
166
|
+
return exit_code
|
167
|
+
end
|
168
|
+
|
169
|
+
Log.debug "#{host_instance.url} | within normal range"
|
170
|
+
end
|
171
|
+
|
172
|
+
false
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
data/lib/ostrichpoll.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'trollop'
|
3
|
+
require 'pp'
|
4
|
+
require 'net/http'
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
require 'ostrichpoll/string'
|
8
|
+
require 'ostrichpoll/version'
|
9
|
+
require 'ostrichpoll/exit_codes'
|
10
|
+
require 'ostrichpoll/config_parser'
|
11
|
+
|
12
|
+
module OstrichPoll
|
13
|
+
Log = Logger.new(STDERR)
|
14
|
+
|
15
|
+
@opts = Trollop::options do
|
16
|
+
version = "ostrichpoll #{VERSION}"
|
17
|
+
banner_text = <<-EOS
|
18
|
+
A ruby utility for monitoring JSON endpoints (Twitter Ostrich, specifically)
|
19
|
+
for normal ranges of values.
|
20
|
+
EOS
|
21
|
+
banner(banner_text.strip_heredoc)
|
22
|
+
|
23
|
+
opt :configfile, "YAML configuration",
|
24
|
+
type: :string
|
25
|
+
|
26
|
+
opt :url, "url",
|
27
|
+
type: :string,
|
28
|
+
default: 'http://127.0.0.1:9900/stats.json'
|
29
|
+
|
30
|
+
opt :debug, "debug",
|
31
|
+
:default => false
|
32
|
+
end
|
33
|
+
|
34
|
+
if @opts[:configfile] and not File.readable_real?(@opts[:configfile])
|
35
|
+
Trollop::die "configuration file #{@opts[:configfile]} cannot be read"
|
36
|
+
end
|
37
|
+
|
38
|
+
if @opts[:debug]
|
39
|
+
Log.level = Logger::DEBUG
|
40
|
+
else
|
41
|
+
Log.level = Logger::WARN
|
42
|
+
end
|
43
|
+
|
44
|
+
# TODO rewrite the basic check in terms of a hard-coded validator, much cleaner
|
45
|
+
# check that the host+port respond to http
|
46
|
+
if @opts[:configfile]
|
47
|
+
yaml = YAML.load_file @opts[:configfile]
|
48
|
+
hosts = ConfigParser.parse(yaml)
|
49
|
+
|
50
|
+
retval = false
|
51
|
+
hosts.each do |h|
|
52
|
+
retval = h.validate unless retval
|
53
|
+
end
|
54
|
+
|
55
|
+
# use the exitcode, unless none is given
|
56
|
+
exit retval if retval
|
57
|
+
|
58
|
+
else
|
59
|
+
# if we don't have a config file, simply check that the host and port respond to http
|
60
|
+
begin
|
61
|
+
uri = URI.parse @opts[:url]
|
62
|
+
@response = Net::HTTP.get uri
|
63
|
+
rescue Exception => e
|
64
|
+
Log.warn e
|
65
|
+
exit EXIT_NOHTTP
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
rescue SystemExit => e
|
70
|
+
exit e.status
|
71
|
+
|
72
|
+
rescue Exception => e
|
73
|
+
Log.error e
|
74
|
+
exit EXIT_ERROR # exit with error
|
75
|
+
end
|
76
|
+
|
77
|
+
exit OstrichPoll::EXIT_OK
|
data/ostrichPoll.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/ostrichPoll/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Wiktor Macura"]
|
6
|
+
gem.email = ["wiktor@tumblr.com"]
|
7
|
+
gem.description = %q{Ostrichpoll is a tiny utility for monitoring Twitter Ostrich services. Effectively it can monitor any service which exposes internal metrics in JSON over HTTP.}
|
8
|
+
gem.summary = %q{Ostrichpoll is a tiny utility for monitoring Twitter Ostrich services.}
|
9
|
+
gem.homepage = "http://github.com/tumblr/ostrichpoll"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "ostrichpoll"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = OstrichPoll::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency 'json'
|
19
|
+
gem.add_development_dependency 'trollop'
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ostrichpoll
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Wiktor Macura
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-08 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: &70093421674620 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70093421674620
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: trollop
|
27
|
+
requirement: &70093413683700 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70093413683700
|
36
|
+
description: Ostrichpoll is a tiny utility for monitoring Twitter Ostrich services.
|
37
|
+
Effectively it can monitor any service which exposes internal metrics in JSON over
|
38
|
+
HTTP.
|
39
|
+
email:
|
40
|
+
- wiktor@tumblr.com
|
41
|
+
executables:
|
42
|
+
- ostrichpoll
|
43
|
+
extensions: []
|
44
|
+
extra_rdoc_files: []
|
45
|
+
files:
|
46
|
+
- .gitignore
|
47
|
+
- .rvmrc
|
48
|
+
- Gemfile
|
49
|
+
- LICENSE.md
|
50
|
+
- README.md
|
51
|
+
- Rakefile
|
52
|
+
- bin/ostrichpoll
|
53
|
+
- exampleconfigs/firehose.yml
|
54
|
+
- lib/ostrichpoll.rb
|
55
|
+
- lib/ostrichpoll/config_parser.rb
|
56
|
+
- lib/ostrichpoll/exit_codes.rb
|
57
|
+
- lib/ostrichpoll/ostrich_validator.rb
|
58
|
+
- lib/ostrichpoll/string.rb
|
59
|
+
- lib/ostrichpoll/version.rb
|
60
|
+
- ostrichPoll.gemspec
|
61
|
+
homepage: http://github.com/tumblr/ostrichpoll
|
62
|
+
licenses: []
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 1.8.10
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: Ostrichpoll is a tiny utility for monitoring Twitter Ostrich services.
|
85
|
+
test_files: []
|