puma-plugin-telemetry_too 0.0.1.alpha3 → 0.0.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: a3826bccd50a4b4366c876ed3d9fe7ce0d75e66a038e11463da80ee2878087cc
4
- data.tar.gz: c1203228b7dbab1717f7a8061b63e95df64c98498dadfbbac493de89e7b80214
3
+ metadata.gz: bc86aadc264e046c25033d4c9a35b2c275fa49214ee1eff287101251454b0f98
4
+ data.tar.gz: fe40cce9b6b4df9c9d51b44fd4b00a03654050fc5283f3eb24df049254bf08d6
5
5
  SHA512:
6
- metadata.gz: 3f6d2a4a638084d7d15bc0466c299305f06268205a47b35eec337edf7364cefce9a86bf17d98f1bda87c921f2d7d256683f405e30097d7b8ad4e0e7c1d1d6ac0
7
- data.tar.gz: d7ba1f825881507ff547408c2d019a3d7b59b9efc39c5343e4ec3ad28d9e82fea8ee0213e2808b28585b847dbe88deb4ddbe83278f9db5f68a01021fd3af6de3
6
+ metadata.gz: a0c0fa9db9c0453773f9f240338df4989d2c5ad7703a17bc9093a3e0bdfbd2a6be1aa983cee00df6ea8ae284f70244e422be1e5750f0ec79fbde10c366bfd584
7
+ data.tar.gz: 5ca8438972313be19086b03e610c898e09f7d66b2bdfaff6e23e3aee294978060ef71fc1bd145b5725bb88975f5f23900a190c59912d805aa8ff7076cf59bea3
data/.rubocop.yml CHANGED
@@ -1,5 +1,4 @@
1
- require:
2
- - rubocop-performance
1
+ plugins: rubocop-performance
3
2
 
4
3
  AllCops:
5
4
  TargetRubyVersion: 3.2
data/CHANGELOG.md CHANGED
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
14
  - Introduce new `formatter:` options: `:json` and `:passthrough`
15
15
  - Introduce new `transform:` options: `:cloud_watch` and `:passthrough`
16
16
  - Introduce new `LogTarget` for logging metrics to any `::Logger` compatible logger
17
+ - Introduce new `OpenTelemetryTarget` for sending metrics via OpenTelemetry Metrics
17
18
  - Support for Puma 7
18
19
 
19
20
  ## [1.1.4] 2025-05-29
data/README.md CHANGED
@@ -4,6 +4,7 @@ NOTE: This is a fork of `puma-plugin-telemetry`, modified to:
4
4
 
5
5
  - Support Puma 7
6
6
  - Add `LogTarget`, with custom `formatter:` and `transform:` options
7
+ - Add `OpenTelemetry` target
7
8
  - Warn about socket telemetry on unsupported platforms
8
9
 
9
10
  Puma plugin which should be able to handle all your metric needs regarding your webserver:
@@ -15,7 +16,7 @@ Puma plugin which should be able to handle all your metric needs regarding your
15
16
 
16
17
  ## Install
17
18
 
18
- Add this line to your application's Gemfile:
19
+ Add this line to your application's `Gemfile`:
19
20
 
20
21
  ```ruby
21
22
  gem "puma-plugin-telemetry_too"
@@ -38,7 +39,7 @@ $ gem install puma-plugin-telemetry_too
38
39
  In your puma configuration file (i.e. `config/puma.rb` or `config/puma/<env>.rb`):
39
40
 
40
41
  ```ruby
41
- plugin "telemetry"
42
+ plugin "telemetry_too"
42
43
 
43
44
  Puma::Plugin::TelemetryToo.configure do |config|
44
45
  config.enabled = true
@@ -98,14 +99,30 @@ The `LogTarget` defaults to `formatter: :logfmt`, and `transform: :passthrough`.
98
99
 
99
100
  A target for the Datadog StatsD client, that uses batch operation to publish metrics.
100
101
 
101
- **NOTE** Be sure to have the `dogstatsd` gem installed.
102
-
103
102
  ```ruby
104
103
  config.add_target(:dogstatsd, client: Datadog::Statsd.new)
105
104
  ```
106
105
 
107
106
  You can provide all the tags, namespaces, and other configuration options as always to `Datadog::Statsd.new` method.
