formatted-metrics 1.2.0 → 1.3.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 +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
|
[](https://travis-ci.org/remind101/formatted-metrics) [](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
|