formatted-metrics 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/metrics.rb +7 -5
- data/lib/metrics/configuration.rb +12 -7
- data/lib/metrics/{formatters → drivers}/l2met.rb +19 -6
- data/lib/metrics/drivers/statsd.rb +46 -0
- data/lib/metrics/grouping.rb +3 -3
- data/lib/metrics/handler.rb +10 -17
- data/lib/metrics/middleware_helpers.rb +2 -2
- data/lib/metrics/version.rb +1 -1
- data/spec/faraday/instrumentation_spec.rb +1 -0
- data/spec/metrics/{formatters → drivers}/l2met_spec.rb +3 -7
- data/spec/metrics/drivers/statsd_spec.rb +45 -0
- data/spec/spec_helper.rb +2 -0
- metadata +23 -20
- data/lib/metrics/formatters/base.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f61de2711adaea249e6fc4f6eb53d9899ed805ef
|
4
|
+
data.tar.gz: 5292dea3deae43f089de2eeb20d0512acbd3aebb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c34b9936b1ae2ea1c6504e85432c9c0a7a63384cb063799e1be98f94702c652dec05d993c432152f47f9132d19fc6cc0cb86e945041dc1d4ecc2650d395a931
|
7
|
+
data.tar.gz: 330e3349dbc4848df534f4a9d85bff0ca0a187897cda130500d9bf89f9dcf631cd595634a39c484ed0e46ac3dbe6869112af4ca7617fe78cf9909d2b830d7634
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/remind101/formatted-metrics.png)](https://travis-ci.org/remind101/formatted-metrics) [![Code Climate](https://codeclimate.com/github/remind101/formatted-metrics.png)](https://codeclimate.com/github/remind101/formatted-metrics)
|
4
4
|
|
5
|
-
Easily produce metrics that can be consumed by [l2met](https://github.com/ryandotsmith/l2met).
|
5
|
+
Easily produce metrics that can be consumed by [l2met](https://github.com/ryandotsmith/l2met) or statsd.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
data/lib/metrics.rb
CHANGED
@@ -10,9 +10,10 @@ module Metrics
|
|
10
10
|
autoload :Grouping, 'metrics/grouping'
|
11
11
|
autoload :Handler, 'metrics/handler'
|
12
12
|
|
13
|
-
module
|
14
|
-
autoload :Base, 'metrics/
|
15
|
-
autoload :L2Met, 'metrics/
|
13
|
+
module Drivers
|
14
|
+
autoload :Base, 'metrics/drivers/base'
|
15
|
+
autoload :L2Met, 'metrics/drivers/l2met'
|
16
|
+
autoload :Statsd, 'metrics/drivers/statsd'
|
16
17
|
end
|
17
18
|
|
18
19
|
module Helpers
|
@@ -65,8 +66,9 @@ module Metrics
|
|
65
66
|
# end
|
66
67
|
#
|
67
68
|
# Returns nothing.
|
68
|
-
def group(
|
69
|
-
|
69
|
+
def group(namespace = nil, options = {}, &block)
|
70
|
+
instrumenters = Grouping.instrument(namespace, &block)
|
71
|
+
Handler.handle(*instrumenters)
|
70
72
|
end
|
71
73
|
|
72
74
|
def subscribe
|
@@ -2,15 +2,24 @@ require 'logger'
|
|
2
2
|
|
3
3
|
module Metrics
|
4
4
|
class Configuration
|
5
|
+
# The driver to use.
|
6
|
+
#
|
7
|
+
# Drivers are objects that implement the following method:
|
8
|
+
#
|
9
|
+
# driver.write(*instrumenters) # => instrumenters written
|
10
|
+
#
|
11
|
+
# Defaults to Metrics::Drivers::L2Met.new(logger, source).
|
12
|
+
attr_accessor :driver
|
13
|
+
|
5
14
|
# The stream source to write to. Defaults to STDOUT.
|
6
15
|
attr_accessor :logger
|
7
16
|
|
8
17
|
# The base source for all metrics.
|
9
18
|
attr_accessor :source
|
10
19
|
|
11
|
-
|
12
|
-
|
13
|
-
|
20
|
+
def driver
|
21
|
+
@driver ||= Metrics::Drivers::L2Met.new(logger, source)
|
22
|
+
end
|
14
23
|
|
15
24
|
def logger
|
16
25
|
@logger ||= Logger.new(STDOUT).tap { |log| log.formatter = log_formatter }
|
@@ -24,9 +33,5 @@ module Metrics
|
|
24
33
|
return @source if defined? @source
|
25
34
|
@source = ENV['METRICS_SOURCE'] || ENV['APP_NAME'] || `hostname`.chomp
|
26
35
|
end
|
27
|
-
|
28
|
-
def formatter
|
29
|
-
@formatter ||= Metrics::Formatters::L2Met
|
30
|
-
end
|
31
36
|
end
|
32
37
|
end
|
@@ -1,11 +1,24 @@
|
|
1
|
-
module Metrics::
|
1
|
+
module Metrics::Drivers
|
2
2
|
PRECISION = 3.freeze
|
3
3
|
|
4
|
-
class L2Met
|
4
|
+
class L2Met
|
5
|
+
attr_reader :logger, :source_prefix
|
6
|
+
def initialize(logger, source_prefix)
|
7
|
+
@logger = logger
|
8
|
+
@source_prefix = source_prefix
|
9
|
+
end
|
10
|
+
|
11
|
+
def write(*instrumenters)
|
12
|
+
lines(instrumenters).each do |line|
|
13
|
+
logger.info line
|
14
|
+
end
|
15
|
+
instrumenters
|
16
|
+
end
|
17
|
+
|
5
18
|
# Example
|
6
19
|
# source=web.2 sample#load_avg_1m=0.31 sample#load_avg_5m=0.10 sample#load_avg_15m=0.05
|
7
|
-
def lines
|
8
|
-
groups.map do |source, instrumenters|
|
20
|
+
def lines(instrumenters)
|
21
|
+
groups(instrumenters).map do |source, instrumenters|
|
9
22
|
measurements = instrumenters.map { |instrumenter| measurement(instrumenter) }
|
10
23
|
Lines.new(full_source(source), measurements).lines
|
11
24
|
end.flatten
|
@@ -15,12 +28,12 @@ module Metrics::Formatters
|
|
15
28
|
|
16
29
|
# Internal: We group the metrics by their source so that we can separate
|
17
30
|
# the lines.
|
18
|
-
def groups
|
31
|
+
def groups(instrumenters)
|
19
32
|
instrumenters.group_by(&:source)
|
20
33
|
end
|
21
34
|
|
22
35
|
def full_source(source=nil)
|
23
|
-
[
|
36
|
+
[source_prefix, source].reject { |s| blank?(s) }.join('.')
|
24
37
|
end
|
25
38
|
|
26
39
|
def measurement(instrumenter)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Metrics::Drivers
|
2
|
+
class Statsd
|
3
|
+
attr_reader :client, :template, :source_prefix
|
4
|
+
|
5
|
+
def initialize(client, template, source_prefix)
|
6
|
+
@client = client # The statsd client
|
7
|
+
@template = template # The template for the metric name
|
8
|
+
@source_prefix = source_prefix # Source prefix
|
9
|
+
end
|
10
|
+
|
11
|
+
def write(*instrumenters)
|
12
|
+
instrumenters.each do |instrumenter|
|
13
|
+
emit(instrumenter)
|
14
|
+
end
|
15
|
+
instrumenters
|
16
|
+
end
|
17
|
+
|
18
|
+
def emit(instrumenter)
|
19
|
+
name = name_for(instrumenter)
|
20
|
+
value = instrumenter.value
|
21
|
+
|
22
|
+
case instrumenter.type
|
23
|
+
when 'measure', 'sample'
|
24
|
+
if instrumenter.units == 'ms'
|
25
|
+
client.timing(name, value)
|
26
|
+
else
|
27
|
+
client.gauge(name, value)
|
28
|
+
end
|
29
|
+
when 'count'
|
30
|
+
client.count(name, value)
|
31
|
+
else
|
32
|
+
raise ArgumentError.new("unsupported instrumenter type for statsd: '%s'" % instrumenter.type)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def name_for(instrumenter)
|
39
|
+
template.gsub('{{name}}', instrumenter.metric).gsub('{{source}}', source(instrumenter))
|
40
|
+
end
|
41
|
+
|
42
|
+
def source(instrumenter)
|
43
|
+
[source_prefix, instrumenter.source].compact.join('.')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/metrics/grouping.rb
CHANGED
@@ -3,9 +3,9 @@ module Metrics
|
|
3
3
|
# instruments to output on a single line.
|
4
4
|
class Grouping
|
5
5
|
attr_reader :namespace, :instrumenters, :options
|
6
|
-
|
7
|
-
def self.instrument(
|
8
|
-
new(
|
6
|
+
|
7
|
+
def self.instrument(namespace = nil, options = {}, &block)
|
8
|
+
new(namespace, options, &block).instrumenters
|
9
9
|
end
|
10
10
|
|
11
11
|
def initialize(namespace = nil, options = {}, &block)
|
data/lib/metrics/handler.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Metrics
|
2
2
|
|
3
3
|
# Internal: Responsible for taking a list or an Array of
|
4
|
-
# Metrics::Instrumenters and passing them to the
|
4
|
+
# Metrics::Instrumenters and passing them to the driver.
|
5
5
|
class Handler
|
6
6
|
attr_reader :instrumenters
|
7
7
|
|
@@ -10,34 +10,27 @@ module Metrics
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def initialize(*instrumenters)
|
13
|
-
@instrumenters = instrumenters
|
13
|
+
@instrumenters = instrumenters
|
14
14
|
end
|
15
15
|
|
16
|
-
# Public: Writes all of the instrumenters to
|
16
|
+
# Public: Writes all of the instrumenters to the driver.
|
17
17
|
#
|
18
|
-
# Returns an Array of Metrics::Instrumenters that were written
|
18
|
+
# Returns an Array of Metrics::Instrumenters that were written.
|
19
19
|
def handle
|
20
|
-
write
|
21
|
-
result
|
20
|
+
return write(*instrumenters)
|
22
21
|
end
|
23
22
|
|
24
23
|
private
|
24
|
+
def write(*instrumenters)
|
25
|
+
driver.write(*instrumenters)
|
26
|
+
end
|
25
27
|
|
26
|
-
def
|
27
|
-
|
28
|
+
def driver
|
29
|
+
configuration.driver
|
28
30
|
end
|
29
31
|
|
30
32
|
def configuration
|
31
33
|
Metrics.configuration
|
32
34
|
end
|
33
|
-
|
34
|
-
def write(*args, &block)
|
35
|
-
formatter.write(*args, &block)
|
36
|
-
end
|
37
|
-
|
38
|
-
def formatter
|
39
|
-
configuration.formatter
|
40
|
-
end
|
41
|
-
|
42
35
|
end
|
43
36
|
end
|
data/lib/metrics/version.rb
CHANGED
@@ -1,19 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'securerandom'
|
3
3
|
|
4
|
-
describe Metrics::
|
5
|
-
let(:
|
6
|
-
|
7
|
-
before do
|
8
|
-
Metrics.configuration.stub source: 'app'
|
9
|
-
end
|
4
|
+
describe Metrics::Drivers::L2Met do
|
5
|
+
let(:driver) { described_class.new(Logger.new('/dev/null'), 'app') }
|
10
6
|
|
11
7
|
def instrumenter(values)
|
12
8
|
double Metrics::Instrumenter, { source: nil, type: 'measure' }.merge(values)
|
13
9
|
end
|
14
10
|
|
15
11
|
describe '.lines' do
|
16
|
-
subject(:lines) {
|
12
|
+
subject(:lines) { driver.lines(instrumenters) }
|
17
13
|
|
18
14
|
context 'with a single instrumenter' do
|
19
15
|
let(:instrumenters) { [ instrumenter(metric: 'rack.request.time', value: 10.3333, units: 'ms', type: 'sample') ] }
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
describe Metrics::Drivers::Statsd do
|
5
|
+
let(:client) { double }
|
6
|
+
|
7
|
+
def instrumenter(*args)
|
8
|
+
Metrics::Instrumenter.new(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def write(*instrumenters)
|
12
|
+
described_class.new(client, '{{name}}.source__{{source}}__', 'app').write(*instrumenters)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '.write' do
|
16
|
+
context 'metric types' do
|
17
|
+
it 'should call statsd.timing' do
|
18
|
+
client.should_receive(:timing).with('rack.request.time.source__app__', 10.3333)
|
19
|
+
write(instrumenter('rack.request.time', 10.3333, units: 'ms', type: 'sample'))
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should call statsd.gauge' do
|
23
|
+
client.should_receive(:gauge).with('rack.request.size.source__app__', 10)
|
24
|
+
write(instrumenter('rack.request.size', 10, type: 'measure'))
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should call statsd.count' do
|
28
|
+
client.should_receive(:count).with('foo.bar.source__app__', 10)
|
29
|
+
write(instrumenter('foo.bar', 10, type: 'count'))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'metric sources' do
|
34
|
+
it 'should insert the globally configured source' do
|
35
|
+
client.should_receive(:count).with('foo.bar.source__app__', 10)
|
36
|
+
write(instrumenter('foo.bar', 10, type: 'count'))
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should append the instrumenter source' do
|
40
|
+
client.should_receive(:count).with('foo.bar.source__app.us__', 10)
|
41
|
+
write(instrumenter('foo.bar', 10, type: 'count', source: 'us'))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,69 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formatted-metrics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric J. Holmes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '2.14'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '2.14'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: faraday
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 0.9.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.9.0
|
69
69
|
description: Easily output formatted metrics to stdout
|
@@ -73,9 +73,9 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
-
- .gitignore
|
77
|
-
- .rspec
|
78
|
-
- .travis.yml
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".travis.yml"
|
79
79
|
- Gemfile
|
80
80
|
- LICENSE
|
81
81
|
- README.md
|
@@ -86,8 +86,8 @@ files:
|
|
86
86
|
- lib/metrics.rb
|
87
87
|
- lib/metrics/configuration.rb
|
88
88
|
- lib/metrics/core_ext.rb
|
89
|
-
- lib/metrics/
|
90
|
-
- lib/metrics/
|
89
|
+
- lib/metrics/drivers/l2met.rb
|
90
|
+
- lib/metrics/drivers/statsd.rb
|
91
91
|
- lib/metrics/grouping.rb
|
92
92
|
- lib/metrics/handler.rb
|
93
93
|
- lib/metrics/instrumentable.rb
|
@@ -98,7 +98,8 @@ files:
|
|
98
98
|
- lib/rack/instrumentation.rb
|
99
99
|
- lib/sidekiq/middleware/server/instrumentation.rb
|
100
100
|
- spec/faraday/instrumentation_spec.rb
|
101
|
-
- spec/metrics/
|
101
|
+
- spec/metrics/drivers/l2met_spec.rb
|
102
|
+
- spec/metrics/drivers/statsd_spec.rb
|
102
103
|
- spec/metrics/grouping_spec.rb
|
103
104
|
- spec/metrics/instrumentable_spec.rb
|
104
105
|
- spec/metrics/instrumenter_spec.rb
|
@@ -115,26 +116,28 @@ require_paths:
|
|
115
116
|
- lib
|
116
117
|
required_ruby_version: !ruby/object:Gem::Requirement
|
117
118
|
requirements:
|
118
|
-
- -
|
119
|
+
- - ">="
|
119
120
|
- !ruby/object:Gem::Version
|
120
121
|
version: '0'
|
121
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
123
|
requirements:
|
123
|
-
- -
|
124
|
+
- - ">="
|
124
125
|
- !ruby/object:Gem::Version
|
125
126
|
version: '0'
|
126
127
|
requirements: []
|
127
128
|
rubyforge_project:
|
128
|
-
rubygems_version: 2.
|
129
|
+
rubygems_version: 2.4.5
|
129
130
|
signing_key:
|
130
131
|
specification_version: 4
|
131
132
|
summary: Easily output formatted metrics to stdout
|
132
133
|
test_files:
|
133
134
|
- spec/faraday/instrumentation_spec.rb
|
134
|
-
- spec/metrics/
|
135
|
+
- spec/metrics/drivers/l2met_spec.rb
|
136
|
+
- spec/metrics/drivers/statsd_spec.rb
|
135
137
|
- spec/metrics/grouping_spec.rb
|
136
138
|
- spec/metrics/instrumentable_spec.rb
|
137
139
|
- spec/metrics/instrumenter_spec.rb
|
138
140
|
- spec/metrics_spec.rb
|
139
141
|
- spec/rack/instrumentation_spec.rb
|
140
142
|
- spec/spec_helper.rb
|
143
|
+
has_rdoc:
|
@@ -1,31 +0,0 @@
|
|
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
|