rails_pod_kit 0.3.0 → 0.3.2
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 +21 -1
- data/VERSION +1 -1
- data/lib/rails_pod_kit/health.rb +16 -4
- data/lib/rails_pod_kit/puma.rb +10 -4
- data/lib/rails_pod_kit/sidekiq.rb +23 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 136074682007e1265cd41d0d71fae7c1be18edc71edf881e82f14521391aa3bc
|
|
4
|
+
data.tar.gz: 8ab4e7116c77e72a60cda99934564124184aa1489f2ea04d5f49510293808d03
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d73285ade30683bfee3f9a933b31d672dbf04fe2ac604270f49f5394799565f65aaa1bfd1a107af0a4f70b6798d75e5dd3ed295696c79cfc65528696732a32a5
|
|
7
|
+
data.tar.gz: aa042f91445f4bd90b6c6c6e7dbdce8b10e0433293efc9239b61a5046443a6a6967c0c7ad040cccc3b70c927016c1749c3f0d70d302581e5ec8a301684dd3c0a
|
data/README.md
CHANGED
|
@@ -609,9 +609,29 @@ serves `solid_queue_*` and nothing else, so the check config needs no filters.
|
|
|
609
609
|
- **Puma control app.** `yabeda-puma-plugin` reads Puma's thread-pool stats
|
|
610
610
|
through Puma's control app, so `Puma.activate` activates one on a
|
|
611
611
|
localhost-only socket (`no_token: true`, never network-exposed).
|
|
612
|
+
- **`json` 3 needs Rails 8.1.** On ActiveSupport **< 8.1**, json **>= 3** breaks
|
|
613
|
+
*every* `to_json` call in the process, not just this gem's. ActiveSupport up
|
|
614
|
+
to 8.0 encodes with `JSON.generate(..., quirks_mode: true)`; json 3.0 turned
|
|
615
|
+
that unknown keyword from a silent no-op into an `ArgumentError`, and Rails
|
|
616
|
+
dropped the call only in 8.1. The whole ecosystem is pinning `json` to `"< 3"`
|
|
617
|
+
behind a Rails-version guard, and so should a host on 7.2 or 8.0 — the
|
|
618
|
+
appraisals here do exactly that.
|
|
619
|
+
|
|
620
|
+
What is specific to this gem is the *shape* of its symptom. Everywhere else
|
|
621
|
+
the error is loud; in the metrics path it is not. prometheus-client-mmap
|
|
622
|
+
builds each metric's mmap key with `to_json` and catches the failure in
|
|
623
|
+
`UsesValueType#value_object`, logging at INFO before falling back to
|
|
624
|
+
`SimpleValue` — which keeps the value in the recording process instead of the
|
|
625
|
+
shared mmap file. So `/metrics` still answers 200 and the series simply go
|
|
626
|
+
missing. If you are chasing an empty exposition, check this first.
|
|
627
|
+
|
|
628
|
+
Not expressible as a gemspec dependency: it applies only below ActiveSupport
|
|
629
|
+
8.1, and `json < 3` there would hold back Rails 8.1+ hosts, which are fine
|
|
630
|
+
(verified: AS 8.1.3.1 + json 3.0.2 encodes normally).
|
|
631
|
+
|
|
612
632
|
- **Rack version.** Under **Rack 3+** the mmap exporter's WEBrick handler also
|
|
613
633
|
needs the `rackup` gem. Under Rack 2.x `webrick` alone is enough, but on
|
|
614
|
-
Ruby ≥
|
|
634
|
+
Ruby ≥ 4.0 make sure `ostruct` is in the bundle (Rack 2.2 requires it
|
|
615
635
|
without declaring it, and it's no longer a default gem).
|
|
616
636
|
- **Two kinds of entry point.** The main file (`require 'rails_pod_kit'`,
|
|
617
637
|
what Bundler.require loads in a Rails app) pulls in every integration
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.2
|
data/lib/rails_pod_kit/health.rb
CHANGED
|
@@ -36,10 +36,11 @@ module RailsPodKit
|
|
|
36
36
|
# Configures HealthMonitor with the kit's defaults.
|
|
37
37
|
#
|
|
38
38
|
# redis: optional Redis connection options hash (same shape the host
|
|
39
|
-
# passes to Sidekiq) or a ready connection object (Redis
|
|
40
|
-
# ConnectionPool
|
|
41
|
-
#
|
|
42
|
-
#
|
|
39
|
+
# passes to Sidekiq) or a ready connection object (Redis,
|
|
40
|
+
# ConnectionPool, or a ConnectionPool::Wrapper, which is unwrapped
|
|
41
|
+
# to the pool behind it); when given the Redis provider is added.
|
|
42
|
+
# Omit entirely (or pass nil) on hosts with no Redis dependency to
|
|
43
|
+
# get a database + cache only endpoint.
|
|
43
44
|
# path: mount-relative endpoint path (default :healthz).
|
|
44
45
|
# sidekiq: optional thresholds hash; when given the Sidekiq provider is
|
|
45
46
|
# added with the provided `queue_size:` / `latency:` overrides
|
|
@@ -88,6 +89,17 @@ module RailsPodKit
|
|
|
88
89
|
end
|
|
89
90
|
|
|
90
91
|
def build_connection(redis)
|
|
92
|
+
# ConnectionPool::Wrapper is a BasicObject delegator: it defines no
|
|
93
|
+
# predicates of its own, so every `is_a?` on it falls through to
|
|
94
|
+
# method_missing and checks out a real connection. That costs a
|
|
95
|
+
# connection attempt here at boot -- fatal when the broker is down, the
|
|
96
|
+
# very outage a health endpoint exists to report -- and health_monitor's
|
|
97
|
+
# own `is_a?(ConnectionPool)` test misses the wrapper anyway and nests it
|
|
98
|
+
# in a second pool, paying another checkout per command. Hand over the
|
|
99
|
+
# pool it wraps. `respond_to?` is answered from the wrapper's own
|
|
100
|
+
# allowlist without touching the network, and is false for the hash,
|
|
101
|
+
# Redis and ConnectionPool arguments handled below.
|
|
102
|
+
return redis.wrapped_pool if redis.respond_to?(:wrapped_pool)
|
|
91
103
|
return redis unless redis.is_a?(Hash)
|
|
92
104
|
|
|
93
105
|
require 'redis'
|
data/lib/rails_pod_kit/puma.rb
CHANGED
|
@@ -43,10 +43,16 @@ module RailsPodKit
|
|
|
43
43
|
puma_config.plugin :yabeda
|
|
44
44
|
puma_config.plugin :yabeda_prometheus
|
|
45
45
|
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
|
|
46
|
+
# Drop the exporter's per-scrape access log the same way the WEBrick path
|
|
47
|
+
# does (see RailsPodKit::Exporter.start!): the log line comes from the
|
|
48
|
+
# Rack::CommonLogger the exporter's rack app mounts unless this is exactly
|
|
49
|
+
# 'false'. See Config#silence_exporter_access_log.
|
|
50
|
+
#
|
|
51
|
+
# Deliberately not `prometheus_silence_logger(true)`, which is the plugin's
|
|
52
|
+
# own knob: it swaps Puma's whole log writer for LogWriter.null, and that
|
|
53
|
+
# writer also carries the exporter's errors — so a /metrics that raises on
|
|
54
|
+
# every scrape would fail completely silently.
|
|
55
|
+
ENV['PROMETHEUS_EXPORTER_LOG_REQUESTS'] = 'false' if RailsPodKit.config.silence_exporter_access_log
|
|
50
56
|
|
|
51
57
|
# `config/puma.rb` is evaluated before Rails is loaded, so requiring this
|
|
52
58
|
# gem here loads yabeda *before* `defined?(Rails)`, and yabeda's Railtie
|
|
@@ -21,6 +21,8 @@ module RailsPodKit
|
|
|
21
21
|
def install!(sidekiq_config = nil)
|
|
22
22
|
return unless RailsPodKit.enabled?
|
|
23
23
|
|
|
24
|
+
export_policy_env!(collect_cluster_metrics: RailsPodKit.config.sidekiq_global_metrics == :all)
|
|
25
|
+
|
|
24
26
|
require 'yabeda/sidekiq'
|
|
25
27
|
require 'yabeda/prometheus/mmap'
|
|
26
28
|
|
|
@@ -72,9 +74,10 @@ module RailsPodKit
|
|
|
72
74
|
# server — i.e. the web (Puma) process under the :web policy. The web has the
|
|
73
75
|
# Sidekiq client configured (Redis access), so yabeda-sidekiq can read the
|
|
74
76
|
# cluster stats there. We force `collect_cluster_metrics` on and keep
|
|
75
|
-
# `declare_process_metrics` off (the web runs no jobs).
|
|
76
|
-
# Yabeda.configure! so the gauges are declared.
|
|
77
|
+
# `declare_process_metrics` off (the web runs no jobs).
|
|
77
78
|
def enable_global_collection!
|
|
79
|
+
export_policy_env!(collect_cluster_metrics: true, declare_process_metrics: false)
|
|
80
|
+
|
|
78
81
|
require 'yabeda/sidekiq'
|
|
79
82
|
|
|
80
83
|
Yabeda::Sidekiq.config.collect_cluster_metrics = true
|
|
@@ -82,6 +85,24 @@ module RailsPodKit
|
|
|
82
85
|
apply_retries_segmentation!
|
|
83
86
|
end
|
|
84
87
|
|
|
88
|
+
# Publishes the policy through yabeda-sidekiq's own env-backed config, and it
|
|
89
|
+
# has to happen *before* `require 'yabeda/sidekiq'`.
|
|
90
|
+
#
|
|
91
|
+
# yabeda-sidekiq declares its cluster gauges inside its own `Yabeda.configure`
|
|
92
|
+
# block, guarded by `collect_cluster_metrics` — and when Yabeda has already
|
|
93
|
+
# been configured (any host where its Railtie ran first) requiring the file
|
|
94
|
+
# evaluates that block immediately. Assigning the flag afterwards is then too
|
|
95
|
+
# late: the gauges are never declared, while the `collect` block — which reads
|
|
96
|
+
# the same flag on every scrape — starts referencing them, and /metrics 500s
|
|
97
|
+
# with a NameError. The env values are read when the config object is built,
|
|
98
|
+
# so setting them here makes the declaration see the policy whenever the
|
|
99
|
+
# require lands.
|
|
100
|
+
def export_policy_env!(collect_cluster_metrics:, declare_process_metrics: nil)
|
|
101
|
+
ENV['YABEDA_SIDEKIQ_COLLECT_CLUSTER_METRICS'] = collect_cluster_metrics.to_s
|
|
102
|
+
ENV['YABEDA_SIDEKIQ_DECLARE_PROCESS_METRICS'] = declare_process_metrics.to_s unless declare_process_metrics.nil?
|
|
103
|
+
ENV['YABEDA_SIDEKIQ_RETRIES_SEGMENTED_BY_QUEUE'] = RailsPodKit.config.retries_segmented_by_queue.to_s
|
|
104
|
+
end
|
|
105
|
+
|
|
85
106
|
# Starts the background WEBrick exporter shared with the other non-Puma
|
|
86
107
|
# entry points; guarded there so a re-entrant Sidekiq boot can't double-bind
|
|
87
108
|
# the port.
|