bitfab 0.22.1 → 0.23.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/lib/bitfab/client.rb +74 -10
- data/lib/bitfab/http_client.rb +4 -1
- data/lib/bitfab/version.rb +1 -1
- data/lib/bitfab.rb +2 -2
- 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: 26ad3b53b9f3da35c01496ecc236ce0f5d27e7921761c7baca7654d1fb8de31e
|
|
4
|
+
data.tar.gz: e653a93c4bf8e5263b22a6114ebcc2a52db6cc3db6eecc7774cb7b6ed07c51c3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7c31a1ffd2e8be0cd31fd94941479351176823eabeadf453972bd493aeadbbc7de97002f484787a6e009024a42a6ed1e3a8fc99ded4b94eb3fd842d6e03772e9
|
|
7
|
+
data.tar.gz: 01ee591f9c3a51254abc101229ba261bc054acd02bfe7c67471367fd8cb0cc2fa015a1c1affc149358caf7dc5af98c7ea4f5351973153b60c6983befbc4d7ac7
|
data/lib/bitfab/client.rb
CHANGED
|
@@ -20,21 +20,40 @@ module Bitfab
|
|
|
20
20
|
# outputs (which may themselves be nil or false).
|
|
21
21
|
MOCK_REPLAY_MISS = Object.new.freeze
|
|
22
22
|
|
|
23
|
-
attr_reader :
|
|
23
|
+
attr_reader :service_url
|
|
24
24
|
|
|
25
|
-
def initialize(api_key
|
|
26
|
-
@
|
|
25
|
+
def initialize(api_key: nil, service_url: nil, enabled: true, strict: false)
|
|
26
|
+
@api_key_config = api_key
|
|
27
27
|
@service_url = service_url || DEFAULT_SERVICE_URL
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
@
|
|
28
|
+
# The user's on/off intent; effective enabled also requires a resolved key.
|
|
29
|
+
@explicitly_enabled = enabled
|
|
30
|
+
@strict = strict
|
|
31
|
+
# Cached only once a non-empty key is found, so an early resolve (before
|
|
32
|
+
# env loaded) can't poison a later one.
|
|
33
|
+
@resolved_api_key = nil
|
|
34
|
+
@api_key_warned = false
|
|
35
|
+
# The key is NOT read here. HttpClient gets a proc so the key is resolved
|
|
36
|
+
# at send time, after any env loading has run.
|
|
37
|
+
@http_client = HttpClient.new(api_key: -> { resolve_api_key }, service_url: @service_url)
|
|
34
38
|
@pending_span_threads = {}
|
|
35
39
|
@pending_span_mutex = Mutex.new
|
|
36
40
|
end
|
|
37
41
|
|
|
42
|
+
# The configured API key (a proc is resolved on read). Reflects what was
|
|
43
|
+
# passed to the client; the ENV["BITFAB_API_KEY"] fallback applied during
|
|
44
|
+
# actual tracing is not surfaced here, and reading this never warns.
|
|
45
|
+
def api_key
|
|
46
|
+
@api_key_config.respond_to?(:call) ? @api_key_config.call : @api_key_config
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Effective tracing state, evaluated lazily: enabled only when not
|
|
50
|
+
# explicitly disabled AND a key resolves. Reading this resolves the key
|
|
51
|
+
# (and may emit the one-time empty-key warning), exactly as the first traced
|
|
52
|
+
# call would.
|
|
53
|
+
def enabled
|
|
54
|
+
tracing_enabled?
|
|
55
|
+
end
|
|
56
|
+
|
|
38
57
|
# Replay historical traces through a method and create a test run.
|
|
39
58
|
#
|
|
40
59
|
# @param receiver [Object, Class] an instance for instance methods, or a Class for class methods
|
|
@@ -100,7 +119,10 @@ module Bitfab
|
|
|
100
119
|
# Called by Traceable, not intended for direct use.
|
|
101
120
|
def execute_span(trace_function_key:, span_name:, span_type:, function_name:, args:, kwargs:,
|
|
102
121
|
mock_on_replay: false)
|
|
103
|
-
|
|
122
|
+
# Decide at CALL time, not construction. The key may be set after the
|
|
123
|
+
# client is built (env loaded later), so re-checking per call lets a
|
|
124
|
+
# late-resolved key take effect.
|
|
125
|
+
return yield unless tracing_enabled?
|
|
104
126
|
|
|
105
127
|
# Span setup runs before the user's block. Tracing is a side-channel, so
|
|
106
128
|
# if anything here raises (id generation, trace-state bookkeeping, a
|
|
@@ -321,6 +343,48 @@ module Bitfab
|
|
|
321
343
|
|
|
322
344
|
private
|
|
323
345
|
|
|
346
|
+
# Resolve the API key lazily, the first time a span actually needs it.
|
|
347
|
+
#
|
|
348
|
+
# The key is intentionally NOT read at construction: a client built when a
|
|
349
|
+
# file is required can run before the app loads its env, so the key would be
|
|
350
|
+
# empty at construction even though it is set moments later. Resolution
|
|
351
|
+
# order: the configured value (a proc is called while still unresolved),
|
|
352
|
+
# then a fallback read of ENV["BITFAB_API_KEY"]. Once a non-empty key is
|
|
353
|
+
# found it is cached.
|
|
354
|
+
def resolve_api_key
|
|
355
|
+
return @resolved_api_key unless @resolved_api_key.nil?
|
|
356
|
+
|
|
357
|
+
from_config = @api_key_config.respond_to?(:call) ? @api_key_config.call : @api_key_config
|
|
358
|
+
candidate = if from_config && !from_config.to_s.strip.empty?
|
|
359
|
+
from_config
|
|
360
|
+
else
|
|
361
|
+
ENV["BITFAB_API_KEY"]
|
|
362
|
+
end
|
|
363
|
+
key = (candidate && !candidate.to_s.strip.empty?) ? candidate : nil
|
|
364
|
+
if key
|
|
365
|
+
@resolved_api_key = key
|
|
366
|
+
return key
|
|
367
|
+
end
|
|
368
|
+
if @strict
|
|
369
|
+
raise "Bitfab: no API key resolved. Set BITFAB_API_KEY or pass api_key: to " \
|
|
370
|
+
"Bitfab.configure. If a script loads env later, load it before the first " \
|
|
371
|
+
"traced call, or pass api_key: -> { ENV[\"BITFAB_API_KEY\"] }."
|
|
372
|
+
end
|
|
373
|
+
if @explicitly_enabled && !@api_key_warned
|
|
374
|
+
@api_key_warned = true
|
|
375
|
+
warn "Bitfab: api_key is empty: tracing is disabled. Provide a valid API key to enable tracing."
|
|
376
|
+
end
|
|
377
|
+
nil
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
# Whether tracing should run, decided lazily at call time. An explicit
|
|
381
|
+
# `enabled: false` short-circuits without ever touching the key.
|
|
382
|
+
def tracing_enabled?
|
|
383
|
+
return false unless @explicitly_enabled
|
|
384
|
+
|
|
385
|
+
!resolve_api_key.nil?
|
|
386
|
+
end
|
|
387
|
+
|
|
324
388
|
# Build an Enumerator that drives `source`, restoring `[trace_id, span_id]`
|
|
325
389
|
# on the iterating fiber so nested `bitfab_span` calls inside lazy / `each`
|
|
326
390
|
# callbacks nest under the parent span. Yielded values are collected as the
|
data/lib/bitfab/http_client.rb
CHANGED
|
@@ -226,9 +226,12 @@ module Bitfab
|
|
|
226
226
|
end
|
|
227
227
|
|
|
228
228
|
def headers
|
|
229
|
+
# Resolve the key at request time, invoking the proc form if one was
|
|
230
|
+
# supplied (never read at construction).
|
|
231
|
+
key = @api_key.respond_to?(:call) ? @api_key.call : @api_key
|
|
229
232
|
{
|
|
230
233
|
"Content-Type" => "application/json",
|
|
231
|
-
"Authorization" => "Bearer #{
|
|
234
|
+
"Authorization" => "Bearer #{key}"
|
|
232
235
|
}
|
|
233
236
|
end
|
|
234
237
|
end
|
data/lib/bitfab/version.rb
CHANGED
data/lib/bitfab.rb
CHANGED
|
@@ -59,8 +59,8 @@ module Bitfab
|
|
|
59
59
|
# @example
|
|
60
60
|
# Bitfab.configure(api_key: ENV["BITFAB_API_KEY"])
|
|
61
61
|
#
|
|
62
|
-
def configure(api_key
|
|
63
|
-
@client = Client.new(api_key:, service_url:, enabled:)
|
|
62
|
+
def configure(api_key: nil, service_url: nil, enabled: true, strict: false)
|
|
63
|
+
@client = Client.new(api_key:, service_url:, enabled:, strict:)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
# Returns the global client, raising if not configured.
|