formatted-metrics 0.1.2 → 0.2.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.
- data/README.md +12 -0
- data/formatted-metrics.gemspec +0 -2
- data/lib/metrics/configuration.rb +2 -2
- data/lib/metrics/formatters/base.rb +31 -0
- data/lib/metrics/formatters/l2met.rb +28 -0
- data/lib/metrics/grouping.rb +22 -0
- data/lib/metrics/handler.rb +20 -17
- data/lib/metrics/instrumentable.rb +4 -3
- data/lib/metrics/instrumenter.rb +64 -0
- data/lib/metrics/version.rb +1 -1
- data/lib/metrics.rb +24 -34
- data/spec/metrics/formatters/l2met_spec.rb +41 -0
- data/spec/metrics/grouping_spec.rb +22 -0
- data/spec/metrics/instrumenter_spec.rb +45 -0
- data/spec/metrics_spec.rb +12 -33
- metadata +14 -25
- data/lib/metrics/formatter.rb +0 -53
- data/spec/metrics/formatter_spec.rb +0 -36
- data/spec/metrics/handler_spec.rb +0 -38
data/README.md
CHANGED
@@ -39,6 +39,18 @@ Metrics.instrument 'sidekiq.queue', source: 'background' do
|
|
39
39
|
yield
|
40
40
|
end
|
41
41
|
# => 'source=app.background measure.sidekiq.queue=500ms'
|
42
|
+
|
43
|
+
Metrics.group 'sidekiq' do
|
44
|
+
instrument 'queues.process', 100, units: 'jobs'
|
45
|
+
instrument 'workers.busy', 10, units: 'workers'
|
46
|
+
|
47
|
+
instrument 'queue.time', source: 'worker.1' do
|
48
|
+
sleep 1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# => 'source=app measure.sidekiq.queues.processed=100jobs measure.sidekiq.workers.busy=10workers'
|
53
|
+
# => 'source=app.worker.1 measure.sidekiq.queue.time=1000.00ms'
|
42
54
|
```
|
43
55
|
|
44
56
|
## TODO
|
data/formatted-metrics.gemspec
CHANGED
@@ -18,8 +18,6 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency 'activesupport', '>= 3.1'
|
22
|
-
|
23
21
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
24
22
|
spec.add_development_dependency 'rake'
|
25
23
|
spec.add_development_dependency 'rspec', '~> 2.14'
|
@@ -21,11 +21,11 @@ module Metrics
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def source
|
24
|
-
@source ||= ENV['METRICS_SOURCE'] || ENV['APP_NAME'] || `hostname`.chomp
|
24
|
+
@source ||= ENV['METRICS_SOURCE'] || ENV['APP_NAME'] || `hostname`.chomp
|
25
25
|
end
|
26
26
|
|
27
27
|
def formatter
|
28
|
-
@formatter ||= Metrics::
|
28
|
+
@formatter ||= Metrics::Formatters::L2Met
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Metrics::Formatters
|
2
|
+
class Base
|
3
|
+
attr_reader :instrumenters
|
4
|
+
|
5
|
+
def self.write(*instrumenters)
|
6
|
+
new(*instrumenters).write
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(*instrumenters)
|
10
|
+
@instrumenters = instrumenters.flatten
|
11
|
+
end
|
12
|
+
|
13
|
+
def write
|
14
|
+
lines.each do |line|
|
15
|
+
configuration.logger.info line
|
16
|
+
end
|
17
|
+
instrumenters
|
18
|
+
end
|
19
|
+
|
20
|
+
def lines
|
21
|
+
raise NotImplementedError
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def configuration
|
27
|
+
Metrics.configuration
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Metrics::Formatters
|
2
|
+
class L2Met < Base
|
3
|
+
def lines
|
4
|
+
groups.map do |source, instrumenters|
|
5
|
+
[
|
6
|
+
"source=#{full_source(source)}",
|
7
|
+
instrumenters.map { |instrumenter| "measure.#{instrumenter.metric}=#{instrumenter.value}#{instrumenter.units}" }.join(' ')
|
8
|
+
].flatten.join(' ')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
# Internal: We group the metrics by their source so that we can separate
|
15
|
+
# the lines.
|
16
|
+
def groups
|
17
|
+
instrumenters.group_by(&:source)
|
18
|
+
end
|
19
|
+
|
20
|
+
def full_source(source=nil)
|
21
|
+
if source
|
22
|
+
[configuration.source, source].join('.')
|
23
|
+
else
|
24
|
+
configuration.source
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Metrics
|
2
|
+
# Public: Starts a new Grouping context, which allows for multiple
|
3
|
+
# instruments to output on a single line.
|
4
|
+
class Grouping
|
5
|
+
attr_reader :namespace, :instrumenters
|
6
|
+
|
7
|
+
def self.instrument(*args, &block)
|
8
|
+
new(*args, &block).instrumenters
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(namespace = nil, &block)
|
12
|
+
@instrumenters = []
|
13
|
+
@namespace = namespace
|
14
|
+
instance_eval &block
|
15
|
+
end
|
16
|
+
|
17
|
+
def instrument(metric, *args, &block)
|
18
|
+
metric = "#{namespace}.#{metric}" if namespace
|
19
|
+
instrumenters << Instrumenter.instrument(metric, *args, &block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/metrics/handler.rb
CHANGED
@@ -1,35 +1,38 @@
|
|
1
|
-
require 'active_support/core_ext/module/delegation'
|
2
|
-
|
3
1
|
module Metrics
|
4
2
|
|
5
|
-
# Internal: Responsible for
|
3
|
+
# Internal: Responsible for taking a list or an Array of
|
4
|
+
# Metrics::Instrumenters and passing them to the formatter.
|
6
5
|
class Handler
|
7
|
-
attr_reader :
|
6
|
+
attr_reader :instrumenters
|
7
|
+
|
8
|
+
def self.handle(*instrumenters)
|
9
|
+
new(*instrumenters).handle
|
10
|
+
end
|
8
11
|
|
9
|
-
def initialize(*
|
10
|
-
@
|
12
|
+
def initialize(*instrumenters)
|
13
|
+
@instrumenters = instrumenters.flatten
|
11
14
|
end
|
12
15
|
|
16
|
+
# Public: Writes all of the instrumenters to STDOUT using the formatter.
|
17
|
+
#
|
18
|
+
# Returns an Array of Metrics::Instrumenters that were written to STDOUT.
|
13
19
|
def handle
|
14
|
-
|
20
|
+
write instrumenters
|
15
21
|
end
|
16
22
|
|
17
23
|
private
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
def trackable?
|
22
|
-
event.payload[:measure]
|
25
|
+
def configuration
|
26
|
+
Metrics.configuration
|
23
27
|
end
|
24
28
|
|
25
|
-
def
|
26
|
-
|
29
|
+
def write(*args, &block)
|
30
|
+
formatter.write(*args, &block)
|
27
31
|
end
|
28
32
|
|
29
|
-
def
|
30
|
-
configuration.
|
33
|
+
def formatter
|
34
|
+
configuration.formatter
|
31
35
|
end
|
32
|
-
|
36
|
+
|
33
37
|
end
|
34
|
-
|
35
38
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Metrics
|
2
|
+
# Public: Responsible for sampling a measurement of something.
|
3
|
+
#
|
4
|
+
# metric - The name of the metric to measure (e.g. rack.request.time)
|
5
|
+
#
|
6
|
+
# Returns a new Metrics::Instrumenter.
|
7
|
+
class Instrumenter
|
8
|
+
TIME_UNITS = 'ms'.freeze
|
9
|
+
|
10
|
+
attr_reader :metric
|
11
|
+
|
12
|
+
def self.instrument(*args, &block)
|
13
|
+
instrument = new(*args, &block)
|
14
|
+
instrument.value
|
15
|
+
instrument
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(metric, *args, &block)
|
19
|
+
@metric = metric
|
20
|
+
@options = extract_options!(args)
|
21
|
+
@block = block
|
22
|
+
@value = args.first if args.length > 0
|
23
|
+
end
|
24
|
+
|
25
|
+
# Public: Runs the instrumenter.
|
26
|
+
#
|
27
|
+
# Returns the run time if a block was supplied.
|
28
|
+
# Returns the value if the
|
29
|
+
def value
|
30
|
+
timing? ? time : @value
|
31
|
+
end
|
32
|
+
|
33
|
+
def units
|
34
|
+
timing? ? TIME_UNITS : options[:units]
|
35
|
+
end
|
36
|
+
|
37
|
+
def source
|
38
|
+
options[:source]
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
attr_reader :options, :block
|
43
|
+
|
44
|
+
def timing?
|
45
|
+
!block.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
def time
|
49
|
+
@time ||= begin
|
50
|
+
start = Time.now
|
51
|
+
block.call
|
52
|
+
(Time.now - start) * 1000.0
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def extract_options!(options)
|
57
|
+
if options.last.is_a?(Hash)
|
58
|
+
options.pop
|
59
|
+
else
|
60
|
+
{}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/metrics/version.rb
CHANGED
data/lib/metrics.rb
CHANGED
@@ -1,24 +1,21 @@
|
|
1
|
-
require 'active_support/notifications'
|
2
|
-
require 'active_support/core_ext/array/extract_options'
|
3
|
-
require 'active_support/dependencies/autoload'
|
4
|
-
|
5
1
|
require 'metrics/railtie' if defined?(Rails)
|
6
2
|
|
7
3
|
module Metrics
|
8
|
-
|
4
|
+
autoload :Configuration, 'metrics/configuration'
|
5
|
+
autoload :Instrumentable, 'metrics/instrumentable'
|
6
|
+
autoload :Instrumenter, 'metrics/instrumenter'
|
7
|
+
autoload :Grouping, 'metrics/grouping'
|
8
|
+
autoload :Handler, 'metrics/handler'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
module Formatters
|
11
|
+
autoload :Base, 'metrics/formatters/base'
|
12
|
+
autoload :L2Met, 'metrics/formatters/l2met'
|
13
|
+
end
|
14
14
|
|
15
15
|
class << self
|
16
16
|
|
17
17
|
# Public: Instrument a metric.
|
18
18
|
#
|
19
|
-
# metric - The name of the metric (e.g. rack.request)
|
20
|
-
# source - A source to append to the default source.
|
21
|
-
#
|
22
19
|
# Example
|
23
20
|
#
|
24
21
|
# # Instrument the duration of an event.
|
@@ -35,35 +32,28 @@ module Metrics
|
|
35
32
|
# end
|
36
33
|
#
|
37
34
|
# Returns nothing.
|
38
|
-
def instrument(
|
39
|
-
|
40
|
-
|
41
|
-
measure = if args.empty?
|
42
|
-
block_given? ? true : 1
|
43
|
-
else
|
44
|
-
args.first
|
45
|
-
end
|
46
|
-
|
47
|
-
ActiveSupport::Notifications.instrument(
|
48
|
-
metric,
|
49
|
-
options.merge(measure: measure, source: options[:source]),
|
50
|
-
&block
|
51
|
-
)
|
35
|
+
def instrument(*args, &block)
|
36
|
+
Handler.handle(Instrumenter.instrument(*args, &block))
|
52
37
|
end
|
53
38
|
|
54
|
-
# Public:
|
55
|
-
# that have a payload with a :measure key that is truthy will be processed
|
56
|
-
# and logged to stdout.
|
39
|
+
# Public: Group multiple instruments.
|
57
40
|
#
|
58
41
|
# Example
|
59
42
|
#
|
60
|
-
# Metrics.
|
43
|
+
# Metrics.group 'sidekiq' do
|
44
|
+
# instrument 'request.time' do
|
45
|
+
# begin
|
46
|
+
# @app.call(env)
|
47
|
+
# rescue Exception => e
|
48
|
+
# instrument 'exceptions', 1
|
49
|
+
# raise
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
# end
|
61
53
|
#
|
62
54
|
# Returns nothing.
|
63
|
-
def
|
64
|
-
|
65
|
-
Metrics::Handler.new(*args).handle
|
66
|
-
end
|
55
|
+
def group(*args, &block)
|
56
|
+
Handler.handle(Grouping.instrument(*args, &block))
|
67
57
|
end
|
68
58
|
|
69
59
|
def configuration
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Metrics::Formatters::L2Met do
|
4
|
+
let(:formatter) { described_class.new *instrumenters }
|
5
|
+
|
6
|
+
before do
|
7
|
+
Metrics.configuration.stub source: 'app'
|
8
|
+
end
|
9
|
+
|
10
|
+
def instrumenter(values)
|
11
|
+
double Metrics::Instrumenter, { source: nil }.merge(values)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.lines' do
|
15
|
+
subject(:format) { formatter.lines }
|
16
|
+
|
17
|
+
context 'with a single instrumenter' do
|
18
|
+
let(:instrumenters) { [ instrumenter(metric: 'rack.request.time', value: 10, units: 'ms') ] }
|
19
|
+
it { should eq ['source=app measure.rack.request.time=10ms'] }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with multiple instrumenters' do
|
23
|
+
let(:instrumenters) do
|
24
|
+
[ instrumenter(metric: 'rack.request.time', value: 10, units: 'ms'),
|
25
|
+
instrumenter(metric: 'jobs.busy', value: 10, units: 'jobs') ]
|
26
|
+
end
|
27
|
+
|
28
|
+
it { should eq ['source=app measure.rack.request.time=10ms measure.jobs.busy=10jobs'] }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with multiple metrics from different sources' do
|
32
|
+
let(:instrumenters) do
|
33
|
+
[ instrumenter(metric: 'rack.request.time', value: 10, units: 'ms'),
|
34
|
+
instrumenter(metric: 'jobs.queued', value: 15, units: 'jobs', source: 'foo'),
|
35
|
+
instrumenter(metric: 'jobs.busy', value: 10, units: 'jobs', source: 'foo') ]
|
36
|
+
end
|
37
|
+
|
38
|
+
it { should eq ['source=app measure.rack.request.time=10ms', 'source=app.foo measure.jobs.queued=15jobs measure.jobs.busy=10jobs'] }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Metrics::Grouping do
|
4
|
+
describe '.instrumenters' do
|
5
|
+
it 'builds instruments' do
|
6
|
+
group = described_class.new do
|
7
|
+
instrument 'jobs.busy', 10
|
8
|
+
instrument 'rack.request.time', 500, units: 'ms'
|
9
|
+
end
|
10
|
+
|
11
|
+
expect(group.instrumenters).to have(2).instrumenters
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'allows a namespace to be provided' do
|
15
|
+
group = described_class.new 'rack' do
|
16
|
+
instrument 'request.time', 500, units: 'ms'
|
17
|
+
end
|
18
|
+
|
19
|
+
expect(group.instrumenters.first.metric).to eq 'rack.request.time'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Metrics::Instrumenter do
|
4
|
+
let(:instrumenter) { described_class.new('rack.request') { } }
|
5
|
+
|
6
|
+
describe '.value' do
|
7
|
+
subject { instrumenter.value }
|
8
|
+
|
9
|
+
context 'with a value' do
|
10
|
+
let(:instrumenter) { described_class.new('rack.request', 500) }
|
11
|
+
it { should eq 500 }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with a block' do
|
15
|
+
before { Time.should_receive(:now).and_return(Time.at(1), Time.at(3)) }
|
16
|
+
it { should eq 2000.0 }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.units' do
|
21
|
+
subject { instrumenter.units }
|
22
|
+
|
23
|
+
context 'with a block' do
|
24
|
+
it { should eq 'ms' }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when specified' do
|
28
|
+
let(:instrumenter) { described_class.new('jobs.busy', 10, units: 'jobs') }
|
29
|
+
it { should eq 'jobs' }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '.source' do
|
34
|
+
subject { instrumenter.source }
|
35
|
+
|
36
|
+
context 'by default' do
|
37
|
+
it { should be_nil }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when specified' do
|
41
|
+
let(:instrumenter) { described_class.new('jobs.busy', 10, units: 'jobs', source: 'sidekiq') }
|
42
|
+
it { should eq 'sidekiq' }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/metrics_spec.rb
CHANGED
@@ -1,42 +1,21 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Metrics do
|
4
|
-
let(:instrumenter) { ActiveSupport::Notifications }
|
5
|
-
|
6
4
|
describe '#instrument' do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'instruments the duration with a source' do
|
16
|
-
instrumenter.should_receive(:instrument).with('rack.request', measure: true, source: 'foo')
|
17
|
-
Metrics.instrument 'rack.request', source: 'foo' do
|
18
|
-
'do something long'
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'with a measurement' do
|
24
|
-
it 'instruments the measurement' do
|
25
|
-
instrumenter.should_receive(:instrument).with('rack.request', measure: 10, source: nil)
|
26
|
-
Metrics.instrument 'rack.request', 10
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'instruments the measurement with a source' do
|
30
|
-
instrumenter.should_receive(:instrument).with('rack.request', measure: 10, source: 'foo')
|
31
|
-
Metrics.instrument 'rack.request', 10, source: 'foo'
|
32
|
-
end
|
5
|
+
it 'delegates to Metrics::Instrumenter' do
|
6
|
+
instrumenter = double Metrics::Instrumenter
|
7
|
+
Metrics::Instrumenter.should_receive(:instrument).with('rack.request', 10).and_return(instrumenter)
|
8
|
+
Metrics::Handler.should_receive(:handle).with(instrumenter)
|
9
|
+
Metrics.instrument 'rack.request', 10
|
33
10
|
end
|
11
|
+
end
|
34
12
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
13
|
+
describe '#group' do
|
14
|
+
it 'delegates to Metrics::Grouping' do
|
15
|
+
grouping = double Metrics::Grouping
|
16
|
+
Metrics::Grouping.should_receive(:instrument).and_return(grouping)
|
17
|
+
Metrics::Handler.should_receive(:handle).with(grouping)
|
18
|
+
Metrics.group { instrument 'rack.request', 10 }
|
40
19
|
end
|
41
20
|
end
|
42
21
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formatted-metrics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: activesupport
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '3.1'
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '3.1'
|
30
14
|
- !ruby/object:Gem::Dependency
|
31
15
|
name: bundler
|
32
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,14 +77,18 @@ files:
|
|
93
77
|
- lib/formatted-metrics.rb
|
94
78
|
- lib/metrics.rb
|
95
79
|
- lib/metrics/configuration.rb
|
96
|
-
- lib/metrics/
|
80
|
+
- lib/metrics/formatters/base.rb
|
81
|
+
- lib/metrics/formatters/l2met.rb
|
82
|
+
- lib/metrics/grouping.rb
|
97
83
|
- lib/metrics/handler.rb
|
98
84
|
- lib/metrics/instrumentable.rb
|
85
|
+
- lib/metrics/instrumenter.rb
|
99
86
|
- lib/metrics/railtie.rb
|
100
87
|
- lib/metrics/version.rb
|
101
|
-
- spec/metrics/
|
102
|
-
- spec/metrics/
|
88
|
+
- spec/metrics/formatters/l2met_spec.rb
|
89
|
+
- spec/metrics/grouping_spec.rb
|
103
90
|
- spec/metrics/instrumentable_spec.rb
|
91
|
+
- spec/metrics/instrumenter_spec.rb
|
104
92
|
- spec/metrics_spec.rb
|
105
93
|
- spec/spec_helper.rb
|
106
94
|
homepage: http://github.com/remind101/formatted-metrics
|
@@ -118,7 +106,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
106
|
version: '0'
|
119
107
|
segments:
|
120
108
|
- 0
|
121
|
-
hash:
|
109
|
+
hash: -1552981004150797655
|
122
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
111
|
none: false
|
124
112
|
requirements:
|
@@ -127,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
115
|
version: '0'
|
128
116
|
segments:
|
129
117
|
- 0
|
130
|
-
hash:
|
118
|
+
hash: -1552981004150797655
|
131
119
|
requirements: []
|
132
120
|
rubyforge_project:
|
133
121
|
rubygems_version: 1.8.23
|
@@ -135,8 +123,9 @@ signing_key:
|
|
135
123
|
specification_version: 3
|
136
124
|
summary: Easily output formatted metrics to stdout
|
137
125
|
test_files:
|
138
|
-
- spec/metrics/
|
139
|
-
- spec/metrics/
|
126
|
+
- spec/metrics/formatters/l2met_spec.rb
|
127
|
+
- spec/metrics/grouping_spec.rb
|
140
128
|
- spec/metrics/instrumentable_spec.rb
|
129
|
+
- spec/metrics/instrumenter_spec.rb
|
141
130
|
- spec/metrics_spec.rb
|
142
131
|
- spec/spec_helper.rb
|
data/lib/metrics/formatter.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/module/delegation'
|
2
|
-
require 'active_support/core_ext/string/inflections'
|
3
|
-
|
4
|
-
module Metrics
|
5
|
-
|
6
|
-
# Internal: Responsible for taking an event and formatting it to be consumed
|
7
|
-
# by l2met.
|
8
|
-
#
|
9
|
-
# Example
|
10
|
-
#
|
11
|
-
# Formatter.new(event).to_s
|
12
|
-
# # => "source=my-app measure.rack.request=50ms"
|
13
|
-
#
|
14
|
-
# Returns a Metrics::Formatter.to_s
|
15
|
-
class Formatter
|
16
|
-
DEFAULT_UNITS = 'ms'.freeze
|
17
|
-
|
18
|
-
# An object that conforms to the same public interface as
|
19
|
-
# ActiveSupport::Notifications::Event
|
20
|
-
attr_reader :event
|
21
|
-
|
22
|
-
def initialize(event)
|
23
|
-
@event = event
|
24
|
-
end
|
25
|
-
|
26
|
-
def to_s
|
27
|
-
"source=#{source} measure.#{event_name}=#{value}"
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
delegate :name, :payload, :duration, to: :event, prefix: true
|
33
|
-
delegate :configuration, to: :'Metrics'
|
34
|
-
|
35
|
-
def value
|
36
|
-
case measurement = event_payload[:measure]
|
37
|
-
when true
|
38
|
-
[event_duration, DEFAULT_UNITS].join('')
|
39
|
-
else
|
40
|
-
if units = event_payload[:units]
|
41
|
-
[measurement, units].join('')
|
42
|
-
else
|
43
|
-
measurement
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def source
|
49
|
-
[configuration.source, Array(event_payload[:source])].flatten.join('.')
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Metrics::Formatter do
|
4
|
-
let(:event ) { double ActiveSupport::Notifications::Event, name: 'rack.request', payload: { measure: true } }
|
5
|
-
let(:formatter) { described_class.new event }
|
6
|
-
|
7
|
-
before do
|
8
|
-
formatter.stub_chain :configuration, source: 'app'
|
9
|
-
end
|
10
|
-
|
11
|
-
describe '.to_s' do
|
12
|
-
subject { formatter.to_s }
|
13
|
-
|
14
|
-
context 'with a duration' do
|
15
|
-
before { event.stub duration: 10 }
|
16
|
-
it { should eq 'source=app measure.rack.request=10ms' }
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'with a measurement' do
|
20
|
-
context 'with units' do
|
21
|
-
before { event.stub payload: { measure: 1, units: 's' } }
|
22
|
-
it { should eq 'source=app measure.rack.request=1s' }
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'without units' do
|
26
|
-
before { event.stub payload: { measure: 50 } }
|
27
|
-
it { should eq 'source=app measure.rack.request=50' }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'with a source' do
|
32
|
-
before { event.stub name: 'workers.busy', payload: { measure: 10, source: 'sidekiq' } }
|
33
|
-
it { should eq 'source=app.sidekiq measure.workers.busy=10' }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Metrics::Handler do
|
4
|
-
let(:args ) { ['event args'] * 5 }
|
5
|
-
let(:handler ) { described_class.new *args }
|
6
|
-
|
7
|
-
let(:event ) { double ActiveSupport::Notifications::Event }
|
8
|
-
let(:formatter) { double Metrics.configuration.formatter }
|
9
|
-
|
10
|
-
describe '.handle' do
|
11
|
-
before do
|
12
|
-
ActiveSupport::Notifications::Event.stub new: event
|
13
|
-
Metrics.configuration.formatter.stub new: formatter
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'when the event is trackable' do
|
17
|
-
before do
|
18
|
-
event.stub payload: { measure: true }
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'should handle the event' do
|
22
|
-
Metrics.configuration.logger.should_receive(:info).with(formatter.to_s)
|
23
|
-
handler.handle
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'when the event is not trackable' do
|
28
|
-
before do
|
29
|
-
event.stub payload: { }
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'should not handle the event' do
|
33
|
-
Metrics.configuration.logger.should_receive(:info).never
|
34
|
-
handler.handle
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|