yabeda-gvl_metrics 0.1.0 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +23 -7
- data/lib/yabeda/gvl_metrics/version.rb +1 -1
- data/lib/yabeda/gvl_metrics.rb +42 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8749669e68bbeda5b52d65280f39b68f008e23f7d043bb35a3cd993acd2ff5a
|
|
4
|
+
data.tar.gz: a7bb3003b69681c70b99e73be3330a694abd8036168c0a858678b47a8a3bbf95
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9ae994b9f1fdf4a6540024680ebaf90d05f36f5ca74238c853329217cd5184265a1e171d02df43ba975ad7e3e4c0e452013278250553514e7d59d8628c98cc07
|
|
7
|
+
data.tar.gz: 921f39479601ea69507705d6edfd3d40d2c7386869ca6e380a2a0b0fff034fbfdd06fb23560225eed300dace047dca93e1277e84d87faafd70ef4e7774d2a40b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- `hostname`, `pid`, `queue`, and `job_class` tags on all GVL metrics. `hostname`/`pid` identify the emitting process (`pid` is read per measurement so it stays correct under forking servers); `queue`/`job_class` segment Sidekiq metrics by the job's queue and class. All values are sourced locally — from within the process and from the data `gvl_metrics_middleware` already passes to the callback — with no `Sidekiq::ProcessSet`/Redis lookup. `queue` and `job_class` are empty for Rack.
|
|
6
|
+
|
|
3
7
|
## [0.1.0] - 2026-02-09
|
|
4
8
|
|
|
5
9
|
- Initial release
|
data/README.md
CHANGED
|
@@ -40,16 +40,32 @@ For non-Rails applications, call `configure!` directly after requiring the gem.
|
|
|
40
40
|
|
|
41
41
|
## Metrics
|
|
42
42
|
|
|
43
|
-
All metrics are registered as Yabeda gauges in the `gvl_metrics` group
|
|
43
|
+
All metrics are registered as Yabeda gauges in the `gvl_metrics` group, reported in nanoseconds. Each gauge holds the value from the most recent request or job for a given set of tags.
|
|
44
44
|
|
|
45
45
|
For metric definitions, see: https://github.com/speedshop/gvl_metrics_middleware?tab=readme-ov-file#available-metrics
|
|
46
46
|
|
|
47
|
-
| Metric |
|
|
48
|
-
|
|
49
|
-
| `gvl_metrics_total` |
|
|
50
|
-
| `gvl_metrics_running` |
|
|
51
|
-
| `gvl_metrics_io_wait` |
|
|
52
|
-
| `gvl_metrics_gvl_wait` |
|
|
47
|
+
| Metric | Description |
|
|
48
|
+
|--------|-------------|
|
|
49
|
+
| `gvl_metrics_total` | Total time (running + io_wait + gvl_wait) |
|
|
50
|
+
| `gvl_metrics_running` | Time spent running Ruby code |
|
|
51
|
+
| `gvl_metrics_io_wait` | Time spent waiting on IO |
|
|
52
|
+
| `gvl_metrics_gvl_wait` | Time spent waiting on the GVL |
|
|
53
|
+
|
|
54
|
+
### Tags
|
|
55
|
+
|
|
56
|
+
Every metric carries the following tags, so you can attribute GVL time to a specific process and, for Sidekiq, to the job that ran:
|
|
57
|
+
|
|
58
|
+
| Tag | Description |
|
|
59
|
+
|-----|-------------|
|
|
60
|
+
| `source` | `"rack"` or `"sidekiq"` |
|
|
61
|
+
| `hostname` | Host the process runs on (`ENV["DYNO"]` if set, otherwise `Socket.gethostname` — the same value Sidekiq reports for itself) |
|
|
62
|
+
| `pid` | Process ID. Read fresh on every measurement, so it stays correct under forking servers (e.g. Puma in cluster mode) |
|
|
63
|
+
| `queue` | Sidekiq only: the queue the job was pulled from. Empty for Rack. |
|
|
64
|
+
| `job_class` | Sidekiq only: the job's class name. Empty for Rack. |
|
|
65
|
+
|
|
66
|
+
The `hostname`, `pid`, `queue`, and `job_class` values are read locally from within the running process and from the data `gvl_metrics_middleware` already passes to the callback — there is no `Sidekiq::ProcessSet`/Redis lookup involved.
|
|
67
|
+
|
|
68
|
+
> **Cardinality:** `queue` and especially `job_class` multiply the number of time series per process (one series per `source`/`queue`/`job_class` combination), and `pid` produces a new series for every restart or redeploy. On apps with many job classes this can add up — keep an eye on your metrics backend's cardinality.
|
|
53
69
|
|
|
54
70
|
## Contributing
|
|
55
71
|
|
data/lib/yabeda/gvl_metrics.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "socket"
|
|
4
|
+
|
|
3
5
|
require "yabeda"
|
|
4
6
|
require "gvl_metrics_middleware"
|
|
5
7
|
|
|
@@ -10,7 +12,7 @@ module Yabeda
|
|
|
10
12
|
class Error < StandardError; end
|
|
11
13
|
|
|
12
14
|
METRIC_GROUP = :gvl_metrics
|
|
13
|
-
METRIC_TAGS = [
|
|
15
|
+
METRIC_TAGS = %i[source hostname pid queue job_class].freeze
|
|
14
16
|
|
|
15
17
|
class << self
|
|
16
18
|
def configure!(rack: defined?(::Rack), sidekiq: defined?(::Sidekiq))
|
|
@@ -39,26 +41,60 @@ module Yabeda
|
|
|
39
41
|
GvlMetricsMiddleware.configure do |config|
|
|
40
42
|
if rack
|
|
41
43
|
config.rack do |total, running, io_wait, gvl_wait|
|
|
42
|
-
|
|
44
|
+
record_rack(total, running, io_wait, gvl_wait)
|
|
43
45
|
end
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
if sidekiq
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
# gvl_metrics_middleware already hands the current job's queue and
|
|
50
|
+
# class to the callback as keyword arguments, so we can segment by
|
|
51
|
+
# them without any Sidekiq::ProcessSet/Redis lookup. They are given
|
|
52
|
+
# defaults so this stays compatible with any middleware version that
|
|
53
|
+
# does not send them.
|
|
54
|
+
config.sidekiq do |total, running, io_wait, gvl_wait, queue: nil, job_class: nil|
|
|
55
|
+
record_sidekiq(total, running, io_wait, gvl_wait, queue: queue, job_class: job_class)
|
|
49
56
|
end
|
|
50
57
|
end
|
|
51
58
|
end
|
|
52
59
|
end
|
|
53
60
|
|
|
54
|
-
def
|
|
55
|
-
|
|
61
|
+
def record_rack(total, running, io_wait, gvl_wait)
|
|
62
|
+
write_metrics({ source: "rack", hostname: hostname, pid: ::Process.pid }, total, running, io_wait, gvl_wait)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def record_sidekiq(total, running, io_wait, gvl_wait, queue: nil, job_class: nil)
|
|
66
|
+
tags = {
|
|
67
|
+
source: "sidekiq",
|
|
68
|
+
hostname: hostname,
|
|
69
|
+
pid: ::Process.pid,
|
|
70
|
+
queue: queue.to_s,
|
|
71
|
+
job_class: job_class.to_s,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
write_metrics(tags, total, running, io_wait, gvl_wait)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def write_metrics(tags, total, running, io_wait, gvl_wait)
|
|
78
|
+
# Every gauge is declared with the full METRIC_TAGS set, and exporters such
|
|
79
|
+
# as yabeda-prometheus reject a write that omits any declared tag. Default
|
|
80
|
+
# the tags a source does not set (queue/job_class for Rack) to an empty
|
|
81
|
+
# string so callers don't have to spell them out.
|
|
82
|
+
tags = { queue: "", job_class: "" }.merge(tags)
|
|
56
83
|
|
|
57
84
|
Yabeda.gvl_metrics.total.set(tags, total)
|
|
58
85
|
Yabeda.gvl_metrics.running.set(tags, running)
|
|
59
86
|
Yabeda.gvl_metrics.io_wait.set(tags, io_wait)
|
|
60
87
|
Yabeda.gvl_metrics.gvl_wait.set(tags, gvl_wait)
|
|
61
88
|
end
|
|
89
|
+
|
|
90
|
+
# The host name does not change across a fork, so memoizing it (even if the
|
|
91
|
+
# value is inherited by a forked worker) is safe. The pid, which does change
|
|
92
|
+
# on fork, is read fresh on every call instead, so it stays correct under
|
|
93
|
+
# forking servers such as Puma in cluster mode. This mirrors how Sidekiq
|
|
94
|
+
# itself derives its hostname.
|
|
95
|
+
def hostname
|
|
96
|
+
@hostname ||= ENV["DYNO"] || Socket.gethostname
|
|
97
|
+
end
|
|
62
98
|
end
|
|
63
99
|
end
|
|
64
100
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yabeda-gvl_metrics
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nate Berkopec
|
|
@@ -77,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
77
|
- !ruby/object:Gem::Version
|
|
78
78
|
version: '0'
|
|
79
79
|
requirements: []
|
|
80
|
-
rubygems_version: 4.0.
|
|
80
|
+
rubygems_version: 4.0.12
|
|
81
81
|
specification_version: 4
|
|
82
82
|
summary: Yabeda plugin for exporting GVL metrics collected by gvl_metrics_middleware.
|
|
83
83
|
test_files: []
|