puma-plugin-telemetry 1.1.6 → 1.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/.rubocop.yml +4 -0
- data/CHANGELOG.md +17 -0
- data/README.md +50 -9
- data/lib/puma/plugin/telemetry/config.rb +13 -2
- data/lib/puma/plugin/telemetry/formatters/json_formatter.rb +18 -0
- data/lib/puma/plugin/telemetry/formatters/passthrough_formatter.rb +16 -0
- data/lib/puma/plugin/telemetry/targets/base_formatting_target.rb +38 -0
- data/lib/puma/plugin/telemetry/targets/io_target.rb +9 -24
- data/lib/puma/plugin/telemetry/targets/open_telemetry_target.rb +53 -0
- data/lib/puma/plugin/telemetry/transforms/cloud_watch_transform.rb +21 -0
- data/lib/puma/plugin/telemetry/transforms/passthrough_transform.rb +16 -0
- data/lib/puma/plugin/telemetry/version.rb +1 -1
- data/lib/puma/plugin/telemetry.rb +48 -12
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 967086816efd56c3d2237c21240a41fcc0a7fa28314fc181d4afcd570337ea0c
|
|
4
|
+
data.tar.gz: e2dd1fdb9ad91c1e07c22304292492fc68b0450c7ef498851f64a067f872b84a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ffe1e2dba8e463969b8ec987170f233678924ffcf69a6a8d54febe499be623495a95b87326e20bb860745a2842bc2e2fab0a43b03588ad0de75a1711558404e8
|
|
7
|
+
data.tar.gz: c6d86543aaf25ae6768c10b3c68d8511ab1089a6bb9cb6c60f0a67c38d0f57f1387ff21b8be1a784615e0779a4132d09cd6cf05a5eeeae2424986dd2f72f5a57
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- New `:open_telemetry` target. Metric names get the `puma` prefix by default. Requires the `opentelemetry-metrics-sdk` gem in the consumer project (#30)
|
|
14
|
+
- New `formatter:` options for the IO target: `:json` and `:passthrough` (#25)
|
|
15
|
+
- New `transform:` options for the IO target: `:cloud_watch` and `:passthrough` (#25)
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- A custom `formatter:` on the IO target now receives the transformed telemetry. Pass `transform: :passthrough` to get the same telemetry as before (#25)
|
|
19
|
+
|
|
20
|
+
### Dropped
|
|
21
|
+
- The `Targets::IOTarget::JSONFormatter` constant. Its behavior moved to `Formatters::JSONFormatter` and `Transforms::CloudWatchTransform` (#25)
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- Stop the telemetry runner when puma shuts down or when the target IO stream is closed. This prevents `IOError: closed stream` errors during shutdown (#31, #45)
|
|
25
|
+
- Log target errors with `unknown_error` instead of `error`, so a failed publish does not make puma exit (#31, #45)
|
|
26
|
+
|
|
10
27
|
## [1.1.6]
|
|
11
28
|
|
|
12
29
|
### Changed
|
data/README.md
CHANGED
|
@@ -41,26 +41,67 @@ Puma::Plugin::Telemetry.configure do |config|
|
|
|
41
41
|
end
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
### Basic
|
|
44
|
+
### Basic IO Target
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
A basic I/O target will emit telemetry data to `STDOUT`, formatted in JSON.
|
|
47
47
|
|
|
48
48
|
```ruby
|
|
49
|
-
|
|
49
|
+
config.add_target :io
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
#### Options
|
|
53
|
+
|
|
54
|
+
This target has configurable `formatter:` and `transform:` options.
|
|
55
|
+
The `formatter:` options are
|
|
56
|
+
|
|
57
|
+
* `:json` _(default)_ - Print the logs in JSON.
|
|
58
|
+
* `:passthrough` - A passthrough formatter which returns the telemetry `Hash` unaltered, passing it directly to the `io:` instance.
|
|
59
|
+
|
|
60
|
+
The `transform:` options are
|
|
61
|
+
|
|
62
|
+
* `:cloud_watch` _(default)_ - Transforms telemetry keys, replacing dots with dashes to support AWS CloudWatch Log Metrics filters.
|
|
63
|
+
* `:passthrough` - A passthrough transform which returns the telemetry `Hash` unaltered.
|
|
64
|
+
|
|
52
65
|
### Datadog StatsD target
|
|
53
66
|
|
|
54
|
-
|
|
67
|
+
A target for the Datadog StatsD client, that uses batch operation to publish metrics.
|
|
55
68
|
|
|
56
|
-
**NOTE**
|
|
69
|
+
**NOTE** This target requires the `dogstatsd-ruby` gem in your project:
|
|
57
70
|
|
|
58
71
|
```ruby
|
|
59
|
-
|
|
72
|
+
gem "dogstatsd-ruby"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
config.add_target :dogstatsd, client: Datadog::Statsd.new
|
|
60
77
|
```
|
|
61
78
|
|
|
62
79
|
You can provide all the tags, namespaces, and other configuration options as always to `Datadog::Statsd.new` method.
|
|
63
80
|
|
|
81
|
+
### OpenTelemetry target
|
|
82
|
+
|
|
83
|
+
A target for the OpenTelemetry Metrics SDK, that uses batch operations to publish metrics.
|
|
84
|
+
|
|
85
|
+
**NOTE** This target requires the `opentelemetry-metrics-sdk` gem in your project:
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
gem "opentelemetry-metrics-sdk"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
config.add_target :open_telemetry, meter_provider: OpenTelemetry.meter_provider
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This target supports the following options:
|
|
96
|
+
|
|
97
|
+
| Option | Description | Default | Required |
|
|
98
|
+
|----------------|----------------------------------------------------------------------------------------------------------------------------------------|---------|----------|
|
|
99
|
+
| meter_provider | The meter provider used to create instruments, e.g. `OpenTelemetry.meter_provider` | - | Yes |
|
|
100
|
+
| prefix | Metric name prefix. <br> ex) prefix: 'web' => 'web.workers.booted'. Pass `nil` for no prefix | 'puma' | No |
|
|
101
|
+
| suffix | Metric name suffix. <br> ex) suffix: 'v1' => 'workers.booted.v1' | nil | No |
|
|
102
|
+
| attributes | Attributes to be included with the metric | {} | No |
|
|
103
|
+
| force_flush | Force flush the meter provider after each publish, so all values are exported, not only the last aggregated one. Can impact performance | false | No |
|
|
104
|
+
|
|
64
105
|
### All available options
|
|
65
106
|
|
|
66
107
|
For detailed documentation checkout [`Puma::Plugin::Telemetry::Config`](./lib/puma/plugin/telemetry/config.rb) class.
|
|
@@ -73,7 +114,7 @@ Puma::Plugin::Telemetry.configure do |config|
|
|
|
73
114
|
config.puma_telemetry = %w[workers.requests_count queue.backlog queue.capacity]
|
|
74
115
|
config.socket_telemetry!
|
|
75
116
|
config.socket_parser = :inspect
|
|
76
|
-
config.add_target :io, formatter: :json,
|
|
117
|
+
config.add_target :io, io: StringIO.new, formatter: :json, transform: :passthrough
|
|
77
118
|
config.add_target :dogstatsd, client: Datadog::Statsd.new(tags: { env: ENV["RAILS_ENV"] })
|
|
78
119
|
end
|
|
79
120
|
```
|
|
@@ -85,8 +126,8 @@ Target is a simple object that implements `call` methods that accepts `telemetry
|
|
|
85
126
|
Just be mindful that if the API takes long to call, it will slow down frequency with which telemetry will get reported.
|
|
86
127
|
|
|
87
128
|
```ruby
|
|
88
|
-
# Example
|
|
89
|
-
config.add_target
|
|
129
|
+
# Example key/value log to `STDOUT` target
|
|
130
|
+
config.add_target ->(telemetry) { puts telemetry.map { |k, v| "#{k}=#{v.inspect}" }.join(" ") }
|
|
90
131
|
```
|
|
91
132
|
|
|
92
133
|
## Extra middleware
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'socket'
|
|
4
|
+
|
|
3
5
|
module Puma
|
|
4
6
|
class Plugin
|
|
5
7
|
module Telemetry
|
|
@@ -32,7 +34,8 @@ module Puma
|
|
|
32
34
|
|
|
33
35
|
TARGETS = {
|
|
34
36
|
dogstatsd: Telemetry::Targets::DatadogStatsdTarget,
|
|
35
|
-
io: Telemetry::Targets::IOTarget
|
|
37
|
+
io: Telemetry::Targets::IOTarget,
|
|
38
|
+
open_telemetry: Telemetry::Targets::OpenTelemetryTarget
|
|
36
39
|
}.freeze
|
|
37
40
|
|
|
38
41
|
# Whenever telemetry should run with puma
|
|
@@ -91,7 +94,15 @@ module Puma
|
|
|
91
94
|
end
|
|
92
95
|
|
|
93
96
|
def socket_telemetry!
|
|
94
|
-
|
|
97
|
+
# These structs are platform specific, and not available on macOS,
|
|
98
|
+
# for example. If they're undefined, then we cannot capture socket
|
|
99
|
+
# telemetry. We'll warn in that case.
|
|
100
|
+
if defined?(Socket::SOL_TCP) && defined?(Socket::TCP_INFO)
|
|
101
|
+
@socket_telemetry = true
|
|
102
|
+
else
|
|
103
|
+
@socket_telemetry = false
|
|
104
|
+
warn("Cannot capture socket telemetry on this platform (#{RUBY_PLATFORM}); socket_telemetry is disabled.")
|
|
105
|
+
end
|
|
95
106
|
end
|
|
96
107
|
|
|
97
108
|
def socket_telemetry?
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Puma
|
|
6
|
+
class Plugin
|
|
7
|
+
module Telemetry
|
|
8
|
+
module Formatters
|
|
9
|
+
# JSON formatter, expects `call` method accepting telemetry hash
|
|
10
|
+
class JSONFormatter
|
|
11
|
+
def self.call(telemetry)
|
|
12
|
+
::JSON.dump(telemetry)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Puma
|
|
4
|
+
class Plugin
|
|
5
|
+
module Telemetry
|
|
6
|
+
module Formatters
|
|
7
|
+
# A passthrough formatter - it returns the telemetry Hash it was given
|
|
8
|
+
class PassthroughFormatter
|
|
9
|
+
def self.call(telemetry)
|
|
10
|
+
telemetry
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../formatters/json_formatter'
|
|
4
|
+
require_relative '../formatters/passthrough_formatter'
|
|
5
|
+
require_relative '../transforms/cloud_watch_transform'
|
|
6
|
+
require_relative '../transforms/passthrough_transform'
|
|
7
|
+
|
|
8
|
+
module Puma
|
|
9
|
+
class Plugin
|
|
10
|
+
module Telemetry
|
|
11
|
+
module Targets
|
|
12
|
+
# A base class for other Targets concerned with formatting telemetry
|
|
13
|
+
class BaseFormattingTarget
|
|
14
|
+
def initialize(formatter: :json, transform: :cloud_watch)
|
|
15
|
+
@transform = case transform
|
|
16
|
+
when :cloud_watch then Transforms::CloudWatchTransform
|
|
17
|
+
when :passthrough then Transforms::PassthroughTransform
|
|
18
|
+
else transform
|
|
19
|
+
end
|
|
20
|
+
@formatter = case formatter
|
|
21
|
+
when :json then Formatters::JSONFormatter
|
|
22
|
+
when :passthrough then Formatters::PassthroughFormatter
|
|
23
|
+
else formatter
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def call(_telemetry)
|
|
28
|
+
raise NotImplementedError, "#{__method__} must be implemented by #{self.class.name}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
attr_reader :formatter, :transform
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,40 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require_relative 'base_formatting_target'
|
|
4
4
|
|
|
5
5
|
module Puma
|
|
6
6
|
class Plugin
|
|
7
7
|
module Telemetry
|
|
8
8
|
module Targets
|
|
9
9
|
# Simple IO Target, publishing metrics to STDOUT or logs
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
#
|
|
14
|
-
class JSONFormatter
|
|
15
|
-
# NOTE: Replace dots with dashes for better support of AWS CloudWatch
|
|
16
|
-
# Log Metric filters, as they don't support dots in key names.
|
|
17
|
-
def self.call(telemetry)
|
|
18
|
-
log = telemetry.transform_keys { |k| k.tr('.', '-') }
|
|
19
|
-
|
|
20
|
-
log['name'] = 'Puma::Plugin::Telemetry'
|
|
21
|
-
log['message'] = 'Publish telemetry'
|
|
22
|
-
|
|
23
|
-
::JSON.dump(log)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def initialize(io: $stdout, formatter: :json)
|
|
10
|
+
class IOTarget < BaseFormattingTarget
|
|
11
|
+
def initialize(io: $stdout, formatter: :json, transform: :cloud_watch)
|
|
12
|
+
super(formatter: formatter, transform: transform)
|
|
28
13
|
@io = io
|
|
29
|
-
@formatter = case formatter
|
|
30
|
-
when :json then JSONFormatter
|
|
31
|
-
else formatter
|
|
32
|
-
end
|
|
33
14
|
end
|
|
34
15
|
|
|
35
16
|
def call(telemetry)
|
|
36
|
-
|
|
17
|
+
io.puts(formatter.call(transform.call(telemetry)))
|
|
37
18
|
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
attr_reader :io
|
|
38
23
|
end
|
|
39
24
|
end
|
|
40
25
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Puma
|
|
4
|
+
class Plugin
|
|
5
|
+
module Telemetry
|
|
6
|
+
module Targets
|
|
7
|
+
# Target wrapping OpenTelemetry Metrics client.
|
|
8
|
+
#
|
|
9
|
+
# ## Example
|
|
10
|
+
#
|
|
11
|
+
# require 'opentelemetry-metrics-sdk'
|
|
12
|
+
#
|
|
13
|
+
# OpenTelemetryTarget.new(meter_provider: OpenTelemetry.meter_provider)
|
|
14
|
+
#
|
|
15
|
+
class OpenTelemetryTarget
|
|
16
|
+
def initialize(meter_provider:, prefix: 'puma', suffix: nil, force_flush: false, attributes: {})
|
|
17
|
+
@meter_provider = meter_provider
|
|
18
|
+
@meter = meter_provider.meter('puma.telemetry')
|
|
19
|
+
@prefix = prefix
|
|
20
|
+
@suffix = suffix
|
|
21
|
+
@force_flush = force_flush
|
|
22
|
+
@attributes = attributes
|
|
23
|
+
@instruments = {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# We are using `gauge` metric type, which means that only the last value will get exported
|
|
27
|
+
# since the OpenTelemetry exporter aggregates metrics before sending them.
|
|
28
|
+
#
|
|
29
|
+
# This means that we could publish metrics from here several times
|
|
30
|
+
# before they get flushed from the aggregation thread, and when they
|
|
31
|
+
# do, only the last values will get sent.
|
|
32
|
+
#
|
|
33
|
+
# That's why we provide the option to explicitly call force_flush here, in order to persist
|
|
34
|
+
# all metrics, and not only the most recent ones.
|
|
35
|
+
#
|
|
36
|
+
# Note: Force flushing metrics every time can significantly impact performance
|
|
37
|
+
#
|
|
38
|
+
def call(telemetry)
|
|
39
|
+
telemetry.each do |metric, value|
|
|
40
|
+
instrument(metric).record(value, attributes: @attributes)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
@meter_provider.force_flush if @force_flush
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def instrument(metric)
|
|
47
|
+
@instruments[metric] ||= @meter.create_gauge([@prefix, metric, @suffix].compact.join('.'))
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Puma
|
|
4
|
+
class Plugin
|
|
5
|
+
module Telemetry
|
|
6
|
+
module Transforms
|
|
7
|
+
# Replace dots with dashes for better support of AWS CloudWatch Log
|
|
8
|
+
# Metric filters, as they don't support dots in key names.
|
|
9
|
+
# Expects `call` method accepting telemetry Hash
|
|
10
|
+
class CloudWatchTransform
|
|
11
|
+
def self.call(telemetry)
|
|
12
|
+
telemetry.transform_keys { |k| String(k).tr('.', '-') }.tap do |data|
|
|
13
|
+
data['name'] = 'Puma::Plugin::Telemetry'
|
|
14
|
+
data['message'] = 'Publish telemetry'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Puma
|
|
4
|
+
class Plugin
|
|
5
|
+
module Telemetry
|
|
6
|
+
module Transforms
|
|
7
|
+
# A passthrough transform - it returns the telemetry Hash it was given
|
|
8
|
+
class PassthroughTransform
|
|
9
|
+
def self.call(telemetry)
|
|
10
|
+
telemetry
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -7,6 +7,7 @@ require 'puma/plugin/telemetry/version'
|
|
|
7
7
|
require 'puma/plugin/telemetry/data'
|
|
8
8
|
require 'puma/plugin/telemetry/targets/datadog_statsd_target'
|
|
9
9
|
require 'puma/plugin/telemetry/targets/io_target'
|
|
10
|
+
require 'puma/plugin/telemetry/targets/open_telemetry_target'
|
|
10
11
|
require 'puma/plugin/telemetry/config'
|
|
11
12
|
|
|
12
13
|
module Puma
|
|
@@ -64,6 +65,7 @@ module Puma
|
|
|
64
65
|
module PluginInstanceMethods
|
|
65
66
|
def start(launcher)
|
|
66
67
|
@launcher = launcher
|
|
68
|
+
@stopped = false
|
|
67
69
|
|
|
68
70
|
unless Puma::Plugin::Telemetry.config.enabled?
|
|
69
71
|
log_writer.log 'plugin=telemetry msg="disabled, exiting..."'
|
|
@@ -72,26 +74,27 @@ module Puma
|
|
|
72
74
|
|
|
73
75
|
log_writer.log 'plugin=telemetry msg="enabled, setting up runner..."'
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
sleep Puma::Plugin::Telemetry.config.initial_delay
|
|
77
|
-
run!
|
|
78
|
-
end
|
|
77
|
+
setup_runner
|
|
79
78
|
end
|
|
80
79
|
|
|
81
80
|
def run!
|
|
82
81
|
loop do
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
# Occurs when trying to output to STDOUT while puma is shutting down
|
|
88
|
-
rescue StandardError => e
|
|
89
|
-
log_writer.error "plugin=telemetry err=#{e.class} msg=#{e.message.inspect}"
|
|
90
|
-
ensure
|
|
82
|
+
break if stopped?
|
|
83
|
+
|
|
84
|
+
break unless try_publish
|
|
85
|
+
|
|
91
86
|
sleep Puma::Plugin::Telemetry.config.frequency
|
|
92
87
|
end
|
|
93
88
|
end
|
|
94
89
|
|
|
90
|
+
def stop!
|
|
91
|
+
@stopped = true
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def stopped?
|
|
95
|
+
!!@stopped
|
|
96
|
+
end
|
|
97
|
+
|
|
95
98
|
def call(telemetry)
|
|
96
99
|
Puma::Plugin::Telemetry.config.targets.each do |target|
|
|
97
100
|
target.call(telemetry)
|
|
@@ -100,6 +103,39 @@ module Puma
|
|
|
100
103
|
|
|
101
104
|
private
|
|
102
105
|
|
|
106
|
+
def setup_runner
|
|
107
|
+
@launcher.events.on_stopped { stop! }
|
|
108
|
+
|
|
109
|
+
in_background do
|
|
110
|
+
sleep Puma::Plugin::Telemetry.config.initial_delay
|
|
111
|
+
run!
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def try_publish
|
|
116
|
+
publish
|
|
117
|
+
true
|
|
118
|
+
rescue IOError, Errno::EPIPE
|
|
119
|
+
# Puma closes the IO streams during shutdown, stop publishing
|
|
120
|
+
log_safely 'plugin=telemetry msg="IO stream closed, stopping the runner"'
|
|
121
|
+
false
|
|
122
|
+
rescue StandardError => e
|
|
123
|
+
log_writer.unknown_error(e, nil, 'plugin=telemetry')
|
|
124
|
+
true
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def publish
|
|
128
|
+
log_writer.debug 'plugin=telemetry msg="publish"'
|
|
129
|
+
|
|
130
|
+
call(Puma::Plugin::Telemetry.build(@launcher))
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def log_safely(message)
|
|
134
|
+
log_writer.log(message)
|
|
135
|
+
rescue IOError, Errno::EPIPE
|
|
136
|
+
nil
|
|
137
|
+
end
|
|
138
|
+
|
|
103
139
|
def log_writer
|
|
104
140
|
if Puma::Const::PUMA_VERSION.to_i < 6
|
|
105
141
|
@launcher.events
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: puma-plugin-telemetry
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Leszek Zalewski
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: puma
|
|
@@ -51,8 +51,14 @@ files:
|
|
|
51
51
|
- lib/puma/plugin/telemetry.rb
|
|
52
52
|
- lib/puma/plugin/telemetry/config.rb
|
|
53
53
|
- lib/puma/plugin/telemetry/data.rb
|
|
54
|
+
- lib/puma/plugin/telemetry/formatters/json_formatter.rb
|
|
55
|
+
- lib/puma/plugin/telemetry/formatters/passthrough_formatter.rb
|
|
56
|
+
- lib/puma/plugin/telemetry/targets/base_formatting_target.rb
|
|
54
57
|
- lib/puma/plugin/telemetry/targets/datadog_statsd_target.rb
|
|
55
58
|
- lib/puma/plugin/telemetry/targets/io_target.rb
|
|
59
|
+
- lib/puma/plugin/telemetry/targets/open_telemetry_target.rb
|
|
60
|
+
- lib/puma/plugin/telemetry/transforms/cloud_watch_transform.rb
|
|
61
|
+
- lib/puma/plugin/telemetry/transforms/passthrough_transform.rb
|
|
56
62
|
- lib/puma/plugin/telemetry/version.rb
|
|
57
63
|
- lib/rack/request_queue_time_middleware.rb
|
|
58
64
|
- puma-plugin-telemetry.gemspec
|