108
107
 
108
+ ### OpenTelemetry target
109
+
110
+ A target for the OpenTelemetry Metrics API, which uses batch operations to publish metrics.
111
+
112
+ ```ruby
113
+ config.add_target :open_telemetry, meter_provider: OpenTelemetry.meter_provider
114
+ ```
115
+
116
+ This target supports the following options:
117
+
118
+ | Option | Description | Default | Required |
119
+ |----------------|-----------------------------------------------------------------------|--------------------------------|----------|
120
+ | meter_provider | An instance of `OpenTelemetry::Metrics::MeterProvider` | `OpenTelemetry.meter_provider` | No |
121
+ | force_flush | Force-flush metrics after each call. <i>This can be expensive!</i> | `false` | No |
122
+ | prefix | Metric name prefix.<br>e.g. `prefix: "app"` → `app.workers.booted` | `puma` | No |
123
+ | suffix | Metric name suffix.<br>e.g. `suffix: "v1"` → `puma.workers.booted.v1` | `nil` | No |
124
+ | attributes | Attributes to be included with the metric | `{}` | No |
125
+
109
126
  ### All available options
110
127
 
111
128
  For detailed documentation checkout [`Puma::Plugin::TelemetryToo::Config`](./lib/puma/plugin/telemetry_too/config.rb) class.
@@ -130,8 +147,8 @@ Target is a simple object that implements `call` methods that accepts `telemetry
130
147
  Just be mindful that if the API takes long to call, it will slow down frequency with which telemetry will get reported.
131
148
 
132
149
  ```ruby
