prometheus-client-tracer 1.0.0 → 1.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 +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -0
- data/Gemfile.lock +4 -2
- data/README.md +28 -11
- data/exe/benchmark_tracer.rb +50 -0
- data/prometheus-client-tracer.gemspec +3 -2
- data/res/bias-0_1-1_0.png +0 -0
- data/res/bias-0_1-30_0.png +0 -0
- data/spec/prometheus/client/tracer_spec.rb +1 -1
- metadata +22 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79f6efb3f1967459a218c40e8cd89854231995138ed238d3d323e901d7a52922
|
|
4
|
+
data.tar.gz: 3253ed69867af1140f9390944692d32ccecb22766342d81409be0185a10f2f19
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ec656afeb632da0716cbba505b9fb0074fb068ce041ae08fcbf9c5392351e2ba766e63e9690a7a53b163fa8688c8dc614dee73deb48f3921755c2330c254b04f
|
|
7
|
+
data.tar.gz: acaa90edcd32797f96ce46f0550ec785eddf9516792f2e4f40471eb949e39cfcfa8356723e69ec9c4da297e8f95e5969964524220c790cbcdd43f431b2cb5a66
|
data/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/prometheus-client-tracer-*.gem
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -2,7 +2,7 @@ PATH
|
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
4
|
prometheus-client-tracer (1.0.0)
|
|
5
|
-
prometheus-client (~>
|
|
5
|
+
prometheus-client (~> 1.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
@@ -18,7 +18,7 @@ GEM
|
|
|
18
18
|
parallel (1.17.0)
|
|
19
19
|
parser (2.6.3.0)
|
|
20
20
|
ast (~> 2.4.0)
|
|
21
|
-
prometheus-client (0.
|
|
21
|
+
prometheus-client (1.0.0)
|
|
22
22
|
pry (0.12.2)
|
|
23
23
|
coderay (~> 1.1.0)
|
|
24
24
|
method_source (~> 0.9.0)
|
|
@@ -45,6 +45,7 @@ GEM
|
|
|
45
45
|
unicode-display_width (>= 1.4.0, < 1.7)
|
|
46
46
|
rubocop-rspec (1.33.0)
|
|
47
47
|
rubocop (>= 0.60.0)
|
|
48
|
+
ruby-prof (0.18.0)
|
|
48
49
|
ruby-progressbar (1.10.1)
|
|
49
50
|
unicode-display_width (1.6.0)
|
|
50
51
|
|
|
@@ -56,6 +57,7 @@ DEPENDENCIES
|
|
|
56
57
|
prometheus-client-tracer!
|
|
57
58
|
pry (~> 0.10)
|
|
58
59
|
rspec (~> 3.8)
|
|
60
|
+
ruby-prof (~> 0.18)
|
|
59
61
|
|
|
60
62
|
BUNDLED WITH
|
|
61
63
|
2.0.1
|
data/README.md
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# prometheus-client-tracer-ruby [](https://circleci.com/gh/lawrencejones/prometheus-client-tracer-ruby)
|
|
2
2
|
|
|
3
|
+
https://blog.lawrencejones.dev/incremental-measurement/
|
|
4
|
+
|
|
3
5
|
This gem provides an interface for tracing long-running duration measurements
|
|
4
6
|
using the Prometheus client. By updating the associated metric as part of the
|
|
5
7
|
Prometheus /metrics endpoint, the increment is spread evenly over the scrapes
|
|
6
|
-
that occur while the operation is in process, instead of applying one
|
|
8
|
+
that occur while the operation is in process, instead of applying one large
|
|
7
9
|
increment at the end.
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
If you find this useful and would prefer it to live within the official
|
|
12
|
+
Prometheus Ruby client, please drop your feedback as a comment here:
|
|
13
|
+
https://github.com/prometheus/client_ruby/pull/135
|
|
11
14
|
|
|
12
15
|
## Why?
|
|
13
16
|
|
|
@@ -30,8 +33,21 @@ value only after the task has finished. Graphs visualising how time is spent
|
|
|
30
33
|
will show no activity while the task was running and then an impossible burst
|
|
31
34
|
just as things finish.
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
When jobs run quickly, your graphs will look reasonable. An example with ten
|
|
37
|
+
workers constantly working small jobs, each worker reports one second of work
|
|
38
|
+
per second, as the world should be.
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
As soon as job duration increases, the bias becomes significant, and the graph
|
|
43
|
+
starts departing from reality:
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
## How?
|
|
48
|
+
|
|
49
|
+
To avoid this time of measurement bias, this gem provides a metric tracer
|
|
50
|
+
that manages updating metrics associated with long-running tasks. Users will
|
|
35
51
|
begin a trace, do work, and while the work is on-going any calls to the tracer
|
|
36
52
|
collect method will incrementally update the associated metric with elapsed
|
|
37
53
|
time.
|
|
@@ -42,9 +58,9 @@ tracer is thread safe and designed to be as lightweight as possible- it should
|
|
|
42
58
|
hopefully provide no performance hit and be preferable for tracing durations of
|
|
43
59
|
most lengths, provided you don't exceed hundreds of on-going traces.
|
|
44
60
|
|
|
45
|
-
For easy use, the Prometheus client
|
|
46
|
-
|
|
47
|
-
initialising
|
|
61
|
+
For easy use, we patch the Prometheus client with a global tracer, following the
|
|
62
|
+
example of the global registry. Most users will want to use tracers without
|
|
63
|
+
initialising one in their own code, and can do so like this:
|
|
48
64
|
|
|
49
65
|
```ruby
|
|
50
66
|
def run
|
|
@@ -54,9 +70,10 @@ def run
|
|
|
54
70
|
end
|
|
55
71
|
```
|
|
56
72
|
|
|
57
|
-
|
|
58
|
-
as the
|
|
59
|
-
must use a TraceCollector to trigger a collection
|
|
73
|
+
Without any additional configuration, users who do this will see their metrics
|
|
74
|
+
update just as frequently as the naive implementation. For the incremental
|
|
75
|
+
measurement to work, they must use a `TraceCollector` to trigger a collection
|
|
76
|
+
just prior to serving metrics:
|
|
60
77
|
|
|
61
78
|
```ruby
|
|
62
79
|
# By default, collect the global tracer
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file can be used to validate the performance of the tracer is not incomparable to a
|
|
4
|
+
# naive tracing implementation. The performance will degrade linearly with the number of
|
|
5
|
+
# on-going traces, however a modern i7 can achieve trace throughput:
|
|
6
|
+
#
|
|
7
|
+
# naive: 333k/s
|
|
8
|
+
# trace, 0 on-going: 233k/s
|
|
9
|
+
# trace, 5 on-going: 216k/s
|
|
10
|
+
# trace, 25 on-going: 155k/s
|
|
11
|
+
# trace, 100 on-going: 84k/s
|
|
12
|
+
#
|
|
13
|
+
# While this seems more than reasonable performance for almost any use case, consider
|
|
14
|
+
# using multiple tracers if this does become a problem.
|
|
15
|
+
|
|
16
|
+
require "benchmark"
|
|
17
|
+
|
|
18
|
+
require "prometheus/client"
|
|
19
|
+
require "prometheus/client/tracer"
|
|
20
|
+
|
|
21
|
+
counter = Prometheus::Client::Counter.new(
|
|
22
|
+
:counter, docstring: "example", labels: %i[worker]
|
|
23
|
+
)
|
|
24
|
+
another_counter = Prometheus::Client::Counter.new(
|
|
25
|
+
:counter_another, docstring: "another example", labels: %i[]
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def trace(metric, labels = {})
|
|
29
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
30
|
+
yield
|
|
31
|
+
ensure
|
|
32
|
+
metric.increment(
|
|
33
|
+
by: Process.clock_gettime(Process::CLOCK_MONOTONIC) - start,
|
|
34
|
+
labels: labels,
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
n_string, n_concurrent_traces_string, = ARGV
|
|
39
|
+
n, n_concurrent_traces = [n_string.to_i, n_concurrent_traces_string.to_i]
|
|
40
|
+
|
|
41
|
+
n_concurrent_traces.times do
|
|
42
|
+
Prometheus::Client.tracer.send(:start, another_counter, {})
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
Benchmark.bm(7) do |x|
|
|
46
|
+
x.report("naive:") { n.times { trace(counter, worker: 1) { nil } } }
|
|
47
|
+
x.report("trace:") do
|
|
48
|
+
n.times { Prometheus::Client.tracer.trace(counter, worker: 1) { nil } }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "prometheus-client-tracer"
|
|
8
|
-
spec.version = "1.
|
|
8
|
+
spec.version = "1.1.0"
|
|
9
9
|
spec.summary = "Tracer for accurate duration tracking with Prometheus metrics"
|
|
10
10
|
spec.authors = %w[me@lawrencejones.dev]
|
|
11
11
|
spec.homepage = "https://github.com/lawrencejones/prometheus-client-tracer"
|
|
@@ -18,9 +18,10 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^spec/})
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
-
spec.add_dependency "prometheus-client", "~>
|
|
21
|
+
spec.add_dependency "prometheus-client", "~> 1.0"
|
|
22
22
|
|
|
23
23
|
spec.add_development_dependency "gc_ruboconfig", "= 2.4.0"
|
|
24
24
|
spec.add_development_dependency "pry", "~> 0.10"
|
|
25
25
|
spec.add_development_dependency "rspec", "~> 3.8"
|
|
26
|
+
spec.add_development_dependency "ruby-prof", "~> 0.18"
|
|
26
27
|
end
|
|
Binary file
|
|
Binary file
|
|
@@ -21,7 +21,7 @@ describe Prometheus::Client::Tracer do
|
|
|
21
21
|
# The tracer is normally passed a block that manipulates @now.
|
|
22
22
|
subject(:trace) { tracer.trace(metric, labels, &trace_block) }
|
|
23
23
|
|
|
24
|
-
let(:labels) { { worker: 1 } }
|
|
24
|
+
let(:labels) { { worker: "1" } }
|
|
25
25
|
let(:trace_block) { -> { @now += 1.0 } }
|
|
26
26
|
|
|
27
27
|
before do
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: prometheus-client-tracer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- me@lawrencejones.dev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-01-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: prometheus-client
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: '1.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: '1.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: gc_ruboconfig
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,6 +66,20 @@ dependencies:
|
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '3.8'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: ruby-prof
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0.18'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0.18'
|
|
69
83
|
description:
|
|
70
84
|
email:
|
|
71
85
|
- me@lawrencejones.dev
|
|
@@ -74,15 +88,19 @@ extensions: []
|
|
|
74
88
|
extra_rdoc_files: []
|
|
75
89
|
files:
|
|
76
90
|
- ".circleci/config.yml"
|
|
91
|
+
- ".gitignore"
|
|
77
92
|
- ".rspec"
|
|
78
93
|
- ".rubocop.yml"
|
|
79
94
|
- ".ruby-version"
|
|
80
95
|
- Gemfile
|
|
81
96
|
- Gemfile.lock
|
|
82
97
|
- README.md
|
|
98
|
+
- exe/benchmark_tracer.rb
|
|
83
99
|
- lib/prometheus/client/tracer.rb
|
|
84
100
|
- lib/prometheus/middleware/trace_collector.rb
|
|
85
101
|
- prometheus-client-tracer.gemspec
|
|
102
|
+
- res/bias-0_1-1_0.png
|
|
103
|
+
- res/bias-0_1-30_0.png
|
|
86
104
|
- spec/prometheus/client/tracer_spec.rb
|
|
87
105
|
- spec/prometheus/middleware/trace_collector_spec.rb
|
|
88
106
|
- spec/spec_helper.rb
|