foam-otel 1.9.0 → 1.9.1
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 +5 -0
- data/lib/foam/otel/before_send.rb +36 -0
- data/lib/foam/otel/version.rb +12 -1
- 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: a2e506ae900650923638df263e5775efa20dd8ab7a63540eefb9d5156c1d008c
|
|
4
|
+
data.tar.gz: 64ea4091c85c9541ec1f08dd5560608e560ec80e8ee6918f95098b976b0ec82e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4c776696c10dc442394e5b023db7b47d178ec4b328addd693ba72b60e726c19f923533f0f1645e7b62ec322e63d6fcd0b39b1ca917cd9aa66403295c0b67e266
|
|
7
|
+
data.tar.gz: 615ec0ee4400e6e11baa6a6572fcafdccdeb6764f9bb2e65afcf4ff72a8185e9ba45086cd5e8e039934ea1043fe165d94784983539ac0d3e361a6b28f72a986e
|
data/README.md
CHANGED
|
@@ -672,6 +672,11 @@ The per-record contract (Sentry `beforeSend` semantics):
|
|
|
672
672
|
in place, they are shared structures. Foam re-normalizes the record's
|
|
673
673
|
`total_recorded_*` bookkeeping after your hooks run, so adding/deleting
|
|
674
674
|
attributes never corrupts the wire's dropped-count accounting.
|
|
675
|
+
`record.resource` and `record.instrumentation_scope` are **identity, not
|
|
676
|
+
payload**: read them freely, but edits and replacements are discarded —
|
|
677
|
+
the original identity objects always ship (they are process-global and
|
|
678
|
+
the encoder groups by them; a writable resource would also bypass
|
|
679
|
+
redaction, which never masks resource attributes).
|
|
675
680
|
* **return `nil`** → the record is dropped, silently (that is the filter
|
|
676
681
|
mechanism, not an error).
|
|
677
682
|
* **raise, or return a foreign object** → that record is dropped
|
|
@@ -62,6 +62,7 @@ module Foam
|
|
|
62
62
|
# flood an adversary-shaped record stream controls — rule 15's
|
|
63
63
|
# "loud but never a flood" posture).
|
|
64
64
|
def run(hooks, record, signal, faults)
|
|
65
|
+
identity = identity_of(record)
|
|
65
66
|
current, counters = thaw(record)
|
|
66
67
|
hooks.each do |hook|
|
|
67
68
|
result = hook.call(current)
|
|
@@ -74,6 +75,7 @@ module Foam
|
|
|
74
75
|
current = result
|
|
75
76
|
end
|
|
76
77
|
restore_counters!(current, counters)
|
|
78
|
+
restore_identity!(current, identity)
|
|
77
79
|
current
|
|
78
80
|
rescue StandardError, SystemStackError => e
|
|
79
81
|
faults << e.class.name
|
|
@@ -110,9 +112,43 @@ module Foam
|
|
|
110
112
|
copy.attributes = attributes.nil? ? {} : attributes.transform_values { |v| thaw_value(v) }
|
|
111
113
|
end
|
|
112
114
|
copy.body = thaw_body(copy.body) if copy.respond_to?(:body) && copy.respond_to?(:body=)
|
|
115
|
+
# The scope handed to the hook is a COPY: InstrumentationScope is a
|
|
116
|
+
# mutable Struct, and an in-place `scope.name =` on the shared
|
|
117
|
+
# object would corrupt process-global identity (see identity_of).
|
|
118
|
+
if copy.respond_to?(:instrumentation_scope) && copy.respond_to?(:instrumentation_scope=)
|
|
119
|
+
copy.instrumentation_scope = copy.instrumentation_scope&.dup
|
|
120
|
+
end
|
|
113
121
|
[copy, sdk_drop_counters(record)]
|
|
114
122
|
end
|
|
115
123
|
|
|
124
|
+
# resource / instrumentation_scope are process-global IDENTITY objects
|
|
125
|
+
# shared by every record the tracer/logger emits — and Ruby's
|
|
126
|
+
# InstrumentationScope is a plain MUTABLE Struct. A hook that renames
|
|
127
|
+
# the scope would corrupt the identity of EVERY subsequent span/log
|
|
128
|
+
# from that instrument (proven live in the 2026-07-29 retro-probe),
|
|
129
|
+
# and a wholesale `record.resource =` replacement would ship
|
|
130
|
+
# hook-authored resource attributes RAW — redaction never masks
|
|
131
|
+
# resource, so that path could widen what ships. Both are closed the
|
|
132
|
+
# way the Go port does it: identity always comes from the ORIGINAL
|
|
133
|
+
# record — captured here, force-restored onto the survivor after the
|
|
134
|
+
# pipeline (hook edits to identity are discarded; the encoder's
|
|
135
|
+
# group-by-identity stays intact). Documented in the README:
|
|
136
|
+
# resource/instrumentation_scope are informational, not hook-writable.
|
|
137
|
+
def identity_of(record)
|
|
138
|
+
{
|
|
139
|
+
resource: (record.resource if record.respond_to?(:resource)),
|
|
140
|
+
scope: (record.instrumentation_scope if record.respond_to?(:instrumentation_scope)),
|
|
141
|
+
}
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def restore_identity!(record, identity)
|
|
145
|
+
record.resource = identity[:resource] if record.respond_to?(:resource=)
|
|
146
|
+
if record.respond_to?(:instrumentation_scope=)
|
|
147
|
+
record.instrumentation_scope = identity[:scope]
|
|
148
|
+
end
|
|
149
|
+
record
|
|
150
|
+
end
|
|
151
|
+
|
|
116
152
|
def thaw_value(value)
|
|
117
153
|
case value
|
|
118
154
|
when String then value.dup
|
data/lib/foam/otel/version.rb
CHANGED
|
@@ -175,6 +175,17 @@ module Foam
|
|
|
175
175
|
# case) install NOTHING. Proven against the real agents in
|
|
176
176
|
# test-apps/ruby-coexistence (six vendors, both patch mechanisms,
|
|
177
177
|
# patched-client probe REQUIRED green).
|
|
178
|
-
|
|
178
|
+
# 1.9.1: before_send IDENTITY RESTORE (retro-probe class 14; PATCH —
|
|
179
|
+
# bugfix-only). resource / instrumentation_scope are process-global
|
|
180
|
+
# identity objects, and InstrumentationScope is a MUTABLE Struct: a
|
|
181
|
+
# hook renaming it corrupted the identity of every subsequent
|
|
182
|
+
# span/log from that instrument (proven live), and a wholesale
|
|
183
|
+
# `record.resource =` replacement shipped hook-authored resource
|
|
184
|
+
# attributes RAW (redaction never masks resource — the one
|
|
185
|
+
# can-never-widen gap). Hooks now receive a COPIED scope, and the
|
|
186
|
+
# ORIGINAL resource/scope are force-restored onto every survivor
|
|
187
|
+
# after the pipeline (identity is not hook-writable — the Go port's
|
|
188
|
+
# contract; README updated).
|
|
189
|
+
VERSION = "1.9.1"
|
|
179
190
|
end
|
|
180
191
|
end
|