133
- # Example key/value log to `STDOUT` target
134
- config.add_target ->(telemetry) { puts telemetry.map { |k, v| "#{k}=#{v.inspect}" }.join(" ") }
150
+ # Example key/value log to `STDOUT` target
151
+ config.add_target ->(telemetry) { puts telemetry.map { |k, v| "#{k}=#{v.inspect}" }.join(" ") }
135
152
  ```
136
153
 
137
154
  ## Extra middleware
@@ -44,6 +44,7 @@ module Puma
44
44
  TARGETS = {
45
45
  dogstatsd: TelemetryToo::Targets::DatadogStatsdTarget,
46
46
  io: TelemetryToo::Targets::IOTarget,
47
+ open_telemetry: TelemetryToo::Targets::OpenTelemetryTarget,
47
48
  log: TelemetryToo::Targets::LogTarget
48
49
  }.freeze
49
50
 
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Puma
4
+ class Plugin
5
+ module TelemetryToo
6
+ module Targets
7
+ # Target wrapping OpenTelemetry Metrics client.
8
+ #
9
+ # This uses the `gauge` metric type which only exports the last value because
10
+ # the OpenTelemetry exporter aggregates metrics before sending them. Meaning
11
+ # metrics could be published several times before they are flushed via aggregation
12
+ # thread. And when flushed, the last values will be sent.
13
+ #
14
+ # If you need to persist all metrics, you can enable the `force_flush` option.
15
+ # However, force-flushing metrics every time can significantly impact performance.
16
+ #
17
+ # ## Example
18
+ #
19
+ # require 'opentelemetry-metrics-sdk'
20
+ #
21
+ # OpenTelemetryTarget.new(meter_provider: OpenTelemetry.meter_provider, prefix: 'webserver')
22
+ class OpenTelemetryTarget
23
+ def initialize(meter_provider: ::OpenTelemetry.meter_provider, prefix: 'puma', suffix: nil,
24
+ force_flush: false, attributes: {})
25
+ @meter_provider = meter_provider
26
+ @meter = meter_provider.meter('puma.telemetry')
27
+ @prefix = prefix
28
+ @suffix = suffix
29
+ @force_flush = force_flush
30
+ @attributes = attributes
31
+ @instruments = {}
32
+ @mutex = Mutex.new
33
+ end
34
+
35
+ def call(telemetry)
36
+ telemetry.each do |metric, value|
37
+ instrument(metric).record(value, attributes: attributes)
38
+ end
39
+
40
+ meter_provider.force_flush if force_flush?
41
+ end
42
+
43
+ def instrument(metric)
44
+ mutex.synchronize do
45
+ instruments[metric] ||= create_gauge(metric)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :meter_provider, :meter, :prefix, :suffix, :force_flush, :attributes, :instruments, :mutex
52
+
53
+ def create_gauge(metric)
54
+ meta = METADATA.fetch(metric, UNKNOWN_METADATA)
55
+ meter.create_gauge([prefix, metric, suffix].compact.join('.'),
56
+ unit: String(meta.unit), description: String(meta.description))
57
+ end
58
+
59
+ def force_flush?
60
+ !!force_flush
61
+ end
62
+
63
+ Metadata = Data.define(:unit, :description) do
64
+ def initialize(unit:, description: '')
65
+ super
66
+ end
67
+ end
68
+ private_constant :Metadata
69
+
70
+ # rubocop:disable Metrics/LineLength
71
+ METADATA = {
72
+ 'workers.booted' => Metadata[unit: '{process}', description: 'Number of booted Puma workers (processes).'],
73
+ 'workers.total' => Metadata[unit: '{process}', description: 'Total number of Puma workers (processes).'],
74
+ 'workers.spawned_threads' => Metadata[unit: '{thread}', description: 'Number of spawned threads across all Puma workers.'],
75
+ 'workers.max_threads' => Metadata[unit: '{thread}', description: 'Maximum number of threads Puma is configured to spawn, across all workers.'],
76
+ 'workers.requests_count' => Metadata[unit: '{request}', description: 'Total number of requests handled by all Puma workers, since start.'],
77
+ 'queue.backlog' => Metadata[unit: '{request}', description: 'Requests that are waiting for an available thread.'],
78
+ 'queue.backlog_max' => Metadata[unit: '{request}', description: "Maximum number of requests that have been fully buffered by the reactor and placed in a ready queue, but have not yet been picked up by a server thread. This stat is reset on every call, so it's the maximum value observed since the last stat call."],
79
+ 'queue.reactor_max' => Metadata[unit: '{request}', description: "Maximum observed number of requests held in Puma's reactor. This stat is reset on every call, so it's the maximum value observed since the last stat call."],
80
+ 'queue.capacity' => Metadata[unit: '{thread}', description: 'Number of Threads waiting to receive work.'],
81
+ 'sockets.backlog' => Metadata[unit: '{request}', description: 'Number of unacknowledged connections in the Sockets Puma is bound to.']
82
+
83
+ }.freeze
84
+ private_constant :METADATA
85
+ # rubocop:enable Metrics/LineLength
86
+
87
+ UNKNOWN_METADATA = Metadata.new(unit: '1')
88
+ private_constant :UNKNOWN_METADATA
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -3,7 +3,7 @@
3
3
  module Puma
4
4
  class Plugin
5
5
  module TelemetryToo
6
- VERSION = '0.0.1.alpha3'
6
+ VERSION = '0.0.2'
7
7
  end
8
8
  end
9
9
  end
@@ -7,6 +7,7 @@ require 'puma/plugin/telemetry_too/version'
7
7
  require 'puma/plugin/telemetry_too/data'
8
8
  require 'puma/plugin/telemetry_too/targets/datadog_statsd_target'
9
9
  require 'puma/plugin/telemetry_too/targets/io_target'
10
+ require 'puma/plugin/telemetry_too/targets/open_telemetry_target'
10
11
  require 'puma/plugin/telemetry_too/targets/log_target'
11
12
  require 'puma/plugin/telemetry_too/config'
12
13
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma-plugin-telemetry_too
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.alpha3
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leszek Zalewski
@@ -63,6 +63,7 @@ files:
63
63
  - lib/puma/plugin/telemetry_too/targets/datadog_statsd_target.rb
64
64
  - lib/puma/plugin/telemetry_too/targets/io_target.rb
65
65
  - lib/puma/plugin/telemetry_too/targets/log_target.rb
66
+ - lib/puma/plugin/telemetry_too/targets/open_telemetry_target.rb
66
67
  - lib/puma/plugin/telemetry_too/transforms/cloud_watch_transform.rb
67
68
  - lib/puma/plugin/telemetry_too/transforms/l2met_transform.rb
68
69
  - lib/puma/plugin/telemetry_too/transforms/passthrough_transform.rb