foam-otel 3.0.0.alpha.4 → 3.0.0.alpha.5
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 +16 -3
- data/lib/foam/otel/internal/init.rb +4 -0
- data/lib/foam/otel/internal/rails_middleware.rb +58 -0
- data/lib/foam/otel/version.rb +1 -1
- data/lib/foam/otel.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 34ec502fdc38ac38099bba65f1fc37c91f1edb79476bff598c6a0dda7245fcf0
|
|
4
|
+
data.tar.gz: 9596d8c1d746b66103b87587f5c52006e024d0498d93816912ed916014e563e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 85207e2233f8a986bb874f68215960f20216e010978e5d1355808ec2ed6bfb44f19c9b8f8947cc3164cca65864326dab8b5ef95fb8ef6c37a1150fe06923ae2a
|
|
7
|
+
data.tar.gz: 3a3bc463b06b32e1d1bd4b6c439e5f8a92b031859301f8681e78a32e4e1db655ef73d4439a0755e336abc9fc1b068bca48049172046732da4adb514eb12c00cb
|
data/README.md
CHANGED
|
@@ -29,7 +29,20 @@ Store the ingest token as `FOAM_OTEL_TOKEN` and pass `ENV["FOAM_OTEL_TOKEN"]` to
|
|
|
29
29
|
|
|
30
30
|
### Rails
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Create `config/initializers/foam.rb`:
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
Foam.init(
|
|
36
|
+
name: "checkout-api",
|
|
37
|
+
environment: Rails.env,
|
|
38
|
+
enabled: true,
|
|
39
|
+
token: ENV["FOAM_OTEL_TOKEN"]
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
During boot, `init` adds Foam's Rack middleware to the app directly after the OpenTelemetry Rack middleware, so server spans get the same header and body capture as under plain Rack. `init` must run before the app initializes: an initializer file or `config/application.rb`. An `init` from `after_initialize` or later warns on stderr and adds no middleware.
|
|
44
|
+
|
|
45
|
+
Nothing else changes; `config.ru` stays as generated. A `RUBYOPT` preload runs before Rails loads, so it installs no Rails instrumentation and adds no middleware.
|
|
33
46
|
|
|
34
47
|
### Plain Ruby and Rack
|
|
35
48
|
|
|
@@ -372,7 +385,7 @@ There is no option to record other headers.
|
|
|
372
385
|
|
|
373
386
|
### Header capture
|
|
374
387
|
|
|
375
|
-
Server spans get the headers from `Foam::Rack::Middleware`, placed after the OpenTelemetry Rack middleware
|
|
388
|
+
Server spans get the headers from `Foam::Rack::Middleware`, placed after the OpenTelemetry Rack middleware (added by `init` in Rails apps).
|
|
376
389
|
|
|
377
390
|
Client spans get the headers from Foam's hooks on `Net::HTTP`, Excon, HTTPClient, and Faraday, applied unless `network_capture` is `:off`. The `Net::HTTP` hook is always installed; the others install only when their gem is loaded before `init`, and Faraday's covers connections built after `init`. Faraday is covered on the Faraday span whatever the adapter. `http`, `httpx`, `ethon`, and `restclient` are not covered.
|
|
378
391
|
|
|
@@ -392,7 +405,7 @@ In `:advanced` mode each captured body arrives as `foam.http.body.chunk` log rec
|
|
|
392
405
|
|
|
393
406
|
### Rack bodies
|
|
394
407
|
|
|
395
|
-
Server bodies need `Foam::Rack::Middleware` after the OpenTelemetry Rack middleware, as shown under "Plain Ruby and Rack"
|
|
408
|
+
Server bodies need `Foam::Rack::Middleware` after the OpenTelemetry Rack middleware, as shown under "Plain Ruby and Rack" (added by `init` in Rails apps).
|
|
396
409
|
|
|
397
410
|
- The request body is captured whether or not the app reads it when the input is rewindable, as it is under Puma, which buffers request bodies. Otherwise what the app reads is captured.
|
|
398
411
|
- A streamed response is observed as the server sends it, without buffering or delaying it. The records are emitted when the body closes; a stream idle for over 60 seconds is closed as incomplete and the rest is dropped.
|
|
@@ -83,6 +83,10 @@ module Foam
|
|
|
83
83
|
# Foam's logger provider where it flushes the tracer and meter providers.
|
|
84
84
|
Safely.call("aws_lambda") { AwsLambda.install }
|
|
85
85
|
|
|
86
|
+
# A Rails app cannot add the middleware in config.ru the way a plain Rack app does, so
|
|
87
|
+
# Foam adds it through Rails itself.
|
|
88
|
+
Safely.call("rails middleware") { RailsMiddleware.install } unless options[:network_capture] == :off
|
|
89
|
+
|
|
86
90
|
# Recorded last so a failed init leaves the state uninitialized.
|
|
87
91
|
State.record_init(
|
|
88
92
|
providers: providers,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Foam
|
|
4
|
+
module Otel
|
|
5
|
+
module Internal
|
|
6
|
+
# Adds Foam::Rack::Middleware to a Rails app directly after the OpenTelemetry Rack middleware:
|
|
7
|
+
# under it, because Foam reads the server span it opens and needs it open until the response
|
|
8
|
+
# body closes; with nothing in between, so Foam sees the bytes that leave the server.
|
|
9
|
+
# The ActionPack instrumentation inserts that middleware from a before_initialize hook, so Foam
|
|
10
|
+
# uses a before_initialize hook too. Rails runs these hooks in registration order and init
|
|
11
|
+
# registers Foam's after installing ActionPack, so the OpenTelemetry middleware is always in
|
|
12
|
+
# place to anchor on, whether init runs before the app class exists or from config/initializers.
|
|
13
|
+
module RailsMiddleware
|
|
14
|
+
ACTION_PACK = "OpenTelemetry::Instrumentation::ActionPack"
|
|
15
|
+
RACK = "OpenTelemetry::Instrumentation::Rack"
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
def install
|
|
19
|
+
return unless defined?(::Rails::Railtie)
|
|
20
|
+
|
|
21
|
+
# Rails records middleware changes on a proxy until it builds the stack late in
|
|
22
|
+
# initialize! (before the after_initialize hooks).
|
|
23
|
+
if stack_built?
|
|
24
|
+
Diagnostics.warn(
|
|
25
|
+
"init ran after the Rails app built its middleware stack, so Foam's middleware " \
|
|
26
|
+
"was not added; call init from config/initializers"
|
|
27
|
+
)
|
|
28
|
+
return
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# A hook cannot be removed, so an init that rolled back and then succeeded adds one, not two.
|
|
32
|
+
return if @registered
|
|
33
|
+
|
|
34
|
+
@registered = true
|
|
35
|
+
::ActiveSupport.on_load(:before_initialize, yield: true) do |app|
|
|
36
|
+
Safely.call("rails middleware insert") { RailsMiddleware.insert(app) }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def stack_built?
|
|
41
|
+
app = ::Rails.application
|
|
42
|
+
!app.nil? && !app.middleware.is_a?(::Rails::Configuration::MiddlewareStackProxy)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Queues the insert on the app's middleware proxy; Rails applies queued inserts in order when
|
|
46
|
+
# it builds the real stack late in initialize!. Anchored on the OpenTelemetry class, not
|
|
47
|
+
# position 0, so another SDK inserting at the top cannot come between the two.
|
|
48
|
+
def insert(app)
|
|
49
|
+
return unless Instrumentations.instance(ACTION_PACK).installed?
|
|
50
|
+
|
|
51
|
+
otel = Instrumentations.instance(RACK).middleware_args.first
|
|
52
|
+
app.middleware.insert_after(otel, Foam::Rack::Middleware)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/foam/otel/version.rb
CHANGED
data/lib/foam/otel.rb
CHANGED
|
@@ -23,6 +23,7 @@ require_relative "otel/internal/clients/excon"
|
|
|
23
23
|
require_relative "otel/internal/clients/http_client"
|
|
24
24
|
require_relative "otel/internal/clients/faraday"
|
|
25
25
|
require_relative "otel/internal/aws_lambda"
|
|
26
|
+
require_relative "otel/internal/rails_middleware"
|
|
26
27
|
require_relative "otel/internal/before_send"
|
|
27
28
|
require_relative "otel/internal/instrumentations"
|
|
28
29
|
require_relative "otel/internal/ignored_hosts"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foam-otel
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.0.alpha.
|
|
4
|
+
version: 3.0.0.alpha.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Foam
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: opentelemetry-exporter-otlp
|
|
@@ -188,6 +188,7 @@ files:
|
|
|
188
188
|
- lib/foam/otel/internal/propagation.rb
|
|
189
189
|
- lib/foam/otel/internal/rack/body_tee.rb
|
|
190
190
|
- lib/foam/otel/internal/rack/input_tee.rb
|
|
191
|
+
- lib/foam/otel/internal/rails_middleware.rb
|
|
191
192
|
- lib/foam/otel/internal/redactor.rb
|
|
192
193
|
- lib/foam/otel/internal/redactor/keys.rb
|
|
193
194
|
- lib/foam/otel/internal/report.rb
|