brainzlab 0.1.2 → 0.1.4
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/LICENSE +6 -21
- data/README.md +16 -2
- data/lib/brainzlab/beacon/client.rb +38 -40
- data/lib/brainzlab/beacon/provisioner.rb +1 -1
- data/lib/brainzlab/beacon.rb +15 -15
- data/lib/brainzlab/configuration.rb +112 -90
- data/lib/brainzlab/context.rb +2 -3
- data/lib/brainzlab/cortex/client.rb +29 -31
- data/lib/brainzlab/cortex/provisioner.rb +1 -1
- data/lib/brainzlab/cortex.rb +7 -11
- data/lib/brainzlab/dendrite/client.rb +42 -44
- data/lib/brainzlab/dendrite/provisioner.rb +1 -1
- data/lib/brainzlab/dendrite.rb +4 -4
- data/lib/brainzlab/devtools/data/collector.rb +22 -22
- data/lib/brainzlab/devtools/middleware/asset_server.rb +14 -14
- data/lib/brainzlab/devtools/middleware/database_handler.rb +52 -55
- data/lib/brainzlab/devtools/middleware/debug_panel.rb +19 -19
- data/lib/brainzlab/devtools/middleware/error_page.rb +45 -44
- data/lib/brainzlab/devtools/renderers/debug_panel_renderer.rb +39 -35
- data/lib/brainzlab/devtools/renderers/error_page_renderer.rb +13 -9
- data/lib/brainzlab/devtools.rb +11 -11
- data/lib/brainzlab/flux/buffer.rb +3 -3
- data/lib/brainzlab/flux/client.rb +14 -16
- data/lib/brainzlab/flux/provisioner.rb +13 -13
- data/lib/brainzlab/flux.rb +8 -8
- data/lib/brainzlab/instrumentation/action_cable.rb +351 -0
- data/lib/brainzlab/instrumentation/action_controller.rb +649 -0
- data/lib/brainzlab/instrumentation/action_dispatch.rb +259 -0
- data/lib/brainzlab/instrumentation/action_mailbox.rb +197 -0
- data/lib/brainzlab/instrumentation/action_mailer.rb +14 -13
- data/lib/brainzlab/instrumentation/action_view.rb +380 -0
- data/lib/brainzlab/instrumentation/active_job.rb +569 -0
- data/lib/brainzlab/instrumentation/active_record.rb +467 -36
- data/lib/brainzlab/instrumentation/active_storage.rb +541 -0
- data/lib/brainzlab/instrumentation/active_support_cache.rb +700 -0
- data/lib/brainzlab/instrumentation/aws.rb +43 -39
- data/lib/brainzlab/instrumentation/dalli.rb +20 -20
- data/lib/brainzlab/instrumentation/delayed_job.rb +27 -29
- data/lib/brainzlab/instrumentation/elasticsearch.rb +23 -24
- data/lib/brainzlab/instrumentation/excon.rb +27 -27
- data/lib/brainzlab/instrumentation/faraday.rb +3 -4
- data/lib/brainzlab/instrumentation/good_job.rb +28 -28
- data/lib/brainzlab/instrumentation/grape.rb +24 -24
- data/lib/brainzlab/instrumentation/graphql.rb +24 -23
- data/lib/brainzlab/instrumentation/httparty.rb +13 -14
- data/lib/brainzlab/instrumentation/mongodb.rb +7 -7
- data/lib/brainzlab/instrumentation/net_http.rb +6 -6
- data/lib/brainzlab/instrumentation/rails_deprecation.rb +139 -0
- data/lib/brainzlab/instrumentation/railties.rb +134 -0
- data/lib/brainzlab/instrumentation/redis.rb +14 -21
- data/lib/brainzlab/instrumentation/resque.rb +23 -24
- data/lib/brainzlab/instrumentation/sidekiq.rb +29 -28
- data/lib/brainzlab/instrumentation/solid_queue.rb +37 -41
- data/lib/brainzlab/instrumentation/stripe.rb +36 -37
- data/lib/brainzlab/instrumentation/typhoeus.rb +19 -17
- data/lib/brainzlab/instrumentation.rb +111 -21
- data/lib/brainzlab/nerve/client.rb +38 -40
- data/lib/brainzlab/nerve/provisioner.rb +1 -1
- data/lib/brainzlab/nerve.rb +6 -6
- data/lib/brainzlab/pulse/client.rb +15 -11
- data/lib/brainzlab/pulse/instrumentation.rb +61 -57
- data/lib/brainzlab/pulse/propagation.rb +28 -28
- data/lib/brainzlab/pulse/provisioner.rb +12 -12
- data/lib/brainzlab/pulse/tracer.rb +3 -3
- data/lib/brainzlab/pulse.rb +13 -13
- data/lib/brainzlab/rails/log_formatter.rb +127 -121
- data/lib/brainzlab/rails/log_subscriber.rb +70 -76
- data/lib/brainzlab/rails/railtie.rb +66 -89
- data/lib/brainzlab/recall/buffer.rb +1 -1
- data/lib/brainzlab/recall/client.rb +14 -10
- data/lib/brainzlab/recall/logger.rb +16 -18
- data/lib/brainzlab/recall/provisioner.rb +16 -16
- data/lib/brainzlab/recall.rb +11 -13
- data/lib/brainzlab/reflex/breadcrumbs.rb +2 -2
- data/lib/brainzlab/reflex/client.rb +14 -10
- data/lib/brainzlab/reflex/provisioner.rb +12 -12
- data/lib/brainzlab/reflex.rb +29 -29
- data/lib/brainzlab/sentinel/client.rb +40 -42
- data/lib/brainzlab/sentinel/provisioner.rb +1 -1
- data/lib/brainzlab/sentinel.rb +5 -5
- data/lib/brainzlab/signal/client.rb +12 -14
- data/lib/brainzlab/signal/provisioner.rb +12 -12
- data/lib/brainzlab/signal.rb +7 -7
- data/lib/brainzlab/synapse/client.rb +42 -44
- data/lib/brainzlab/synapse/provisioner.rb +1 -1
- data/lib/brainzlab/synapse.rb +6 -6
- data/lib/brainzlab/utilities/circuit_breaker.rb +37 -41
- data/lib/brainzlab/utilities/health_check.rb +53 -55
- data/lib/brainzlab/utilities/log_formatter.rb +38 -40
- data/lib/brainzlab/utilities/rate_limiter.rb +5 -5
- data/lib/brainzlab/utilities.rb +4 -4
- data/lib/brainzlab/vault/cache.rb +1 -1
- data/lib/brainzlab/vault/client.rb +39 -41
- data/lib/brainzlab/vault/provisioner.rb +1 -1
- data/lib/brainzlab/vault.rb +19 -25
- data/lib/brainzlab/version.rb +1 -1
- data/lib/brainzlab/vision/client.rb +20 -20
- data/lib/brainzlab/vision/provisioner.rb +21 -21
- data/lib/brainzlab/vision.rb +17 -19
- data/lib/brainzlab-sdk.rb +1 -1
- data/lib/brainzlab.rb +22 -24
- data/lib/generators/brainzlab/install/install_generator.rb +29 -27
- metadata +11 -1
|
@@ -6,18 +6,18 @@ module BrainzLab
|
|
|
6
6
|
# https://www.w3.org/TR/trace-context/
|
|
7
7
|
module Propagation
|
|
8
8
|
# W3C Trace Context header names
|
|
9
|
-
TRACEPARENT_HEADER =
|
|
10
|
-
TRACESTATE_HEADER =
|
|
9
|
+
TRACEPARENT_HEADER = 'traceparent'
|
|
10
|
+
TRACESTATE_HEADER = 'tracestate'
|
|
11
11
|
|
|
12
12
|
# HTTP header versions (with HTTP_ prefix for Rack env)
|
|
13
|
-
HTTP_TRACEPARENT =
|
|
14
|
-
HTTP_TRACESTATE =
|
|
13
|
+
HTTP_TRACEPARENT = 'HTTP_TRACEPARENT'
|
|
14
|
+
HTTP_TRACESTATE = 'HTTP_TRACESTATE'
|
|
15
15
|
|
|
16
16
|
# Also support B3 format for compatibility
|
|
17
|
-
B3_TRACE_ID =
|
|
18
|
-
B3_SPAN_ID =
|
|
19
|
-
B3_SAMPLED =
|
|
20
|
-
B3_PARENT_SPAN_ID =
|
|
17
|
+
B3_TRACE_ID = 'X-B3-TraceId'
|
|
18
|
+
B3_SPAN_ID = 'X-B3-SpanId'
|
|
19
|
+
B3_SAMPLED = 'X-B3-Sampled'
|
|
20
|
+
B3_PARENT_SPAN_ID = 'X-B3-ParentSpanId'
|
|
21
21
|
|
|
22
22
|
class Context
|
|
23
23
|
attr_accessor :trace_id, :span_id, :parent_span_id, :sampled, :tracestate
|
|
@@ -137,8 +137,8 @@ module BrainzLab
|
|
|
137
137
|
# traceparent: version-traceid-spanid-flags
|
|
138
138
|
# Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
|
|
139
139
|
def inject_w3c(headers, ctx)
|
|
140
|
-
version =
|
|
141
|
-
flags = ctx.sampled ?
|
|
140
|
+
version = '00'
|
|
141
|
+
flags = ctx.sampled ? '01' : '00'
|
|
142
142
|
trace_id = normalize_trace_id(ctx.trace_id, 32)
|
|
143
143
|
span_id = normalize_trace_id(ctx.span_id, 16)
|
|
144
144
|
|
|
@@ -152,31 +152,31 @@ module BrainzLab
|
|
|
152
152
|
def extract_w3c(headers)
|
|
153
153
|
traceparent = headers[TRACEPARENT_HEADER] ||
|
|
154
154
|
headers[HTTP_TRACEPARENT] ||
|
|
155
|
-
headers[
|
|
155
|
+
headers['Traceparent']
|
|
156
156
|
return nil unless traceparent
|
|
157
157
|
|
|
158
158
|
# Parse: version-traceid-spanid-flags
|
|
159
|
-
parts = traceparent.to_s.split(
|
|
159
|
+
parts = traceparent.to_s.split('-')
|
|
160
160
|
return nil if parts.length < 4
|
|
161
161
|
|
|
162
162
|
version, trace_id, span_id, flags = parts
|
|
163
163
|
|
|
164
164
|
# Validate version
|
|
165
|
-
return nil unless version ==
|
|
165
|
+
return nil unless version == '00'
|
|
166
166
|
|
|
167
167
|
# Validate trace_id (32 hex chars, not all zeros)
|
|
168
168
|
return nil unless trace_id&.match?(/\A[a-f0-9]{32}\z/i)
|
|
169
|
-
return nil if trace_id ==
|
|
169
|
+
return nil if trace_id == '0' * 32
|
|
170
170
|
|
|
171
171
|
# Validate span_id (16 hex chars, not all zeros)
|
|
172
172
|
return nil unless span_id&.match?(/\A[a-f0-9]{16}\z/i)
|
|
173
|
-
return nil if span_id ==
|
|
173
|
+
return nil if span_id == '0' * 16
|
|
174
174
|
|
|
175
175
|
sampled = flags.to_i(16) & 0x01 == 1
|
|
176
176
|
|
|
177
177
|
tracestate = headers[TRACESTATE_HEADER] ||
|
|
178
178
|
headers[HTTP_TRACESTATE] ||
|
|
179
|
-
headers[
|
|
179
|
+
headers['Tracestate']
|
|
180
180
|
|
|
181
181
|
Context.new(
|
|
182
182
|
trace_id: trace_id,
|
|
@@ -192,7 +192,7 @@ module BrainzLab
|
|
|
192
192
|
def inject_b3(headers, ctx)
|
|
193
193
|
headers[B3_TRACE_ID] = normalize_trace_id(ctx.trace_id, 32)
|
|
194
194
|
headers[B3_SPAN_ID] = normalize_trace_id(ctx.span_id, 16)
|
|
195
|
-
headers[B3_SAMPLED] = ctx.sampled ?
|
|
195
|
+
headers[B3_SAMPLED] = ctx.sampled ? '1' : '0'
|
|
196
196
|
headers[B3_PARENT_SPAN_ID] = ctx.parent_span_id if ctx.parent_span_id
|
|
197
197
|
|
|
198
198
|
headers
|
|
@@ -201,23 +201,23 @@ module BrainzLab
|
|
|
201
201
|
# B3 format extraction
|
|
202
202
|
def extract_b3(headers)
|
|
203
203
|
trace_id = headers[B3_TRACE_ID] ||
|
|
204
|
-
headers[
|
|
205
|
-
headers[
|
|
204
|
+
headers['HTTP_X_B3_TRACEID'] ||
|
|
205
|
+
headers['x-b3-traceid']
|
|
206
206
|
return nil unless trace_id
|
|
207
207
|
|
|
208
208
|
span_id = headers[B3_SPAN_ID] ||
|
|
209
|
-
headers[
|
|
210
|
-
headers[
|
|
209
|
+
headers['HTTP_X_B3_SPANID'] ||
|
|
210
|
+
headers['x-b3-spanid']
|
|
211
211
|
return nil unless span_id
|
|
212
212
|
|
|
213
213
|
sampled_header = headers[B3_SAMPLED] ||
|
|
214
|
-
headers[
|
|
215
|
-
headers[
|
|
216
|
-
sampled = sampled_header !=
|
|
214
|
+
headers['HTTP_X_B3_SAMPLED'] ||
|
|
215
|
+
headers['x-b3-sampled']
|
|
216
|
+
sampled = sampled_header != '0'
|
|
217
217
|
|
|
218
218
|
parent_span_id = headers[B3_PARENT_SPAN_ID] ||
|
|
219
|
-
headers[
|
|
220
|
-
headers[
|
|
219
|
+
headers['HTTP_X_B3_PARENTSPANID'] ||
|
|
220
|
+
headers['x-b3-parentspanid']
|
|
221
221
|
|
|
222
222
|
Context.new(
|
|
223
223
|
trace_id: trace_id,
|
|
@@ -232,8 +232,8 @@ module BrainzLab
|
|
|
232
232
|
def normalize_trace_id(id, length)
|
|
233
233
|
return nil unless id
|
|
234
234
|
|
|
235
|
-
hex = id.to_s.gsub(
|
|
236
|
-
hex.rjust(length,
|
|
235
|
+
hex = id.to_s.gsub('-', '').downcase
|
|
236
|
+
hex.rjust(length, '0').slice(0, length)
|
|
237
237
|
end
|
|
238
238
|
end
|
|
239
239
|
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'uri'
|
|
5
|
+
require 'json'
|
|
6
|
+
require 'fileutils'
|
|
7
7
|
|
|
8
8
|
module BrainzLab
|
|
9
9
|
module Pulse
|
|
10
10
|
class Provisioner
|
|
11
|
-
CACHE_DIR = ENV.fetch(
|
|
11
|
+
CACHE_DIR = ENV.fetch('BRAINZLAB_CACHE_DIR') { File.join(Dir.home, '.brainzlab') }
|
|
12
12
|
|
|
13
13
|
def initialize(config)
|
|
14
14
|
@config = config
|
|
@@ -38,10 +38,10 @@ module BrainzLab
|
|
|
38
38
|
|
|
39
39
|
def should_provision?
|
|
40
40
|
return false unless @config.pulse_auto_provision
|
|
41
|
-
return false unless @config.app_name.to_s.strip.length
|
|
41
|
+
return false unless @config.app_name.to_s.strip.length.positive?
|
|
42
42
|
# Only skip if pulse_api_key is already set
|
|
43
|
-
return false if @config.pulse_api_key.to_s.strip.length
|
|
44
|
-
return false unless @config.pulse_master_key.to_s.strip.length
|
|
43
|
+
return false if @config.pulse_api_key.to_s.strip.length.positive?
|
|
44
|
+
return false unless @config.pulse_master_key.to_s.strip.length.positive?
|
|
45
45
|
|
|
46
46
|
true
|
|
47
47
|
end
|
|
@@ -49,9 +49,9 @@ module BrainzLab
|
|
|
49
49
|
def provision_project
|
|
50
50
|
uri = URI.parse("#{@config.pulse_url}/api/v1/projects/provision")
|
|
51
51
|
request = Net::HTTP::Post.new(uri)
|
|
52
|
-
request[
|
|
53
|
-
request[
|
|
54
|
-
request[
|
|
52
|
+
request['Content-Type'] = 'application/json'
|
|
53
|
+
request['X-Master-Key'] = @config.pulse_master_key
|
|
54
|
+
request['User-Agent'] = "brainzlab-sdk-ruby/#{BrainzLab::VERSION}"
|
|
55
55
|
request.body = JSON.generate({ name: @config.app_name })
|
|
56
56
|
|
|
57
57
|
response = execute(uri, request)
|
|
@@ -98,7 +98,7 @@ module BrainzLab
|
|
|
98
98
|
|
|
99
99
|
def execute(uri, request)
|
|
100
100
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
101
|
-
http.use_ssl = uri.scheme ==
|
|
101
|
+
http.use_ssl = uri.scheme == 'https'
|
|
102
102
|
http.open_timeout = 5
|
|
103
103
|
http.read_timeout = 10
|
|
104
104
|
http.request(request)
|
|
@@ -16,7 +16,7 @@ module BrainzLab
|
|
|
16
16
|
Thread.current[:brainzlab_pulse_spans] ||= []
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def start_trace(name, kind:
|
|
19
|
+
def start_trace(name, kind: 'custom', **attributes)
|
|
20
20
|
trace = {
|
|
21
21
|
trace_id: SecureRandom.uuid,
|
|
22
22
|
name: name,
|
|
@@ -64,7 +64,7 @@ module BrainzLab
|
|
|
64
64
|
payload
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
def span(name, kind:
|
|
67
|
+
def span(name, kind: 'custom', **data)
|
|
68
68
|
span_data = {
|
|
69
69
|
span_id: SecureRandom.uuid,
|
|
70
70
|
name: name,
|
|
@@ -91,7 +91,7 @@ module BrainzLab
|
|
|
91
91
|
|
|
92
92
|
private
|
|
93
93
|
|
|
94
|
-
def format_span(span,
|
|
94
|
+
def format_span(span, _trace_started_at)
|
|
95
95
|
{
|
|
96
96
|
span_id: span[:span_id],
|
|
97
97
|
parent_span_id: span[:parent_span_id],
|
data/lib/brainzlab/pulse.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
3
|
+
require_relative 'pulse/client'
|
|
4
|
+
require_relative 'pulse/provisioner'
|
|
5
|
+
require_relative 'pulse/tracer'
|
|
6
|
+
require_relative 'pulse/instrumentation'
|
|
7
|
+
require_relative 'pulse/propagation'
|
|
8
8
|
|
|
9
9
|
module BrainzLab
|
|
10
10
|
module Pulse
|
|
@@ -13,7 +13,7 @@ module BrainzLab
|
|
|
13
13
|
# @param name [String] the trace name
|
|
14
14
|
# @param kind [String] trace kind (request, job, custom)
|
|
15
15
|
# @param parent_context [Propagation::Context] optional parent context for distributed tracing
|
|
16
|
-
def start_trace(name, kind:
|
|
16
|
+
def start_trace(name, kind: 'custom', parent_context: nil, **attributes)
|
|
17
17
|
return nil unless enabled?
|
|
18
18
|
|
|
19
19
|
ensure_provisioned!
|
|
@@ -36,15 +36,15 @@ module BrainzLab
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
# Add a span to the current trace
|
|
39
|
-
def span(name, kind:
|
|
39
|
+
def span(name, kind: 'custom', **data, &)
|
|
40
40
|
return yield unless enabled?
|
|
41
41
|
return yield unless tracer.current_trace
|
|
42
42
|
|
|
43
|
-
tracer.span(name, kind: kind, **data)
|
|
43
|
+
tracer.span(name, kind: kind, **data, &)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
# Record a complete trace (for when you have all data upfront)
|
|
47
|
-
def record_trace(name, kind:
|
|
47
|
+
def record_trace(name, started_at:, ended_at:, kind: 'request', **attributes)
|
|
48
48
|
return unless enabled?
|
|
49
49
|
|
|
50
50
|
ensure_provisioned!
|
|
@@ -55,7 +55,7 @@ module BrainzLab
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# Record a custom metric
|
|
58
|
-
def record_metric(name, value:, kind:
|
|
58
|
+
def record_metric(name, value:, kind: 'gauge', tags: {})
|
|
59
59
|
return unless enabled?
|
|
60
60
|
|
|
61
61
|
ensure_provisioned!
|
|
@@ -74,15 +74,15 @@ module BrainzLab
|
|
|
74
74
|
|
|
75
75
|
# Convenience methods for metrics
|
|
76
76
|
def gauge(name, value, tags: {})
|
|
77
|
-
record_metric(name, value: value, kind:
|
|
77
|
+
record_metric(name, value: value, kind: 'gauge', tags: tags)
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def counter(name, value = 1, tags: {})
|
|
81
|
-
record_metric(name, value: value, kind:
|
|
81
|
+
record_metric(name, value: value, kind: 'counter', tags: tags)
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
def histogram(name, value, tags: {})
|
|
85
|
-
record_metric(name, value: value, kind:
|
|
85
|
+
record_metric(name, value: value, kind: 'histogram', tags: tags)
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
def ensure_provisioned!
|