meter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -0
- data/README.md +29 -0
- data/lib/meter/backend.rb +190 -0
- data/lib/meter/configuration.rb +112 -0
- data/lib/meter/version.rb +9 -0
- data/lib/meter.rb +42 -0
- data/spec/lib/meter/backend_spec.rb +18 -0
- data/spec/lib/meter/configuration_spec.rb +60 -0
- data/spec/lib/meter_spec.rb +34 -0
- data/spec/spec_helper.rb +33 -0
- metadata +107 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2013 Bukowskis
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Meter
|
2
|
+
|
3
|
+
BETA!
|
4
|
+
|
5
|
+
A generic abstraction layer for fire and forgetting measurements via UDP.
|
6
|
+
|
7
|
+
# Installation
|
8
|
+
|
9
|
+
```bash
|
10
|
+
gem install meter
|
11
|
+
````
|
12
|
+
|
13
|
+
# Usage
|
14
|
+
|
15
|
+
#### Syntax
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
Meter.increment key, delta, options
|
19
|
+
````
|
20
|
+
|
21
|
+
#### Examples
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
Meter.increment 'my.key'
|
25
|
+
Meter.increment 'my.key', 5
|
26
|
+
Meter.increment 'my.key', 5, sample_rate: 0.25
|
27
|
+
|
28
|
+
Meter.gauge 'my.gauge.key', 20
|
29
|
+
```
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
# Copy and paste from https://github.com/DataDog/dogstatsd-ruby/blob/master/lib/statsd.rb
|
4
|
+
# Changes:
|
5
|
+
# - The class is renamed to "Backend"
|
6
|
+
# - the logger class method points to meter's logger
|
7
|
+
|
8
|
+
module Meter
|
9
|
+
# = Statsd: A DogStatsd client (https://www.datadoghq.com)
|
10
|
+
#
|
11
|
+
# @example Set up a global Statsd client for a server on localhost:8125
|
12
|
+
# require 'statsd'
|
13
|
+
# $statsd = Statsd.new 'localhost', 8125
|
14
|
+
# @example Send some stats
|
15
|
+
# $statsd.increment 'page.views'
|
16
|
+
# $statsd.timing 'page.load', 320
|
17
|
+
# $statsd.gauge 'users.online', 100
|
18
|
+
# @example Use {#time} to time the execution of a block
|
19
|
+
# $statsd.time('account.activate') { @account.activate! }
|
20
|
+
# @example Create a namespaced statsd client and increment 'account.activate'
|
21
|
+
# statsd = Statsd.new('localhost').tap{|sd| sd.namespace = 'account'}
|
22
|
+
# statsd.increment 'activate'
|
23
|
+
class Backend
|
24
|
+
# A namespace to prepend to all statsd calls.
|
25
|
+
attr_reader :namespace
|
26
|
+
|
27
|
+
# StatsD host. Defaults to 127.0.0.1.
|
28
|
+
attr_accessor :host
|
29
|
+
|
30
|
+
# StatsD port. Defaults to 8125.
|
31
|
+
attr_accessor :port
|
32
|
+
|
33
|
+
def self.logger
|
34
|
+
Meter.config.logger
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return the current version of the library.
|
38
|
+
def self.VERSION
|
39
|
+
"1.1.0"
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param [String] host your statsd host
|
43
|
+
# @param [Integer] port your statsd port
|
44
|
+
def initialize(host = '127.0.0.1', port = 8125)
|
45
|
+
self.host, self.port = host, port
|
46
|
+
@prefix = nil
|
47
|
+
@socket = UDPSocket.new
|
48
|
+
end
|
49
|
+
|
50
|
+
def namespace=(namespace) #:nodoc:
|
51
|
+
@namespace = namespace
|
52
|
+
@prefix = "#{namespace}."
|
53
|
+
end
|
54
|
+
|
55
|
+
def host=(host) #:nodoc:
|
56
|
+
@host = host || '127.0.0.1'
|
57
|
+
end
|
58
|
+
|
59
|
+
def port=(port) #:nodoc:
|
60
|
+
@port = port || 8125
|
61
|
+
end
|
62
|
+
|
63
|
+
# Sends an increment (count = 1) for the given stat to the statsd server.
|
64
|
+
#
|
65
|
+
# @param [String] stat stat name
|
66
|
+
# @param [Hash] opts the options to create the metric with
|
67
|
+
# @option opts [Numeric] :sample_rate sample rate, 1 for always
|
68
|
+
# @option opts [Array<String>] :tags An array of tags
|
69
|
+
# @see #count
|
70
|
+
def increment(stat, opts={})
|
71
|
+
count stat, 1, opts
|
72
|
+
end
|
73
|
+
|
74
|
+
# Sends a decrement (count = -1) for the given stat to the statsd server.
|
75
|
+
#
|
76
|
+
# @param [String] stat stat name
|
77
|
+
# @param [Hash] opts the options to create the metric with
|
78
|
+
# @option opts [Numeric] :sample_rate sample rate, 1 for always
|
79
|
+
# @option opts [Array<String>] :tags An array of tags
|
80
|
+
# @see #count
|
81
|
+
def decrement(stat, opts={})
|
82
|
+
count stat, -1, opts
|
83
|
+
end
|
84
|
+
|
85
|
+
# Sends an arbitrary count for the given stat to the statsd server.
|
86
|
+
#
|
87
|
+
# @param [String] stat stat name
|
88
|
+
# @param [Integer] count count
|
89
|
+
# @param [Hash] opts the options to create the metric with
|
90
|
+
# @option opts [Numeric] :sample_rate sample rate, 1 for always
|
91
|
+
# @option opts [Array<String>] :tags An array of tags
|
92
|
+
def count(stat, count, opts={})
|
93
|
+
send_stats stat, count, :c, opts
|
94
|
+
end
|
95
|
+
|
96
|
+
# Sends an arbitary gauge value for the given stat to the statsd server.
|
97
|
+
#
|
98
|
+
# This is useful for recording things like available disk space,
|
99
|
+
# memory usage, and the like, which have different semantics than
|
100
|
+
# counters.
|
101
|
+
#
|
102
|
+
# @param [String] stat stat name.
|
103
|
+
# @param [Numeric] gauge value.
|
104
|
+
# @param [Hash] opts the options to create the metric with
|
105
|
+
# @option opts [Numeric] :sample_rate sample rate, 1 for always
|
106
|
+
# @option opts [Array<String>] :tags An array of tags
|
107
|
+
# @example Report the current user count:
|
108
|
+
# $statsd.gauge('user.count', User.count)
|
109
|
+
def gauge(stat, value, opts={})
|
110
|
+
send_stats stat, value, :g, opts
|
111
|
+
end
|
112
|
+
|
113
|
+
# Sends a value to be tracked as a histogram to the statsd server.
|
114
|
+
#
|
115
|
+
# @param [String] stat stat name.
|
116
|
+
# @param [Numeric] histogram value.
|
117
|
+
# @param [Hash] opts the options to create the metric with
|
118
|
+
# @option opts [Numeric] :sample_rate sample rate, 1 for always
|
119
|
+
# @option opts [Array<String>] :tags An array of tags
|
120
|
+
# @example Report the current user count:
|
121
|
+
# $statsd.histogram('user.count', User.count)
|
122
|
+
def histogram(stat, value, opts={})
|
123
|
+
send_stats stat, value, :h, opts
|
124
|
+
end
|
125
|
+
|
126
|
+
# Sends a timing (in ms) for the given stat to the statsd server. The
|
127
|
+
# sample_rate determines what percentage of the time this report is sent. The
|
128
|
+
# statsd server then uses the sample_rate to correctly track the average
|
129
|
+
# timing for the stat.
|
130
|
+
#
|
131
|
+
# @param [String] stat stat name
|
132
|
+
# @param [Integer] ms timing in milliseconds
|
133
|
+
# @param [Hash] opts the options to create the metric with
|
134
|
+
# @option opts [Numeric] :sample_rate sample rate, 1 for always
|
135
|
+
# @option opts [Array<String>] :tags An array of tags
|
136
|
+
def timing(stat, ms, opts={})
|
137
|
+
send_stats stat, ms, :ms, opts
|
138
|
+
end
|
139
|
+
|
140
|
+
# Reports execution time of the provided block using {#timing}.
|
141
|
+
#
|
142
|
+
# @param [String] stat stat name
|
143
|
+
# @param [Hash] opts the options to create the metric with
|
144
|
+
# @option opts [Numeric] :sample_rate sample rate, 1 for always
|
145
|
+
# @option opts [Array<String>] :tags An array of tags
|
146
|
+
# @yield The operation to be timed
|
147
|
+
# @see #timing
|
148
|
+
# @example Report the time (in ms) taken to activate an account
|
149
|
+
# $statsd.time('account.activate') { @account.activate! }
|
150
|
+
def time(stat, opts={})
|
151
|
+
start = Time.now
|
152
|
+
result = yield
|
153
|
+
timing(stat, ((Time.now - start) * 1000).round, opts)
|
154
|
+
result
|
155
|
+
end
|
156
|
+
# Sends a value to be tracked as a set to the statsd server.
|
157
|
+
#
|
158
|
+
# @param [String] stat stat name.
|
159
|
+
# @param [Numeric] set value.
|
160
|
+
# @param [Hash] opts the options to create the metric with
|
161
|
+
# @option opts [Numeric] :sample_rate sample rate, 1 for always
|
162
|
+
# @option opts [Array<String>] :tags An array of tags
|
163
|
+
# @example Record a unique visitory by id:
|
164
|
+
# $statsd.set('visitors.uniques', User.id)
|
165
|
+
def set(stat, value, opts={})
|
166
|
+
send_stats stat, value, :s, opts
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
|
171
|
+
def send_stats(stat, delta, type, opts={})
|
172
|
+
sample_rate = opts[:sample_rate] || 1
|
173
|
+
if sample_rate == 1 or rand < sample_rate
|
174
|
+
# Replace Ruby module scoping with '.' and reserved chars (: | @) with underscores.
|
175
|
+
stat = stat.to_s.gsub('::', '.').tr(':|@', '_')
|
176
|
+
rate = "|@#{sample_rate}" unless sample_rate == 1
|
177
|
+
tags = "|##{opts[:tags].join(",")}" if opts[:tags]
|
178
|
+
send_to_socket "#{@prefix}#{stat}:#{delta}|#{type}#{rate}#{tags}"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def send_to_socket(message)
|
183
|
+
self.class.logger.debug { "Statsd: #{message}" } if self.class.logger
|
184
|
+
@socket.send(message, 0, @host, @port)
|
185
|
+
rescue => boom
|
186
|
+
self.class.logger.error { "Statsd: #{boom.class} #{boom}" } if self.class.logger
|
187
|
+
nil
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'meter/backend'
|
3
|
+
|
4
|
+
module Meter
|
5
|
+
class Configuration
|
6
|
+
|
7
|
+
attr_accessor :logger, :tags
|
8
|
+
attr_reader :primary_backend, :secondary_backend
|
9
|
+
|
10
|
+
def initialize(options={})
|
11
|
+
@logger = options[:logger] || default_logger
|
12
|
+
@primary_backend = Backend.new
|
13
|
+
@primary_backend.host = options[:primary_host] || default_host
|
14
|
+
@primary_backend.port = options[:primary_port] || default_port
|
15
|
+
@primary_backend.namespace = options[:namespace] || default_namespace
|
16
|
+
@secondary_backend = Backend.new
|
17
|
+
@secondary_backend.host = options[:secondary_host] || default_host
|
18
|
+
@secondary_backend.port = options[:secondary_port] || default_secondary_port
|
19
|
+
@secondary_backend.namespace = options[:namespace] || default_namespace
|
20
|
+
@tags = options[:tags] || {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def namespace=(new_namespace)
|
24
|
+
primary_backend.namespace = new_namespace
|
25
|
+
secondary_backend.namespace = new_namespace
|
26
|
+
end
|
27
|
+
|
28
|
+
def namespace
|
29
|
+
primary_backend.namespace
|
30
|
+
end
|
31
|
+
|
32
|
+
def primary_host
|
33
|
+
primary_backend.host
|
34
|
+
end
|
35
|
+
|
36
|
+
def primary_port
|
37
|
+
primary_backend.port
|
38
|
+
end
|
39
|
+
|
40
|
+
def secondary_host
|
41
|
+
secondary_backend.host
|
42
|
+
end
|
43
|
+
|
44
|
+
def secondary_port
|
45
|
+
secondary_backend.port
|
46
|
+
end
|
47
|
+
|
48
|
+
def primary_host=(new_host)
|
49
|
+
primary_backend.host = new_host
|
50
|
+
end
|
51
|
+
|
52
|
+
def primary_port=(new_port)
|
53
|
+
primary_backend.port = new_port
|
54
|
+
end
|
55
|
+
|
56
|
+
def secondary_host=(new_host)
|
57
|
+
secondary_backend.host = new_host
|
58
|
+
end
|
59
|
+
|
60
|
+
def secondary_port=(new_port)
|
61
|
+
secondary_backend.port = new_port
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def default_logger
|
67
|
+
if defined?(Rails)
|
68
|
+
Rails.logger
|
69
|
+
else
|
70
|
+
Logger.new(STDOUT)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def default_host
|
75
|
+
'127.0.0.1'
|
76
|
+
end
|
77
|
+
|
78
|
+
def default_port
|
79
|
+
8125
|
80
|
+
end
|
81
|
+
|
82
|
+
def default_secondary_port
|
83
|
+
3333
|
84
|
+
end
|
85
|
+
|
86
|
+
def default_namespace
|
87
|
+
'meter'
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
module Meter
|
94
|
+
|
95
|
+
# Public: Returns the the configuration instance.
|
96
|
+
#
|
97
|
+
def self.config
|
98
|
+
@config ||= Configuration.new
|
99
|
+
end
|
100
|
+
|
101
|
+
# Public: Yields the configuration instance.
|
102
|
+
#
|
103
|
+
def self.configure(&block)
|
104
|
+
yield config
|
105
|
+
end
|
106
|
+
|
107
|
+
# Public: Reset the configuration (useful for testing).
|
108
|
+
#
|
109
|
+
def self.reset!
|
110
|
+
@config = nil
|
111
|
+
end
|
112
|
+
end
|
data/lib/meter.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'meter/configuration'
|
2
|
+
|
3
|
+
# A generic wrapper for Statsd-like gauges and counters.
|
4
|
+
#
|
5
|
+
module Meter
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def increment(key, options = {})
|
9
|
+
id = options.delete(:id)
|
10
|
+
primary.increment key, options
|
11
|
+
if id
|
12
|
+
secondary.increment "#{key}.#{id}", options
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def count(key, delta, options = {})
|
17
|
+
id = options.delete(:id)
|
18
|
+
primary.count key, delta, options
|
19
|
+
if id
|
20
|
+
secondary.count "#{key}.#{id}", delta, options
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def gauge(key, value, options = {})
|
25
|
+
primary.gauge key, value, options
|
26
|
+
end
|
27
|
+
|
28
|
+
def histogram(key, value, options = {})
|
29
|
+
primary.histogram key, value, options
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def primary
|
35
|
+
config.primary_backend
|
36
|
+
end
|
37
|
+
|
38
|
+
def secondary
|
39
|
+
config.secondary_backend
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'meter'
|
3
|
+
|
4
|
+
describe Meter::Backend do
|
5
|
+
|
6
|
+
let(:backend) { Meter.config.primary_backend }
|
7
|
+
|
8
|
+
before do
|
9
|
+
Meter.reset!
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.increment' do
|
13
|
+
it 'works and I did not make any mistakes when copy and pasting the backend from StatsD' do
|
14
|
+
backend.increment 'my.counter'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'meter/configuration'
|
3
|
+
|
4
|
+
describe Meter::Configuration do
|
5
|
+
|
6
|
+
let(:logger) { mock(:logger) }
|
7
|
+
let(:config) { Meter.config }
|
8
|
+
|
9
|
+
before do
|
10
|
+
Meter.reset!
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '.config' do
|
14
|
+
|
15
|
+
describe '#logger' do
|
16
|
+
it 'is an STDOUT logger' do
|
17
|
+
Logger.should_receive(:new).with(STDOUT).and_return logger
|
18
|
+
config.logger.should be logger
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with Rails' do
|
22
|
+
before do
|
23
|
+
ensure_module :Rails
|
24
|
+
Rails.stub!(:logger).and_return(logger)
|
25
|
+
end
|
26
|
+
|
27
|
+
after do
|
28
|
+
Object.send(:remove_const, :Rails)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'is the Rails logger' do
|
32
|
+
config.logger.should be Rails.logger
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#primary_backend and #secondary_backend' do
|
38
|
+
it 'is a Backend' do
|
39
|
+
config.primary_backend.should be_instance_of Meter::Backend
|
40
|
+
config.secondary_backend.should be_instance_of Meter::Backend
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'has the default host' do
|
44
|
+
config.primary_backend.host.should == '127.0.0.1'
|
45
|
+
config.secondary_backend.host.should == '127.0.0.1'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'has the default namespace' do
|
49
|
+
config.primary_backend.namespace.should == 'meter'
|
50
|
+
config.secondary_backend.namespace.should == 'meter'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'has the default port' do
|
54
|
+
config.primary_backend.port.should == 8125
|
55
|
+
config.secondary_backend.port.should == 3333
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Meter do
|
4
|
+
|
5
|
+
let(:meter) { Meter }
|
6
|
+
let(:primary) { Meter.config.primary_backend }
|
7
|
+
let(:secondary) { Meter.config.secondary_backend }
|
8
|
+
|
9
|
+
describe '.increment' do
|
10
|
+
context "when given an id as option" do
|
11
|
+
it "proxies to the secondary with the id" do
|
12
|
+
secondary.should_receive(:increment).with("my.key.123", {})
|
13
|
+
meter.increment 'my.key', :id => 123
|
14
|
+
end
|
15
|
+
|
16
|
+
it "proxies to the primary without the id" do
|
17
|
+
primary.should_receive(:increment).with("my.key", {})
|
18
|
+
meter.increment 'my.key', :id => 123
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when id is NOT given as an option" do
|
23
|
+
it "doesn't proxy to the secondary at all" do
|
24
|
+
secondary.should_not_receive(:increment)
|
25
|
+
meter.increment 'my.key'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "proxies to the primary" do
|
29
|
+
primary.should_receive(:increment).with("my.key", {})
|
30
|
+
meter.increment 'my.key'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'meter'
|
2
|
+
|
3
|
+
def ensure_class_or_module(full_name, class_or_module)
|
4
|
+
full_name.to_s.split(/::/).inject(Object) do |context, name|
|
5
|
+
begin
|
6
|
+
context.const_get(name)
|
7
|
+
rescue NameError
|
8
|
+
if class_or_module == :class
|
9
|
+
context.const_set(name, Class.new)
|
10
|
+
else
|
11
|
+
context.const_set(name, Module.new)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def ensure_module(name)
|
18
|
+
ensure_class_or_module(name, :module)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ensure_class(name)
|
22
|
+
ensure_class_or_module(name, :class)
|
23
|
+
end
|
24
|
+
|
25
|
+
RSpec.configure do |config|
|
26
|
+
config.before do
|
27
|
+
Meter.config.logger = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
config.after do
|
31
|
+
Meter.reset!
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: meter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- bukowskis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-08-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
none: false
|
21
|
+
name: rspec
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ! '>='
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
29
|
+
none: false
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
version_requirements: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
none: false
|
37
|
+
name: guard-rspec
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
none: false
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
none: false
|
53
|
+
name: rb-fsevent
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
none: false
|
62
|
+
description: A generic abstraction layer for fire and forgetting measurements via
|
63
|
+
UDP.
|
64
|
+
email:
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- lib/meter/backend.rb
|
70
|
+
- lib/meter/configuration.rb
|
71
|
+
- lib/meter/version.rb
|
72
|
+
- lib/meter.rb
|
73
|
+
- spec/lib/meter/backend_spec.rb
|
74
|
+
- spec/lib/meter/configuration_spec.rb
|
75
|
+
- spec/lib/meter_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
- README.md
|
78
|
+
- LICENSE
|
79
|
+
homepage: https://github.com/bukowskis/meter
|
80
|
+
licenses:
|
81
|
+
- MIT
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options:
|
84
|
+
- --encoding
|
85
|
+
- UTF-8
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
none: false
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
none: false
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 1.8.23
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: A generic abstraction layer for fire and forgetting measurements via UDP.
|
106
|
+
test_files: []
|
107
|
+
has_rdoc:
|