prometheus-client-tracer 1.0.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/.circleci/config.yml +42 -0
- data/.rspec +1 -0
- data/.rubocop.yml +25 -0
- data/.ruby-version +1 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +61 -0
- data/README.md +64 -0
- data/lib/prometheus/client/tracer.rb +79 -0
- data/lib/prometheus/middleware/trace_collector.rb +22 -0
- data/prometheus-client-tracer.gemspec +26 -0
- data/spec/prometheus/client/tracer_spec.rb +82 -0
- data/spec/prometheus/middleware/trace_collector_spec.rb +22 -0
- data/spec/spec_helper.rb +5 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 11dbb55ad9c5ce0135dd4376dff72e95b1f6e5ae378e1e4c6de2ce23a4ddc915
|
4
|
+
data.tar.gz: 762b4e6b78aaa60c82c97470a9cf1df136b0e3fe685396df117beee3671c7012
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6291fbf2dcb56141208005a94df27e22531cd3e7c012551a809ab3287602702d91d8a499a3cea580b3b2b8ef07c677898abdb7c5f0a06296b923652a94e60b66
|
7
|
+
data.tar.gz: ec047172d19516f20a24996adf32ceabb651e03627923e30b2e1ef90e096107f0f123e263cb2ff6325a5cbabfc86a4044a681046c54ebcfcd440c726a76817ea
|
@@ -0,0 +1,42 @@
|
|
1
|
+
---
|
2
|
+
version: 2
|
3
|
+
|
4
|
+
references:
|
5
|
+
steps: &steps
|
6
|
+
- checkout
|
7
|
+
|
8
|
+
- type: cache-restore
|
9
|
+
key: prometheus-client-tracer-bundler-{{ checksum "prometheus-client-tracer.gemspec" }}
|
10
|
+
|
11
|
+
- run: gem install bundler -v 2.0.1
|
12
|
+
- run: bundle install --path vendor/bundle
|
13
|
+
|
14
|
+
- type: cache-save
|
15
|
+
key: prometheus-client-tracer-bundler-{{ checksum "prometheus-client-tracer.gemspec" }}
|
16
|
+
paths:
|
17
|
+
- vendor/bundle
|
18
|
+
|
19
|
+
- run: bundle exec rubocop
|
20
|
+
- run: bundle exec rspec
|
21
|
+
|
22
|
+
jobs:
|
23
|
+
build-ruby24:
|
24
|
+
docker:
|
25
|
+
- image: ruby:2.4
|
26
|
+
steps: *steps
|
27
|
+
build-ruby25:
|
28
|
+
docker:
|
29
|
+
- image: ruby:2.5
|
30
|
+
steps: *steps
|
31
|
+
build-ruby26:
|
32
|
+
docker:
|
33
|
+
- image: ruby:2.6
|
34
|
+
steps: *steps
|
35
|
+
|
36
|
+
workflows:
|
37
|
+
version: 2
|
38
|
+
tests:
|
39
|
+
jobs:
|
40
|
+
- build-ruby24
|
41
|
+
- build-ruby25
|
42
|
+
- build-ruby26
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require ./spec/spec_helper.rb --color
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
inherit_gem:
|
3
|
+
gc_ruboconfig: rubocop.yml
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
TargetRubyVersion: 2.4
|
7
|
+
|
8
|
+
Metrics/MethodLength:
|
9
|
+
Max: 15
|
10
|
+
|
11
|
+
RSpec/MultipleExpectations:
|
12
|
+
Max: 3
|
13
|
+
|
14
|
+
Style/RescueStandardError:
|
15
|
+
Exclude:
|
16
|
+
- "*/**/*_spec.rb"
|
17
|
+
|
18
|
+
Naming/UncommunicativeMethodParamName:
|
19
|
+
AllowedNames:
|
20
|
+
# These are the default allowed names, set by Rubocop
|
21
|
+
- io
|
22
|
+
- id
|
23
|
+
# These are some custom names that we want to allow, since they aren't
|
24
|
+
# uncommunicative - they're actually rather meaningful!
|
25
|
+
- as
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.6.2
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
prometheus-client-tracer (1.0.0)
|
5
|
+
prometheus-client (~> 0.10.0.alpha)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.4.0)
|
11
|
+
coderay (1.1.2)
|
12
|
+
diff-lcs (1.3)
|
13
|
+
gc_ruboconfig (2.4.0)
|
14
|
+
rubocop (>= 0.70)
|
15
|
+
rubocop-rspec (>= 1.33.0)
|
16
|
+
jaro_winkler (1.5.3)
|
17
|
+
method_source (0.9.2)
|
18
|
+
parallel (1.17.0)
|
19
|
+
parser (2.6.3.0)
|
20
|
+
ast (~> 2.4.0)
|
21
|
+
prometheus-client (0.10.0.pre.alpha.2)
|
22
|
+
pry (0.12.2)
|
23
|
+
coderay (~> 1.1.0)
|
24
|
+
method_source (~> 0.9.0)
|
25
|
+
rainbow (3.0.0)
|
26
|
+
rspec (3.8.0)
|
27
|
+
rspec-core (~> 3.8.0)
|
28
|
+
rspec-expectations (~> 3.8.0)
|
29
|
+
rspec-mocks (~> 3.8.0)
|
30
|
+
rspec-core (3.8.2)
|
31
|
+
rspec-support (~> 3.8.0)
|
32
|
+
rspec-expectations (3.8.4)
|
33
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
+
rspec-support (~> 3.8.0)
|
35
|
+
rspec-mocks (3.8.1)
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
+
rspec-support (~> 3.8.0)
|
38
|
+
rspec-support (3.8.2)
|
39
|
+
rubocop (0.72.0)
|
40
|
+
jaro_winkler (~> 1.5.1)
|
41
|
+
parallel (~> 1.10)
|
42
|
+
parser (>= 2.6)
|
43
|
+
rainbow (>= 2.2.2, < 4.0)
|
44
|
+
ruby-progressbar (~> 1.7)
|
45
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
46
|
+
rubocop-rspec (1.33.0)
|
47
|
+
rubocop (>= 0.60.0)
|
48
|
+
ruby-progressbar (1.10.1)
|
49
|
+
unicode-display_width (1.6.0)
|
50
|
+
|
51
|
+
PLATFORMS
|
52
|
+
ruby
|
53
|
+
|
54
|
+
DEPENDENCIES
|
55
|
+
gc_ruboconfig (= 2.4.0)
|
56
|
+
prometheus-client-tracer!
|
57
|
+
pry (~> 0.10)
|
58
|
+
rspec (~> 3.8)
|
59
|
+
|
60
|
+
BUNDLED WITH
|
61
|
+
2.0.1
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# prometheus-client-tracer-ruby [](https://circleci.com/gh/lawrencejones/prometheus-client-tracer-ruby)
|
2
|
+
|
3
|
+
This gem provides an interface for tracing long-running duration measurements
|
4
|
+
using the Prometheus client. By updating the associated metric as part of the
|
5
|
+
Prometheus /metrics endpoint, the increment is spread evenly over the scrapes
|
6
|
+
that occur while the operation is in process, instead of applying one massive
|
7
|
+
increment at the end.
|
8
|
+
|
9
|
+
This means you can trust your metrics will be accurate, even if the operations
|
10
|
+
you're measuring far exceed your scrape duration.
|
11
|
+
|
12
|
+
## Why?
|
13
|
+
|
14
|
+
One of the most common observability requirements is to trace the amount of time
|
15
|
+
spent running a job or task. This information is useful in the context of when
|
16
|
+
this time was spent. The typical implementation of such a measurement might be:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
def run
|
20
|
+
start = Time.now
|
21
|
+
long_running_task
|
22
|
+
metric.increment(by: start - Time.now)
|
23
|
+
end
|
24
|
+
```
|
25
|
+
|
26
|
+
The metric tracking duration is incremented only once the task has finished. If
|
27
|
+
the task took > Prometheus scrape interval, perhaps by a significant factor (say
|
28
|
+
1hr vs the normal 15s scrape interval), then the metric is incremented by a huge
|
29
|
+
value only after the task has finished. Graphs visualising how time is spent
|
30
|
+
will show no activity while the task was running and then an impossible burst
|
31
|
+
just as things finish.
|
32
|
+
|
33
|
+
To avoid this time of measurement bias, this commit introduces a metric tracer
|
34
|
+
that manages updating metrics associated with long-running tasks. Users will
|
35
|
+
begin a trace, do work, and while the work is on-going any calls to the tracer
|
36
|
+
collect method will incrementally update the associated metric with elapsed
|
37
|
+
time.
|
38
|
+
|
39
|
+
This is a game-changer in terms of making metrics usable, removing a huge source
|
40
|
+
of uncertainty when interpreting metric measurements. The implementation of the
|
41
|
+
tracer is thread safe and designed to be as lightweight as possible- it should
|
42
|
+
hopefully provide no performance hit and be preferable for tracing durations of
|
43
|
+
most lengths, provided you don't exceed hundreds of on-going traces.
|
44
|
+
|
45
|
+
For easy use, the Prometheus client initialises a global tracer in the same vein
|
46
|
+
as the global registry. Most users are going to want to use a tracer without
|
47
|
+
initialising a handle in their own code, and can do so like this:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
def run
|
51
|
+
Prometheus::Client.trace(metric, { worker: 1 }) do
|
52
|
+
long_running_task
|
53
|
+
end
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
By default, users who do this will see their metrics update just as frequently
|
58
|
+
as the original implementation. For the incremental measurement to work, they
|
59
|
+
must use a TraceCollector to trigger a collection just prior to serving metrics:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
# By default, collect the global tracer
|
63
|
+
use Prometheus::Middleware::TraceCollector
|
64
|
+
```
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Prometheus
|
4
|
+
module Client
|
5
|
+
# Most people will want to use a global tracer instead of building their own, similar
|
6
|
+
# to how most will use the global metrics registry.
|
7
|
+
def self.tracer
|
8
|
+
@tracer ||= Tracer.new
|
9
|
+
end
|
10
|
+
|
11
|
+
# Delegate to the Tracer.
|
12
|
+
def self.trace(metric, labels = {}, &block)
|
13
|
+
tracer.trace(metric, labels, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
# For metrics that track durations over the course of long-running tasks, we need to
|
17
|
+
# ensure the metric is updated gradually while they execute instead of right at the
|
18
|
+
# end. This class is used to track on-going 'traces', records of tasks starting and
|
19
|
+
# stopping, and exposes a method `collect` that will update the associated metric with
|
20
|
+
# the time elapsed since the last `collect`.
|
21
|
+
class Tracer
|
22
|
+
Trace = Struct.new(:metric, :labels, :time)
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@lock = Mutex.new
|
26
|
+
@traces = []
|
27
|
+
end
|
28
|
+
|
29
|
+
# Start and manage the life of a trace. Pass a long-running block to this method to
|
30
|
+
# ensure the associated metric is updated gradually throughout the execution.
|
31
|
+
def trace(metric, labels = {})
|
32
|
+
start(metric, labels)
|
33
|
+
yield
|
34
|
+
ensure
|
35
|
+
stop(metric, labels)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Update currently traced metrics- this will increment all on-going traces with the
|
39
|
+
# delta of time between the last update and now. This should be called just before
|
40
|
+
# serving a /metrics request.
|
41
|
+
def collect(traces = @traces)
|
42
|
+
@lock.synchronize do
|
43
|
+
now = monotonic_now
|
44
|
+
traces.each do |trace|
|
45
|
+
time_since = [now - trace.time, 0].max
|
46
|
+
trace.time = now
|
47
|
+
trace.metric.increment(
|
48
|
+
by: time_since,
|
49
|
+
labels: trace.labels,
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def start(metric, labels = {})
|
58
|
+
@lock.synchronize { @traces << Trace.new(metric, labels, monotonic_now) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def stop(metric, labels = {})
|
62
|
+
matching = nil
|
63
|
+
@lock.synchronize do
|
64
|
+
matching, @traces = @traces.partition do |trace|
|
65
|
+
trace.metric == metric && trace.labels == labels
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
collect(matching)
|
70
|
+
end
|
71
|
+
|
72
|
+
# We're doing duration arithmetic which should make use of monotonic clocks, to
|
73
|
+
# avoid changes to the system time from affecting our metrics.
|
74
|
+
def monotonic_now
|
75
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "prometheus/client"
|
4
|
+
|
5
|
+
module Prometheus
|
6
|
+
module Middleware
|
7
|
+
# This class integrates with a Prometheus::Client::Tracer to update associated metric
|
8
|
+
# traces just prior to serving metrics. By default, this will collect traces on the
|
9
|
+
# global Client tracer.
|
10
|
+
class TraceCollector
|
11
|
+
def initialize(app, options = {})
|
12
|
+
@app = app
|
13
|
+
@tracer = options[:tracer] || Client.tracer
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
@tracer.collect
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "prometheus-client-tracer"
|
8
|
+
spec.version = "1.0.0"
|
9
|
+
spec.summary = "Tracer for accurate duration tracking with Prometheus metrics"
|
10
|
+
spec.authors = %w[me@lawrencejones.dev]
|
11
|
+
spec.homepage = "https://github.com/lawrencejones/prometheus-client-tracer"
|
12
|
+
spec.email = %w[me@lawrencejones.dev]
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.required_ruby_version = ">= 2.4"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "prometheus-client", "~> 0.10.0.alpha"
|
22
|
+
|
23
|
+
spec.add_development_dependency "gc_ruboconfig", "= 2.4.0"
|
24
|
+
spec.add_development_dependency "pry", "~> 0.10"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.8"
|
26
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "timeout"
|
4
|
+
|
5
|
+
# rubocop:disable RSpec/InstanceVariable
|
6
|
+
describe Prometheus::Client::Tracer do
|
7
|
+
subject(:tracer) { described_class.new }
|
8
|
+
|
9
|
+
let(:metric) do
|
10
|
+
Prometheus::Client::Counter.new(:counter, docstring: "example", labels: %i[worker])
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".trace" do
|
14
|
+
# These tests try stubbing timing logic. Instead of using let's, we use a test
|
15
|
+
# instance variable @now to represent the current time, as returned by a monotonic
|
16
|
+
# clock system call.
|
17
|
+
#
|
18
|
+
# The #monotonic_now method of the tracer is stubbed to always return the current
|
19
|
+
# value of @now, and tests can manipulate time by advancing that instance variable.
|
20
|
+
#
|
21
|
+
# The tracer is normally passed a block that manipulates @now.
|
22
|
+
subject(:trace) { tracer.trace(metric, labels, &trace_block) }
|
23
|
+
|
24
|
+
let(:labels) { { worker: 1 } }
|
25
|
+
let(:trace_block) { -> { @now += 1.0 } }
|
26
|
+
|
27
|
+
before do
|
28
|
+
@now = 0.0 # set initial time
|
29
|
+
allow(tracer).to receive(:monotonic_now) { @now }
|
30
|
+
end
|
31
|
+
|
32
|
+
it "increments metric with elapsed duration" do
|
33
|
+
expect { trace }.to change { metric.values[labels] }.by(1.0)
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when .collect is called during a trace" do
|
37
|
+
let(:latch) { Mutex.new }
|
38
|
+
let(:trace_block) do
|
39
|
+
-> { latch.synchronize { @now += 1.0 } }
|
40
|
+
end
|
41
|
+
|
42
|
+
# rubocop:disable RSpec/ExampleLength
|
43
|
+
it "increments metric with incremental duration" do
|
44
|
+
latch.lock # acquire the lock, trace should now block
|
45
|
+
trace_thread = Thread.new do
|
46
|
+
trace # will block until latch is released
|
47
|
+
end
|
48
|
+
|
49
|
+
# We need to block until the trace_thread has actually begun, otherwise we'll
|
50
|
+
# never be able to guarantee the trace was started at now = 0.0, even if this
|
51
|
+
# should happen almost immediately.
|
52
|
+
Timeout.timeout(1) { sleep(0.01) until tracer.collect.any? }
|
53
|
+
|
54
|
+
# Advance the clock by 0.5s
|
55
|
+
@now += 0.5
|
56
|
+
|
57
|
+
# If we now collect, the metric should be incremented by the elapsed time (0.5s)
|
58
|
+
expect { tracer.collect }.to change { metric.values[labels] }.by(0.5)
|
59
|
+
|
60
|
+
# Collect once more should leave the metric unchanged, as no time has passed since
|
61
|
+
# the last collect
|
62
|
+
expect { tracer.collect }.to change { metric.values[labels] }.by(0.0)
|
63
|
+
|
64
|
+
# Unlocking the latch and allowing the trace thread to complete will execute the
|
65
|
+
# final part of a trace, which should update the metric with time elapsed. The
|
66
|
+
# trace thread advances time by 1s right before it ends, so we expect to update
|
67
|
+
# the metric by 1s.
|
68
|
+
#
|
69
|
+
# A bug would be if we incremented the metric by the time since our trace started
|
70
|
+
# and when it ended, which in total is 1.5s. This would suggest we never reset the
|
71
|
+
# trace clock when calling collect.
|
72
|
+
expect do
|
73
|
+
latch.unlock
|
74
|
+
trace_thread.join(1)
|
75
|
+
trace_thread.kill # in case thread misbehaves
|
76
|
+
end.to change { metric.values[labels] }.by(1.0)
|
77
|
+
end
|
78
|
+
# rubocop:enable RSpec/ExampleLength
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
# rubocop:enable RSpec/InstanceVariable
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Prometheus::Middleware::TraceCollector do
|
4
|
+
subject(:collector) { described_class.new(app, options) }
|
5
|
+
|
6
|
+
let(:app) { instance_double(Proc, call: []) }
|
7
|
+
let(:options) { { tracer: tracer } }
|
8
|
+
let(:tracer) { Prometheus::Client::Tracer.new }
|
9
|
+
|
10
|
+
describe ".call" do
|
11
|
+
subject(:call) { collector.call({}) }
|
12
|
+
|
13
|
+
# The most basic of tests, just verifying the tracer is invoked. We rely on the tests
|
14
|
+
# for the tracer to validate #collect works correctly.
|
15
|
+
it "calls tracer.collect, then the original app" do
|
16
|
+
expect(tracer).to receive(:collect).and_call_original
|
17
|
+
expect(app).to receive(:call)
|
18
|
+
|
19
|
+
call
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: prometheus-client-tracer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- me@lawrencejones.dev
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-07-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: prometheus-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.10.0.alpha
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.10.0.alpha
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: gc_ruboconfig
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.4.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.4.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.8'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.8'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- me@lawrencejones.dev
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".circleci/config.yml"
|
77
|
+
- ".rspec"
|
78
|
+
- ".rubocop.yml"
|
79
|
+
- ".ruby-version"
|
80
|
+
- Gemfile
|
81
|
+
- Gemfile.lock
|
82
|
+
- README.md
|
83
|
+
- lib/prometheus/client/tracer.rb
|
84
|
+
- lib/prometheus/middleware/trace_collector.rb
|
85
|
+
- prometheus-client-tracer.gemspec
|
86
|
+
- spec/prometheus/client/tracer_spec.rb
|
87
|
+
- spec/prometheus/middleware/trace_collector_spec.rb
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
homepage: https://github.com/lawrencejones/prometheus-client-tracer
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '2.4'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubygems_version: 3.0.3
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Tracer for accurate duration tracking with Prometheus metrics
|
112
|
+
test_files:
|
113
|
+
- spec/prometheus/client/tracer_spec.rb
|
114
|
+
- spec/prometheus/middleware/trace_collector_spec.rb
|
115
|
+
- spec/spec_helper.rb
|