leafy-metrics 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 +7 -0
- data/.gitignore +5 -0
- data/Gemfile +7 -0
- data/LICENSE +22 -0
- data/README.md +183 -0
- data/Rakefile +14 -0
- data/leafy-metrics.gemspec +29 -0
- data/lib/leafy-metrics.rb +2 -0
- data/lib/leafy-metrics_jars.rb +5 -0
- data/lib/leafy/metrics.rb +2 -0
- data/lib/leafy/metrics/console_reporter.rb +32 -0
- data/lib/leafy/metrics/csv_reporter.rb +26 -0
- data/lib/leafy/metrics/graphite/graphite.rb +28 -0
- data/lib/leafy/metrics/graphite/graphite_reporter.rb +31 -0
- data/lib/leafy/metrics/registry.rb +96 -0
- data/lib/leafy/metrics/reporter.rb +48 -0
- data/lib/leafy/metrics/version.rb +6 -0
- data/spec/console_reporter_spec.rb +51 -0
- data/spec/csv_reporter_spec.rb +55 -0
- data/spec/graphite_reporter_spec.rb +51 -0
- data/spec/graphite_spec.rb +23 -0
- data/spec/registry_spec.rb +92 -0
- data/spec/setup.rb +10 -0
- metadata +127 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 32f03a451482abd7703260a77742d3e6673fa1f6
|
4
|
+
data.tar.gz: 353a861b96966a5b6c57103e6342de7360db0ecf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c7af7eebe97349d2c17327efe778fa8d84f078fda748b3258a83284ad33579da965b7429c6cad0b3d8589aa048fd8dec88a8a95da9c92e66f5fd3c76d402376
|
7
|
+
data.tar.gz: e974467905d84881a2213ede5ccef40bed73de429046080b5a7def0a305ff174ecaceedd8bf6c413801f95ce001dfb05b0fd93d3f12549079cccc5c29dc2ef33
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Lookout
|
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 all
|
13
|
+
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 THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
# Leafy-Metrics
|
2
|
+
|
3
|
+
## installation
|
4
|
+
|
5
|
+
via rubygems
|
6
|
+
```
|
7
|
+
gem install leafy-metrics
|
8
|
+
```
|
9
|
+
or add to your Gemfile
|
10
|
+
```
|
11
|
+
gem 'leafy-metrics'
|
12
|
+
```
|
13
|
+
|
14
|
+
installing the gem also takes care of the jar dependencies with jruby-1.7.16+
|
15
|
+
|
16
|
+
## usage
|
17
|
+
|
18
|
+
an instance of the registry ```Leafy::Metrics::Registry``` can register various metrics like gauge, timer, meter, counter and histogram and remove them again.
|
19
|
+
|
20
|
+
registry = Leafy::Metrics::Registry.new
|
21
|
+
|
22
|
+
### gauge
|
23
|
+
|
24
|
+
it can be other a given block or any object with a #call method returning the gauge - a number
|
25
|
+
|
26
|
+
registry.register_gauge( 'app.uptime') do
|
27
|
+
App.uptime
|
28
|
+
end
|
29
|
+
|
30
|
+
or with an object
|
31
|
+
|
32
|
+
class UptimeGauge
|
33
|
+
def call
|
34
|
+
App.uptime
|
35
|
+
enf
|
36
|
+
end
|
37
|
+
registry.register_gauge( 'app.uptime', UptimeGauge.new )
|
38
|
+
|
39
|
+
### timer
|
40
|
+
|
41
|
+
a timer can measure the time an block needs to execute:
|
42
|
+
|
43
|
+
timer = registry.register_timer( 'app.timer' )
|
44
|
+
timer.time do
|
45
|
+
App.update_data
|
46
|
+
end
|
47
|
+
|
48
|
+
### counter
|
49
|
+
|
50
|
+
a counter simply counts i.e. can be incremented or decremented
|
51
|
+
|
52
|
+
counter = registry.register_counter( 'active.users.counter' )
|
53
|
+
|
54
|
+
# one new user logged on
|
55
|
+
counter.inc
|
56
|
+
|
57
|
+
# three new users logged on
|
58
|
+
counter.inc 3
|
59
|
+
|
60
|
+
# one user logged off
|
61
|
+
counter.dec
|
62
|
+
|
63
|
+
# two users logged off
|
64
|
+
counter.dec 2
|
65
|
+
|
66
|
+
### meter
|
67
|
+
|
68
|
+
used = registry.register_meter( 'app.used' )
|
69
|
+
|
70
|
+
mark the occurrence of an event
|
71
|
+
|
72
|
+
used.mark
|
73
|
+
|
74
|
+
mark the occurrence of 'n' events
|
75
|
+
|
76
|
+
used.mark n
|
77
|
+
|
78
|
+
|
79
|
+
### histogram
|
80
|
+
|
81
|
+
measures the distribution of values in a stream of data using an exponentially decaying reservoir
|
82
|
+
|
83
|
+
histogram = registry.register_histogram( 'search.results' )
|
84
|
+
histogram.update( Search.last_result.size )
|
85
|
+
|
86
|
+
### remove any metrics
|
87
|
+
|
88
|
+
registry.unregister( 'app.uptime )
|
89
|
+
|
90
|
+
### note
|
91
|
+
|
92
|
+
currently there is not further introspection on the registry and its health-check. with the ```Leafy::Json::MetricsWriter``` (from leafy-rack) you can get a json representation of the current **metrics report**
|
93
|
+
|
94
|
+
Leafy::Json::MetricsWriter.to_json( registry.metrics )
|
95
|
+
|
96
|
+
## reporters
|
97
|
+
|
98
|
+
all reporters use a builder pattern. there are following timeunits for
|
99
|
+
configuration:
|
100
|
+
|
101
|
+
* ```Leafy::Metrics::Reporter::DAYS```
|
102
|
+
* ```Leafy::Metrics::Reporter::HOURS```
|
103
|
+
* ```Leafy::Metrics::Reporter::MINUTES```
|
104
|
+
* ```Leafy::Metrics::Reporter::SECONDS```
|
105
|
+
* ```Leafy::Metrics::Reporter::MILLISECONDS```
|
106
|
+
* ```Leafy::Metrics::Reporter::MICROSECONDS```
|
107
|
+
* ```Leafy::Metrics::Reporter::NANOSECONDS```
|
108
|
+
|
109
|
+
in all examples below ```metrics = Leafy::Metrics::Registry.new```
|
110
|
+
|
111
|
+
### console reporter
|
112
|
+
|
113
|
+
require 'leafy/metrics/console_reporter'
|
114
|
+
reporter = Leafy::Metrics::ConsoleReporter.for_registry( metrics ).build
|
115
|
+
reporter.start( 1, Leafy::Metrics::Reporter::SECONDS )
|
116
|
+
....
|
117
|
+
reporter.stop
|
118
|
+
|
119
|
+
or with all the possible configuration
|
120
|
+
|
121
|
+
reporter = Leafy::Metrics::ConsoleReporter.for_registry( metrics )
|
122
|
+
.convert_rates_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
123
|
+
.convert_durations_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
124
|
+
.output_to( STDERR )
|
125
|
+
.build
|
126
|
+
|
127
|
+
### csv reporter
|
128
|
+
|
129
|
+
for each metric there will be a CSV file inside a given directory
|
130
|
+
|
131
|
+
require 'leafy/metrics/csv_reporter'
|
132
|
+
reporter = Leafy::Metrics::CSVReporter.for_registry( metrics )
|
133
|
+
.build( 'metrics/directory' )
|
134
|
+
reporter.start( 1, Leafy::Metrics::Reporter::SECONDS )
|
135
|
+
....
|
136
|
+
reporter.stop
|
137
|
+
|
138
|
+
or with all possible configuration
|
139
|
+
|
140
|
+
reporter = Leafy::Metrics::CSVReporter.for_registry( metrics )
|
141
|
+
.convert_rates_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
142
|
+
.convert_durations_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
143
|
+
.build( 'metrics/directory' )
|
144
|
+
|
145
|
+
### graphite reporter
|
146
|
+
|
147
|
+
there are three targets where to send the data
|
148
|
+
|
149
|
+
* ```Leafy::Metrics::Graphite.new_tcp( hostname, port )```
|
150
|
+
* ```Leafy::Metrics::Graphite.new_udp( hostname, port )```
|
151
|
+
* ```Leafy::Metrics::Graphite.new_pickled( hostname, port, batchsize )```
|
152
|
+
|
153
|
+
the latter is collecting a few report event and sends them as batch. the ```sender``` is one of the above targets.
|
154
|
+
|
155
|
+
require 'leafy/metrics/graphite_reporter'
|
156
|
+
reporter = Leafy::Metrics::GraphiteReporter.for_registry( metrics )
|
157
|
+
.build( sender )
|
158
|
+
reporter.start( 1, Leafy::Metrics::Reporter::SECONDS )
|
159
|
+
....
|
160
|
+
reporter.stop
|
161
|
+
|
162
|
+
or with full configuration
|
163
|
+
|
164
|
+
reporter = Leafy::Metrics::GraphiteReporter.for_registry( metrics )
|
165
|
+
.convert_rates_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
166
|
+
.convert_durations_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
167
|
+
.prefixed_with( 'myapp' )
|
168
|
+
.build( sender )
|
169
|
+
|
170
|
+
## developement
|
171
|
+
|
172
|
+
get all the gems and jars in place
|
173
|
+
|
174
|
+
gem install jar-dependencies --development
|
175
|
+
bundle install
|
176
|
+
|
177
|
+
for running all specs
|
178
|
+
|
179
|
+
rake
|
180
|
+
|
181
|
+
or
|
182
|
+
|
183
|
+
rspec spec/reporter_spec.rb
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#-*- mode: ruby -*-
|
2
|
+
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
RSpec::Core::RakeTask.new
|
5
|
+
|
6
|
+
require "yard"
|
7
|
+
YARD::Rake::YardocTask.new do |t|
|
8
|
+
t.files = ['lib/**/*.rb']
|
9
|
+
t.options += ["--title", "Leafy Metrics API"]
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => [ :spec ]
|
13
|
+
|
14
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#-*- mode: ruby -*-
|
2
|
+
|
3
|
+
require File.expand_path( '../lib/leafy/metrics/version', __FILE__ )
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'leafy-metrics'
|
7
|
+
s.version = Leafy::Metrics::VERSION
|
8
|
+
s.author = 'christian meier'
|
9
|
+
s.email = [ 'christian.meier@lookout.com' ]
|
10
|
+
|
11
|
+
s.license = 'MIT'
|
12
|
+
s.summary = %q(provide an API to register metrics)
|
13
|
+
s.homepage = 'https://github.com/lookout/leafy'
|
14
|
+
s.description = %q(provides an API to register metrics like meters, timers, gauge, counter using dropwizard-metrics. it also allows to setup reporters: console-reporter, csv-reporter and graphite-reporter)
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split($/)
|
17
|
+
|
18
|
+
METRICS_VERSION = '3.1.0'
|
19
|
+
s.requirements << "jar io.dropwizard.metrics:metrics-core, #{METRICS_VERSION}"
|
20
|
+
s.requirements << "jar io.dropwizard.metrics:metrics-graphite, #{METRICS_VERSION}"
|
21
|
+
s.requirements << "jar org.slf4j, slf4j-simple, 1.7.7, :scope => :test"
|
22
|
+
|
23
|
+
s.add_runtime_dependency 'jar-dependencies', '~> 0.1.8'
|
24
|
+
s.add_development_dependency 'rspec', '~> 3.1.0'
|
25
|
+
s.add_development_dependency 'yard', '~> 0.8.7'
|
26
|
+
s.add_development_dependency 'rake', '~> 10.2'
|
27
|
+
end
|
28
|
+
|
29
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'leafy/metrics/reporter'
|
2
|
+
|
3
|
+
java_import com.codahale.metrics.ConsoleReporter
|
4
|
+
|
5
|
+
module Leafy
|
6
|
+
module Metrics
|
7
|
+
class ConsoleReporter < Reporter
|
8
|
+
|
9
|
+
class Builder < Reporter::Builder
|
10
|
+
def initialize( metrics )
|
11
|
+
super( ::ConsoleReporter, metrics )
|
12
|
+
end
|
13
|
+
|
14
|
+
def output_to( io )
|
15
|
+
# IO objects in jruby do have a to_outputstream method
|
16
|
+
@io = java.io.PrintStream.new( io.to_outputstream )
|
17
|
+
@builder.output_to( @io )
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def build
|
22
|
+
Reporter.new( @builder.build )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.for_registry( metrics )
|
27
|
+
Builder.new( metrics )
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'leafy/metrics/reporter'
|
2
|
+
|
3
|
+
java_import com.codahale.metrics.CsvReporter
|
4
|
+
|
5
|
+
module Leafy
|
6
|
+
module Metrics
|
7
|
+
class CSVReporter < Reporter
|
8
|
+
|
9
|
+
class Builder < Reporter::Builder
|
10
|
+
def initialize( metrics )
|
11
|
+
super( ::CsvReporter, metrics )
|
12
|
+
end
|
13
|
+
|
14
|
+
def build( directory )
|
15
|
+
directory = java.io.File.new( directory )
|
16
|
+
Reporter.new( @builder.build( directory ) )
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.for_registry( metrics )
|
21
|
+
Builder.new( metrics )
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Leafy
|
2
|
+
module Metrics
|
3
|
+
class Graphite
|
4
|
+
|
5
|
+
attr_reader :sender
|
6
|
+
|
7
|
+
def initialize( sender )
|
8
|
+
unless sender.java_kind_of? Java::ComCodahaleMetricsGraphite::GraphiteSender
|
9
|
+
raise "not instance of 'Java::ComCodahaleMetricsGraphite::Graphite'"
|
10
|
+
end
|
11
|
+
@sender = sender
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.new_tcp( hostname, port )
|
15
|
+
new com.codahale.metrics.graphite.Graphite.new( hostname, port )
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.new_udp( hostname, port )
|
19
|
+
new com.codahale.metrics.graphite.GraphiteUDP.new( hostname, port )
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.new_pickled( hostname, port, batchsize )
|
23
|
+
new com.codahale.metrics.graphite.PickledGraphite.new( hostname, port, batchsize )
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'leafy/metrics/reporter'
|
2
|
+
require 'leafy/metrics/graphite/graphite'
|
3
|
+
|
4
|
+
java_import com.codahale.metrics.graphite.GraphiteReporter
|
5
|
+
|
6
|
+
module Leafy
|
7
|
+
module Metrics
|
8
|
+
class GraphiteReporter < Reporter
|
9
|
+
|
10
|
+
class Builder < Reporter::Builder
|
11
|
+
def initialize( metrics )
|
12
|
+
super( ::GraphiteReporter, metrics )
|
13
|
+
end
|
14
|
+
|
15
|
+
def prefixed_with( prefix )
|
16
|
+
@builder.prefixed_with( prefix )
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def build( graphite )
|
21
|
+
Reporter.new( @builder.build( graphite.sender ) )
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.for_registry( metrics )
|
26
|
+
Builder.new( metrics )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'leafy/metrics'
|
2
|
+
module Leafy
|
3
|
+
module Metrics
|
4
|
+
class Registry
|
5
|
+
|
6
|
+
class Timer
|
7
|
+
|
8
|
+
attr_reader :timer
|
9
|
+
|
10
|
+
def initialize( timer )
|
11
|
+
@timer = timer
|
12
|
+
end
|
13
|
+
|
14
|
+
def time( &block )
|
15
|
+
context = @timer.time
|
16
|
+
|
17
|
+
yield
|
18
|
+
|
19
|
+
ensure
|
20
|
+
context.stop
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Gauge
|
25
|
+
include com.codahale.metrics.Gauge
|
26
|
+
|
27
|
+
def initialize( block )
|
28
|
+
@block = block
|
29
|
+
end
|
30
|
+
|
31
|
+
def value
|
32
|
+
@block.call
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# state ofthe registry
|
37
|
+
attr_reader :metrics
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
@metrics = com.codahale.metrics.MetricRegistry.new
|
41
|
+
end
|
42
|
+
|
43
|
+
# register a gauge under a given name
|
44
|
+
#
|
45
|
+
# @param [String] name
|
46
|
+
# @param [String] instead of block any gauge object which responds to 'call'
|
47
|
+
# @yieldreturn [Object] can be any object like Fixnum, String, Float
|
48
|
+
# @return [MetricsRegistry::Gauge] gauge object which has a 'value' method to retrieve the current value
|
49
|
+
def register_gauge( name, gauge = nil, &block )
|
50
|
+
if gauge and not block_given? and gauge.respond_to? :call
|
51
|
+
@metrics.register( name, Gauge.new( gauge ) )
|
52
|
+
elsif gauge.nil? and block_given?
|
53
|
+
@metrics.register( name, Gauge.new( block ) )
|
54
|
+
else
|
55
|
+
raise 'needs either a block and object with call method'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# register a meter under a given name
|
60
|
+
#
|
61
|
+
# @param [String] name
|
62
|
+
# @return [Java::ComCodahaleMetrics::Meter] meter object which has a 'mark' method to mark the meter
|
63
|
+
def register_meter( name )
|
64
|
+
@metrics.meter( name )
|
65
|
+
end
|
66
|
+
|
67
|
+
# register a counter under a given name
|
68
|
+
#
|
69
|
+
# @param [String] name
|
70
|
+
# @return [Java::ComCodahaleMetrics::Counter] counter object which has an 'inc' and 'dec' method
|
71
|
+
def register_counter( name )
|
72
|
+
@metrics.counter( name )
|
73
|
+
end
|
74
|
+
|
75
|
+
# register a timer under a given name
|
76
|
+
#
|
77
|
+
# @param [String] name
|
78
|
+
# @return [Java::ComCodahaleMetrics::Timer] timer object which has an 'context' method which starts the timer. the context has a 'stop' method to stop it.
|
79
|
+
def register_timer( name )
|
80
|
+
Timer.new( @metrics.timer( name ) )
|
81
|
+
end
|
82
|
+
|
83
|
+
# register a histogram under a given name
|
84
|
+
#
|
85
|
+
# @param [String] name
|
86
|
+
# @return [Java::ComCodahaleMetrics::Counter] histogram object which has an 'update' method
|
87
|
+
def register_histogram( name )
|
88
|
+
@metrics.histogram( name )
|
89
|
+
end
|
90
|
+
|
91
|
+
def remove( name )
|
92
|
+
@metrics.remove( name )
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'leafy/metrics/registry'
|
2
|
+
|
3
|
+
java_import java.util.concurrent.TimeUnit;
|
4
|
+
|
5
|
+
module Leafy
|
6
|
+
module Metrics
|
7
|
+
class Reporter
|
8
|
+
# copy the TimeUnit constants
|
9
|
+
TimeUnit.constants.each do |c|
|
10
|
+
const_set( c, TimeUnit.const_get( c ) )
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize( reporter )
|
14
|
+
@reporter = reporter
|
15
|
+
end
|
16
|
+
|
17
|
+
def start( period, time_unit )
|
18
|
+
@reporter.start( period, time_unit )
|
19
|
+
end
|
20
|
+
|
21
|
+
def stop
|
22
|
+
@reporter.stop
|
23
|
+
end
|
24
|
+
|
25
|
+
def report
|
26
|
+
@reporter.report
|
27
|
+
end
|
28
|
+
|
29
|
+
class Builder
|
30
|
+
def initialize( reporter_class, metrics )
|
31
|
+
@builder = reporter_class.for_registry( metrics.metrics )
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def convert_rates_to( time_unit )
|
36
|
+
@builder.convert_rates_to( time_unit )
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def convert_durations_to( time_unit )
|
41
|
+
@builder.convert_durations_to( time_unit )
|
42
|
+
self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
require 'leafy/metrics/console_reporter'
|
3
|
+
|
4
|
+
describe Leafy::Metrics::ConsoleReporter do
|
5
|
+
|
6
|
+
subject { Leafy::Metrics::ConsoleReporter }
|
7
|
+
|
8
|
+
let( :metrics ) { Leafy::Metrics::Registry.new }
|
9
|
+
let( :requests ) { metrics.register_meter( "requests" ) }
|
10
|
+
|
11
|
+
it 'run reporter with defaults' do
|
12
|
+
old_out = java.lang.System.out
|
13
|
+
bytes = StringIO.new
|
14
|
+
java.lang.System.out = java.io.PrintStream.new( bytes.to_outputstream )
|
15
|
+
begin
|
16
|
+
reporter = subject.for_registry( metrics ).build
|
17
|
+
requests.mark
|
18
|
+
reporter.start( 10, Leafy::Metrics::Reporter::MILLISECONDS )
|
19
|
+
sleep 0.01
|
20
|
+
reporter.stop
|
21
|
+
result = bytes.string.gsub( /\n/m, '')
|
22
|
+
expect( result ).to match /count = 1/
|
23
|
+
expect( result ).to match /second/
|
24
|
+
ensure
|
25
|
+
java.lang.System.out = old_out
|
26
|
+
reporter.stop if reporter
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'run reporter' do
|
31
|
+
bytes = StringIO.new
|
32
|
+
begin
|
33
|
+
reporter = subject.for_registry( metrics )
|
34
|
+
.convert_rates_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
35
|
+
.convert_durations_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
36
|
+
.output_to( bytes )
|
37
|
+
.build
|
38
|
+
|
39
|
+
requests.mark
|
40
|
+
reporter.start( 10, Leafy::Metrics::Reporter::MILLISECONDS )
|
41
|
+
sleep 0.01
|
42
|
+
reporter.stop
|
43
|
+
result = bytes.string.gsub( /\n/m, '')
|
44
|
+
expect( result ).to match /count = 1/
|
45
|
+
expect( result ).to match /millisecond/
|
46
|
+
ensure
|
47
|
+
reporter.stop if reporter
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
require 'leafy/metrics/csv_reporter'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
describe Leafy::Metrics::CSVReporter do
|
6
|
+
|
7
|
+
subject { Leafy::Metrics::CSVReporter }
|
8
|
+
|
9
|
+
let( :metrics ) { Leafy::Metrics::Registry.new }
|
10
|
+
let( :requests ) { metrics.register_meter( "requests" ) }
|
11
|
+
let( :csvfile ) { File.expand_path( File.dirname( __FILE__ ) ) + "/tmp/requests.csv" }
|
12
|
+
let( :tmpdir ) do
|
13
|
+
dir = File.expand_path( File.dirname( csvfile ) )
|
14
|
+
FileUtils.mkdir_p( dir )
|
15
|
+
FileUtils.rm_f( csvfile )
|
16
|
+
dir
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'run reporter with defaults' do
|
20
|
+
begin
|
21
|
+
reporter = subject.for_registry( metrics ).build( tmpdir )
|
22
|
+
requests.mark
|
23
|
+
reporter.start( 10, Leafy::Metrics::Reporter::MILLISECONDS )
|
24
|
+
sleep 0.01
|
25
|
+
reporter.stop
|
26
|
+
result = File.read( csvfile )
|
27
|
+
expect( result ).to match /t,count,mean_rate,m1_rate,m5_rate,m15_rate,rate_unit/
|
28
|
+
expect( result ).to match /second/
|
29
|
+
ensure
|
30
|
+
FileUtils.rm_rf( tmpdir )
|
31
|
+
reporter.stop if reporter
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'run reporter' do
|
36
|
+
begin
|
37
|
+
reporter = subject.for_registry( metrics )
|
38
|
+
.convert_rates_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
39
|
+
.convert_durations_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
40
|
+
.build( tmpdir )
|
41
|
+
|
42
|
+
requests.mark
|
43
|
+
reporter.start( 10, Leafy::Metrics::Reporter::MILLISECONDS )
|
44
|
+
sleep 0.01
|
45
|
+
reporter.stop
|
46
|
+
result = File.read( csvfile )
|
47
|
+
expect( result ).to match /t,count,mean_rate,m1_rate,m5_rate,m15_rate,rate_unit/
|
48
|
+
expect( result ).to match /second/
|
49
|
+
ensure
|
50
|
+
FileUtils.rm_rf( tmpdir )
|
51
|
+
reporter.stop if reporter
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
require 'leafy/metrics/graphite/graphite_reporter'
|
3
|
+
|
4
|
+
describe Leafy::Metrics::GraphiteReporter do
|
5
|
+
|
6
|
+
subject { Leafy::Metrics::GraphiteReporter }
|
7
|
+
|
8
|
+
let( :metrics ) { Leafy::Metrics::Registry.new }
|
9
|
+
let( :requests ) { metrics.register_meter( "requests" ) }
|
10
|
+
let( :logfile ) { LOG_FILE }
|
11
|
+
|
12
|
+
graphites = [ Leafy::Metrics::Graphite.new_tcp( 'localhost', 12345 ),
|
13
|
+
Leafy::Metrics::Graphite.new_pickled( 'localhost', 12345, 1 ) ]
|
14
|
+
graphites.each_with_index do |graphite, index|
|
15
|
+
describe graphite.sender.class do
|
16
|
+
it 'run reporter with defaults' do
|
17
|
+
log = File.read( logfile )
|
18
|
+
begin
|
19
|
+
reporter = subject.for_registry( metrics ).build( graphite )
|
20
|
+
requests.mark
|
21
|
+
reporter.start( 10, Leafy::Metrics::Reporter::MILLISECONDS )
|
22
|
+
sleep 0.01
|
23
|
+
reporter.stop
|
24
|
+
result = File.read( logfile )[ (log.size)..-1 ]
|
25
|
+
expect( result ).to match /metrics-graphite-reporter-.-thread-1] WARN com.codahale.metrics.graphite.GraphiteReporter/
|
26
|
+
ensure
|
27
|
+
reporter.stop if reporter
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'run reporter' do
|
32
|
+
log = File.read( logfile )
|
33
|
+
begin
|
34
|
+
reporter = subject.for_registry( metrics )
|
35
|
+
.convert_rates_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
36
|
+
.convert_durations_to( Leafy::Metrics::Reporter::MILLISECONDS )
|
37
|
+
.build( graphite )
|
38
|
+
|
39
|
+
requests.mark
|
40
|
+
reporter.start( 10, Leafy::Metrics::Reporter::MILLISECONDS )
|
41
|
+
sleep 0.01
|
42
|
+
reporter.stop
|
43
|
+
result = File.read( logfile )[ (log.size)..-1 ]
|
44
|
+
expect( result ).to match /metrics-graphite-reporter-.-thread-1] WARN com.codahale.metrics.graphite.GraphiteReporter/
|
45
|
+
ensure
|
46
|
+
reporter.stop if reporter
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
require 'leafy/metrics/graphite/graphite'
|
3
|
+
|
4
|
+
describe Leafy::Metrics::Graphite do
|
5
|
+
|
6
|
+
subject { Leafy::Metrics::Graphite }
|
7
|
+
|
8
|
+
it 'fails to create an instance without proper sender' do
|
9
|
+
expect { subject.new Object.new }.to raise_error RuntimeError
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'creates tcp graphite' do
|
13
|
+
expect( subject.new_tcp( 'localhost', 123 ) ).not_to be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'creates udp graphite' do
|
17
|
+
expect( subject.new_udp( 'localhost', 123 ) ).not_to be_nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'creates pickled graphite' do
|
21
|
+
expect( subject.new_pickled( 'localhost', 123, 456 ) ).not_to be_nil
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
require 'leafy/metrics/registry'
|
3
|
+
|
4
|
+
describe Leafy::Metrics::Registry do
|
5
|
+
|
6
|
+
subject { Leafy::Metrics::Registry.new }
|
7
|
+
|
8
|
+
it 'registers and unregister a meter' do
|
9
|
+
obj = subject.register_meter('me')
|
10
|
+
expect(obj).to be_a(Java::ComCodahaleMetrics::Meter)
|
11
|
+
expect(subject.metrics.meters['me']).to be obj
|
12
|
+
expect(obj.respond_to? :mark).to be true
|
13
|
+
|
14
|
+
subject.remove('me')
|
15
|
+
expect(subject.metrics.meters).to be_empty
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'registers and unregister a counter' do
|
19
|
+
obj = subject.register_counter('me')
|
20
|
+
expect(obj).to be_a(Java::ComCodahaleMetrics::Counter)
|
21
|
+
expect(subject.metrics.counters['me']).to be obj
|
22
|
+
expect(obj.respond_to? :inc).to be true
|
23
|
+
expect(obj.respond_to? :dec).to be true
|
24
|
+
|
25
|
+
subject.remove('me')
|
26
|
+
expect(subject.metrics.counters).to be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'registers and unregister a histogram' do
|
30
|
+
obj = subject.register_histogram('me')
|
31
|
+
expect(obj).to be_a(Java::ComCodahaleMetrics::Histogram)
|
32
|
+
expect(subject.metrics.histograms['me']).to be obj
|
33
|
+
expect(obj.respond_to? :update).to be true
|
34
|
+
|
35
|
+
subject.remove('me')
|
36
|
+
expect(subject.metrics.histograms).to be_empty
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'registers and unregister a timer' do
|
40
|
+
obj = subject.register_timer('me')
|
41
|
+
expect(obj).to be_a(Leafy::Metrics::Registry::Timer)
|
42
|
+
expect(subject.metrics.timers['me']).to be obj.timer
|
43
|
+
expect(obj.timer.respond_to? :time).to be true
|
44
|
+
|
45
|
+
subject.remove('me')
|
46
|
+
expect(subject.metrics.timers).to be_empty
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'registers and unregister gauge as block' do
|
50
|
+
obj = subject.register_gauge('me') do
|
51
|
+
123
|
52
|
+
end
|
53
|
+
expect(obj).to be_a(Leafy::Metrics::Registry::Gauge)
|
54
|
+
expect(subject.metrics.gauges['me']).to be obj
|
55
|
+
expect(obj.value).to eq 123
|
56
|
+
|
57
|
+
subject.remove('me')
|
58
|
+
expect(subject.metrics.gauges).to be_empty
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'registers and unregister gauge as object with call method' do
|
62
|
+
obj = subject.register_gauge('me', Proc.new do
|
63
|
+
123
|
64
|
+
end )
|
65
|
+
expect(obj).to be_a(Leafy::Metrics::Registry::Gauge)
|
66
|
+
expect(subject.metrics.gauges['me']).to be obj
|
67
|
+
expect(obj.value).to eq 123
|
68
|
+
|
69
|
+
subject.remove('me')
|
70
|
+
expect(subject.metrics.gauges).to be_empty
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'fails register gauge as object without call method' do
|
74
|
+
expect { subject.register_gauge('me', Object.new ) }.to raise_error
|
75
|
+
end
|
76
|
+
|
77
|
+
describe Leafy::Metrics::Registry::Timer do
|
78
|
+
|
79
|
+
it 'can messure duration' do
|
80
|
+
obj = subject.register_timer('me')
|
81
|
+
expect(obj.timer.mean_rate).to eq 0.0
|
82
|
+
|
83
|
+
obj.time do
|
84
|
+
sleep 0.1
|
85
|
+
end
|
86
|
+
|
87
|
+
expect(obj.timer.mean_rate).to be > 0.0
|
88
|
+
|
89
|
+
subject.remove('me')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/spec/setup.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path( '../../lib', __FILE__ )
|
2
|
+
require 'jar-dependencies'
|
3
|
+
|
4
|
+
# setup logging
|
5
|
+
LOG_FILE = File.expand_path( '../../pkg/log', __FILE__ )
|
6
|
+
require 'fileutils'
|
7
|
+
FileUtils.mkdir_p File.dirname( LOG_FILE )
|
8
|
+
FileUtils.rm_f( LOG_FILE )
|
9
|
+
java.lang.System.set_property( 'org.slf4j.simpleLogger.logFile', LOG_FILE )
|
10
|
+
require_jar( 'org.slf4j', 'slf4j-simple', '1.7.7' )
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: leafy-metrics
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- christian meier
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: jar-dependencies
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.8
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.8
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.1.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: yard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.8.7
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.8.7
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.2'
|
69
|
+
description: 'provides an API to register metrics like meters, timers, gauge, counter
|
70
|
+
using dropwizard-metrics. it also allows to setup reporters: console-reporter, csv-reporter
|
71
|
+
and graphite-reporter'
|
72
|
+
email:
|
73
|
+
- christian.meier@lookout.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- ".gitignore"
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- leafy-metrics.gemspec
|
84
|
+
- lib/leafy-metrics.rb
|
85
|
+
- lib/leafy-metrics_jars.rb
|
86
|
+
- lib/leafy/metrics.rb
|
87
|
+
- lib/leafy/metrics/console_reporter.rb
|
88
|
+
- lib/leafy/metrics/csv_reporter.rb
|
89
|
+
- lib/leafy/metrics/graphite/graphite.rb
|
90
|
+
- lib/leafy/metrics/graphite/graphite_reporter.rb
|
91
|
+
- lib/leafy/metrics/registry.rb
|
92
|
+
- lib/leafy/metrics/reporter.rb
|
93
|
+
- lib/leafy/metrics/version.rb
|
94
|
+
- spec/console_reporter_spec.rb
|
95
|
+
- spec/csv_reporter_spec.rb
|
96
|
+
- spec/graphite_reporter_spec.rb
|
97
|
+
- spec/graphite_spec.rb
|
98
|
+
- spec/registry_spec.rb
|
99
|
+
- spec/setup.rb
|
100
|
+
homepage: https://github.com/lookout/leafy
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements:
|
119
|
+
- jar io.dropwizard.metrics:metrics-core, 3.1.0
|
120
|
+
- jar io.dropwizard.metrics:metrics-graphite, 3.1.0
|
121
|
+
- jar org.slf4j, slf4j-simple, 1.7.7, :scope => :test
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 2.4.5
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: provide an API to register metrics
|
127
|
+
test_files: []
|