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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0dda5e5202f1bb5e509fad032de8449c5d8e9eec78c0cedcd0a59d20cc4f0d32
4
- data.tar.gz: ebccb551ba5dcfd23c1dc2e668d417f59fb1d76f06522e02c352cea1f5e0dca5
3
+ metadata.gz: 136074682007e1265cd41d0d71fae7c1be18edc71edf881e82f14521391aa3bc
4
+ data.tar.gz: 8ab4e7116c77e72a60cda99934564124184aa1489f2ea04d5f49510293808d03
5
5
  SHA512:
6
- metadata.gz: f6ab1b5432bf79341efabb50d0d3d1862dafa49523bbbc8f70ea718eb520d258b7c216da274f0d184dbeb1737c887ebfb19f04fbcc656e8fd39c6a0e057d6346
7
- data.tar.gz: c2e8aa9a3b35a1ea4d557a47be04810c69e79de50a0297593388f90c1be48f8a144a281ad3d26a6c42c4564ba608d6ded064ba53b12f5f49279ddefa940e049c
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 ≥ 3.5 make sure `ostruct` is in the bundle (Rack 2.2 requires it
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.0
1
+ 0.3.2
@@ -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); when given the Redis provider is added. Omit
41
- # entirely (or pass nil) on hosts with no Redis dependency to get
42
- # a database + cache only endpoint.
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'
@@ -43,10 +43,16 @@ module RailsPodKit
43
43
  puma_config.plugin :yabeda
44
44
  puma_config.plugin :yabeda_prometheus
45
45
 
46
- # Silence the exporter's per-scrape access log. The `prometheus_silence_logger`
47
- # DSL method is defined by the :yabeda_prometheus plugin, so this must run
48
- # after the plugin is loaded above. See Config#silence_exporter_access_log.
49
- puma_config.prometheus_silence_logger(true) if RailsPodKit.config.silence_exporter_access_log
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). Must run before
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.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_pod_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabio Napoleoni