logbrew-sdk 0.1.9 → 0.1.11
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 +19 -4
- data/lib/logbrew/http_client_tracing.rb +34 -28
- data/lib/logbrew/rails.rb +1 -0
- data/lib/logbrew/rails_integration.rb +24 -0
- data/lib/logbrew/version.rb +1 -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: e4d8cebbc9fcb274134dda84b6de6b086a4dc6cdc119b80f02c3458624ca1587
|
|
4
|
+
data.tar.gz: c35a55684af97f05ef24f3626412f471c12af7cef0bcc7468430393dfbfccfdd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e9f385c563b7de3bd38294d83e5aa9b3e72c57efb21cf6b22c59de8c5c0328d3a117dbbbee2bf42a91a36d98d97ece63afb2997661968a902f525c932351e5de
|
|
7
|
+
data.tar.gz: ae840cec0095218353192f4af76c00b4ec80707e4bc208c03ba6ae654e2c98158c2af8c198d68e1d279a84df944382e654312a599d7311cd8ad4a6eb519e8d8a
|
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<img src="https://raw.githubusercontent.com/LogBrewCo/sdk/main/assets/brand/logbrew-logo-transparent-512.png" alt="LogBrew logo" width="96" height="96">
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
Public Ruby SDK for building, validating, previewing, and flushing LogBrew event batches, with automatic Rails request, database, cache, view, error, and
|
|
7
|
+
Public Ruby SDK for building, validating, previewing, and flushing LogBrew event batches, with automatic Rails request, database, cache, view, error, ActiveJob, and outbound `Net::HTTP` capture; standard-library delivery; opt-in standard-library `Logger` support; and manual Rack helpers.
|
|
8
8
|
|
|
9
9
|
The core package has no runtime gem dependencies. Its automatic integration
|
|
10
10
|
activates only inside an application that has already loaded Rails.
|
|
@@ -23,7 +23,7 @@ needed:
|
|
|
23
23
|
|
|
24
24
|
```ruby
|
|
25
25
|
# Gemfile
|
|
26
|
-
gem "logbrew-sdk", "~> 0.1.
|
|
26
|
+
gem "logbrew-sdk", "~> 0.1.11"
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
```bash
|
|
@@ -65,6 +65,11 @@ arguments, serialized payloads, exception messages, or raw backtraces by
|
|
|
65
65
|
default. When ActiveJob uses LogBrew's Sidekiq middleware, the inner carrier
|
|
66
66
|
suppresses duplicate Sidekiq spans and issues.
|
|
67
67
|
|
|
68
|
+
Outbound `Net::HTTP` calls made inside an active Rails request or job trace also
|
|
69
|
+
need no initializer. They propagate one W3C child and record only method,
|
|
70
|
+
normalized host, status, duration, adapter source, sampled state, and exception
|
|
71
|
+
type. Calls outside an active trace remain exact pass-throughs.
|
|
72
|
+
|
|
68
73
|
The explicit Rails capture settings are:
|
|
69
74
|
|
|
70
75
|
| Environment variable | Default | Purpose |
|
|
@@ -427,7 +432,9 @@ end
|
|
|
427
432
|
|
|
428
433
|
## Outbound HTTP Tracing
|
|
429
434
|
|
|
430
|
-
|
|
435
|
+
The enabled Rails integration captures `Net::HTTP` automatically while a
|
|
436
|
+
LogBrew trace is active. Outside Rails, wrap an app-owned connection explicitly
|
|
437
|
+
when outbound work should become a child of the active trace:
|
|
431
438
|
|
|
432
439
|
```ruby
|
|
433
440
|
uri = URI("https://service.example/health")
|
|
@@ -452,7 +459,15 @@ connection = Faraday.new("https://service.example") do |builder|
|
|
|
452
459
|
end
|
|
453
460
|
```
|
|
454
461
|
|
|
455
|
-
Both adapters are literal pass-throughs when `LogBrew::Trace.current`
|
|
462
|
+
Both explicit adapters are literal pass-throughs when `LogBrew::Trace.current`
|
|
463
|
+
is absent. With an active parent, explicit adapters and automatic Rails
|
|
464
|
+
`Net::HTTP` capture propagate one W3C `traceparent`, return caller-visible
|
|
465
|
+
header and trace state, and capture one completion span per actual execution.
|
|
466
|
+
Duplicate wrappers, nested LogBrew HTTP middleware, and SDK delivery are
|
|
467
|
+
suppressed. Outside an enabled Rails process, the SDK does not patch
|
|
468
|
+
`Net::HTTP`. Start blocks, response streaming, Faraday middleware ordering,
|
|
469
|
+
responses, and exceptions retain normal behavior; capture failures are
|
|
470
|
+
advisory.
|
|
456
471
|
|
|
457
472
|
Outbound HTTP spans allow only method, normalized host, status code, duration, adapter source, sampled state, and exception type. They never record scheme, port, path, query, fragment, full URL, request or response headers, bodies or sizes, exception messages or stacks, authentication material, cookies, baggage, tracestate, resolved addresses, or arbitrary request options.
|
|
458
473
|
|
|
@@ -19,6 +19,7 @@ module LogBrew
|
|
|
19
19
|
@method = HttpClientTracing.normalize_method(method)
|
|
20
20
|
@host = HttpClientTracing.normalize_host(host)
|
|
21
21
|
@on_capture_error = on_capture_error
|
|
22
|
+
@timestamp = Time.now.utc.iso8601(6)
|
|
22
23
|
@started_at = HttpClientTracing.monotonic_time
|
|
23
24
|
@mutex = Mutex.new
|
|
24
25
|
@finished = false
|
|
@@ -60,7 +61,7 @@ module LogBrew
|
|
|
60
61
|
|
|
61
62
|
@client.span(
|
|
62
63
|
"ruby_http_span_#{@context.span_id}",
|
|
63
|
-
|
|
64
|
+
@timestamp,
|
|
64
65
|
{
|
|
65
66
|
name: "http.client:#{@method}",
|
|
66
67
|
traceId: @context.trace_id,
|
|
@@ -86,35 +87,12 @@ module LogBrew
|
|
|
86
87
|
end
|
|
87
88
|
|
|
88
89
|
def request(request, body = nil, &block)
|
|
89
|
-
|
|
90
|
+
HttpClientTracing.capture_net_http(
|
|
91
|
+
@http,
|
|
92
|
+
request,
|
|
90
93
|
client: @client,
|
|
91
|
-
source: "net_http",
|
|
92
94
|
on_capture_error: @on_capture_error
|
|
93
|
-
)
|
|
94
|
-
[request.method, address, HttpClientTracing::NetHttpHeaderSnapshot.new(request)]
|
|
95
|
-
end
|
|
96
|
-
return @http.request(request, body, &block) unless prepared
|
|
97
|
-
|
|
98
|
-
operation, header = prepared
|
|
99
|
-
begin
|
|
100
|
-
header.inject(operation.traceparent)
|
|
101
|
-
rescue StandardError => error
|
|
102
|
-
operation.capture_error(error)
|
|
103
|
-
HttpClientTracing.reset_header(header, operation)
|
|
104
|
-
return @http.request(request, body, &block)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
response = nil
|
|
108
|
-
begin
|
|
109
|
-
response = operation.around { @http.request(request, body, &block) }
|
|
110
|
-
rescue StandardError => error
|
|
111
|
-
operation.finish(error: error)
|
|
112
|
-
raise
|
|
113
|
-
ensure
|
|
114
|
-
HttpClientTracing.reset_header(header, operation)
|
|
115
|
-
end
|
|
116
|
-
operation.finish(status_code: HttpClientTracing.read_status(response, :code, operation))
|
|
117
|
-
response
|
|
95
|
+
) { @http.request(request, body, &block) }
|
|
118
96
|
end
|
|
119
97
|
|
|
120
98
|
def start(*arguments)
|
|
@@ -187,6 +165,34 @@ module LogBrew
|
|
|
187
165
|
NetHttpTracingClient.new(http, client: client, on_capture_error: on_capture_error)
|
|
188
166
|
end
|
|
189
167
|
|
|
168
|
+
def capture_net_http(http, request, client:, on_capture_error: nil)
|
|
169
|
+
prepared = prepare(client: client, source: "net_http", on_capture_error: on_capture_error) do
|
|
170
|
+
[request.method, http.address, NetHttpHeaderSnapshot.new(request)]
|
|
171
|
+
end
|
|
172
|
+
return yield unless prepared
|
|
173
|
+
|
|
174
|
+
operation, header = prepared
|
|
175
|
+
begin
|
|
176
|
+
header.inject(operation.traceparent)
|
|
177
|
+
rescue StandardError => error
|
|
178
|
+
operation.capture_error(error)
|
|
179
|
+
reset_header(header, operation)
|
|
180
|
+
return yield
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
response = nil
|
|
184
|
+
begin
|
|
185
|
+
response = operation.around { yield }
|
|
186
|
+
rescue StandardError => error
|
|
187
|
+
operation.finish(error: error)
|
|
188
|
+
raise
|
|
189
|
+
ensure
|
|
190
|
+
reset_header(header, operation)
|
|
191
|
+
end
|
|
192
|
+
operation.finish(status_code: read_status(response, :code, operation))
|
|
193
|
+
response
|
|
194
|
+
end
|
|
195
|
+
|
|
190
196
|
def prepare(client:, source:, on_capture_error: nil)
|
|
191
197
|
parent = Trace.current
|
|
192
198
|
return nil unless parent
|
data/lib/logbrew/rails.rb
CHANGED
|
@@ -77,6 +77,7 @@ module LogBrew
|
|
|
77
77
|
runtime = LogBrew::Rails.install(application: application)
|
|
78
78
|
if runtime.configuration.enabled?
|
|
79
79
|
LogBrew::Rails.const_get(:RequestOperations).install(::ActiveSupport::Notifications)
|
|
80
|
+
LogBrew::Rails.const_get(:OutboundHttp).install
|
|
80
81
|
end
|
|
81
82
|
::ActiveSupport.on_load(:active_job) do
|
|
82
83
|
prepend LogBrew::Rails::ActiveJobExtension unless ancestors.include?(LogBrew::Rails::ActiveJobExtension)
|
|
@@ -398,6 +398,30 @@ module LogBrew
|
|
|
398
398
|
end
|
|
399
399
|
end
|
|
400
400
|
|
|
401
|
+
# Adds bounded child spans to Net::HTTP calls made inside an active Rails trace.
|
|
402
|
+
module OutboundHttp
|
|
403
|
+
module Request
|
|
404
|
+
def request(request, body = nil, &block)
|
|
405
|
+
runtime = LogBrew::Rails.runtime
|
|
406
|
+
client = LogBrew::Trace.current && runtime&.client
|
|
407
|
+
return super unless client
|
|
408
|
+
|
|
409
|
+
LogBrew::HttpClientTracing.capture_net_http(
|
|
410
|
+
self,
|
|
411
|
+
request,
|
|
412
|
+
client: client,
|
|
413
|
+
on_capture_error: ->(error) { runtime.report_error("outbound_http_capture", error) }
|
|
414
|
+
) { super(request, body, &block) }
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
module_function
|
|
419
|
+
|
|
420
|
+
def install
|
|
421
|
+
Net::HTTP.prepend(Request) unless Net::HTTP.ancestors.include?(Request)
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
|
|
401
425
|
# One privacy-bounded producer or worker operation for ActiveJob.
|
|
402
426
|
class ActiveJobOperation
|
|
403
427
|
attr_reader :context
|
data/lib/logbrew/version.rb
CHANGED