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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +6 -21
  3. data/README.md +16 -2
  4. data/lib/brainzlab/beacon/client.rb +38 -40
  5. data/lib/brainzlab/beacon/provisioner.rb +1 -1
  6. data/lib/brainzlab/beacon.rb +15 -15
  7. data/lib/brainzlab/configuration.rb +112 -90
  8. data/lib/brainzlab/context.rb +2 -3
  9. data/lib/brainzlab/cortex/client.rb +29 -31
  10. data/lib/brainzlab/cortex/provisioner.rb +1 -1
  11. data/lib/brainzlab/cortex.rb +7 -11
  12. data/lib/brainzlab/dendrite/client.rb +42 -44
  13. data/lib/brainzlab/dendrite/provisioner.rb +1 -1
  14. data/lib/brainzlab/dendrite.rb +4 -4
  15. data/lib/brainzlab/devtools/data/collector.rb +22 -22
  16. data/lib/brainzlab/devtools/middleware/asset_server.rb +14 -14
  17. data/lib/brainzlab/devtools/middleware/database_handler.rb +52 -55
  18. data/lib/brainzlab/devtools/middleware/debug_panel.rb +19 -19
  19. data/lib/brainzlab/devtools/middleware/error_page.rb +45 -44
  20. data/lib/brainzlab/devtools/renderers/debug_panel_renderer.rb +39 -35
  21. data/lib/brainzlab/devtools/renderers/error_page_renderer.rb +13 -9
  22. data/lib/brainzlab/devtools.rb +11 -11
  23. data/lib/brainzlab/flux/buffer.rb +3 -3
  24. data/lib/brainzlab/flux/client.rb +14 -16
  25. data/lib/brainzlab/flux/provisioner.rb +13 -13
  26. data/lib/brainzlab/flux.rb +8 -8
  27. data/lib/brainzlab/instrumentation/action_cable.rb +351 -0
  28. data/lib/brainzlab/instrumentation/action_controller.rb +649 -0
  29. data/lib/brainzlab/instrumentation/action_dispatch.rb +259 -0
  30. data/lib/brainzlab/instrumentation/action_mailbox.rb +197 -0
  31. data/lib/brainzlab/instrumentation/action_mailer.rb +14 -13
  32. data/lib/brainzlab/instrumentation/action_view.rb +380 -0
  33. data/lib/brainzlab/instrumentation/active_job.rb +569 -0
  34. data/lib/brainzlab/instrumentation/active_record.rb +467 -36
  35. data/lib/brainzlab/instrumentation/active_storage.rb +541 -0
  36. data/lib/brainzlab/instrumentation/active_support_cache.rb +700 -0
  37. data/lib/brainzlab/instrumentation/aws.rb +43 -39
  38. data/lib/brainzlab/instrumentation/dalli.rb +20 -20
  39. data/lib/brainzlab/instrumentation/delayed_job.rb +27 -29
  40. data/lib/brainzlab/instrumentation/elasticsearch.rb +23 -24
  41. data/lib/brainzlab/instrumentation/excon.rb +27 -27
  42. data/lib/brainzlab/instrumentation/faraday.rb +3 -4
  43. data/lib/brainzlab/instrumentation/good_job.rb +28 -28
  44. data/lib/brainzlab/instrumentation/grape.rb +24 -24
  45. data/lib/brainzlab/instrumentation/graphql.rb +24 -23
  46. data/lib/brainzlab/instrumentation/httparty.rb +13 -14
  47. data/lib/brainzlab/instrumentation/mongodb.rb +7 -7
  48. data/lib/brainzlab/instrumentation/net_http.rb +6 -6
  49. data/lib/brainzlab/instrumentation/rails_deprecation.rb +139 -0
  50. data/lib/brainzlab/instrumentation/railties.rb +134 -0
  51. data/lib/brainzlab/instrumentation/redis.rb +14 -21
  52. data/lib/brainzlab/instrumentation/resque.rb +23 -24
  53. data/lib/brainzlab/instrumentation/sidekiq.rb +29 -28
  54. data/lib/brainzlab/instrumentation/solid_queue.rb +37 -41
  55. data/lib/brainzlab/instrumentation/stripe.rb +36 -37
  56. data/lib/brainzlab/instrumentation/typhoeus.rb +19 -17
  57. data/lib/brainzlab/instrumentation.rb +111 -21
  58. data/lib/brainzlab/nerve/client.rb +38 -40
  59. data/lib/brainzlab/nerve/provisioner.rb +1 -1
  60. data/lib/brainzlab/nerve.rb +6 -6
  61. data/lib/brainzlab/pulse/client.rb +15 -11
  62. data/lib/brainzlab/pulse/instrumentation.rb +61 -57
  63. data/lib/brainzlab/pulse/propagation.rb +28 -28
  64. data/lib/brainzlab/pulse/provisioner.rb +12 -12
  65. data/lib/brainzlab/pulse/tracer.rb +3 -3
  66. data/lib/brainzlab/pulse.rb +13 -13
  67. data/lib/brainzlab/rails/log_formatter.rb +127 -121
  68. data/lib/brainzlab/rails/log_subscriber.rb +70 -76
  69. data/lib/brainzlab/rails/railtie.rb +66 -89
  70. data/lib/brainzlab/recall/buffer.rb +1 -1
  71. data/lib/brainzlab/recall/client.rb +14 -10
  72. data/lib/brainzlab/recall/logger.rb +16 -18
  73. data/lib/brainzlab/recall/provisioner.rb +16 -16
  74. data/lib/brainzlab/recall.rb +11 -13
  75. data/lib/brainzlab/reflex/breadcrumbs.rb +2 -2
  76. data/lib/brainzlab/reflex/client.rb +14 -10
  77. data/lib/brainzlab/reflex/provisioner.rb +12 -12
  78. data/lib/brainzlab/reflex.rb +29 -29
  79. data/lib/brainzlab/sentinel/client.rb +40 -42
  80. data/lib/brainzlab/sentinel/provisioner.rb +1 -1
  81. data/lib/brainzlab/sentinel.rb +5 -5
  82. data/lib/brainzlab/signal/client.rb +12 -14
  83. data/lib/brainzlab/signal/provisioner.rb +12 -12
  84. data/lib/brainzlab/signal.rb +7 -7
  85. data/lib/brainzlab/synapse/client.rb +42 -44
  86. data/lib/brainzlab/synapse/provisioner.rb +1 -1
  87. data/lib/brainzlab/synapse.rb +6 -6
  88. data/lib/brainzlab/utilities/circuit_breaker.rb +37 -41
  89. data/lib/brainzlab/utilities/health_check.rb +53 -55
  90. data/lib/brainzlab/utilities/log_formatter.rb +38 -40
  91. data/lib/brainzlab/utilities/rate_limiter.rb +5 -5
  92. data/lib/brainzlab/utilities.rb +4 -4
  93. data/lib/brainzlab/vault/cache.rb +1 -1
  94. data/lib/brainzlab/vault/client.rb +39 -41
  95. data/lib/brainzlab/vault/provisioner.rb +1 -1
  96. data/lib/brainzlab/vault.rb +19 -25
  97. data/lib/brainzlab/version.rb +1 -1
  98. data/lib/brainzlab/vision/client.rb +20 -20
  99. data/lib/brainzlab/vision/provisioner.rb +21 -21
  100. data/lib/brainzlab/vision.rb +17 -19
  101. data/lib/brainzlab-sdk.rb +1 -1
  102. data/lib/brainzlab.rb +22 -24
  103. data/lib/generators/brainzlab/install/install_generator.rb +29 -27
  104. 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 = "traceparent"
10
- TRACESTATE_HEADER = "tracestate"
9
+ TRACEPARENT_HEADER = 'traceparent'
10
+ TRACESTATE_HEADER = 'tracestate'
11
11
 
12
12
  # HTTP header versions (with HTTP_ prefix for Rack env)
13
- HTTP_TRACEPARENT = "HTTP_TRACEPARENT"
14
- HTTP_TRACESTATE = "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 = "X-B3-TraceId"
18
- B3_SPAN_ID = "X-B3-SpanId"
19
- B3_SAMPLED = "X-B3-Sampled"
20
- B3_PARENT_SPAN_ID = "X-B3-ParentSpanId"
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 = "00"
141
- flags = ctx.sampled ? "01" : "00"
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["Traceparent"]
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 == "00"
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 == "0" * 32
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 == "0" * 16
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["Tracestate"]
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 ? "1" : "0"
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["HTTP_X_B3_TRACEID"] ||
205
- headers["x-b3-traceid"]
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["HTTP_X_B3_SPANID"] ||
210
- headers["x-b3-spanid"]
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["HTTP_X_B3_SAMPLED"] ||
215
- headers["x-b3-sampled"]
216
- sampled = sampled_header != "0"
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["HTTP_X_B3_PARENTSPANID"] ||
220
- headers["x-b3-parentspanid"]
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("-", "").downcase
236
- hex.rjust(length, "0").slice(0, 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 "net/http"
4
- require "uri"
5
- require "json"
6
- require "fileutils"
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("BRAINZLAB_CACHE_DIR") { File.join(Dir.home, ".brainzlab") }
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 > 0
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 > 0
44
- return false unless @config.pulse_master_key.to_s.strip.length > 0
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["Content-Type"] = "application/json"
53
- request["X-Master-Key"] = @config.pulse_master_key
54
- request["User-Agent"] = "brainzlab-sdk-ruby/#{BrainzLab::VERSION}"
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 == "https"
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: "custom", **attributes)
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: "custom", **data)
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, trace_started_at)
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],
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
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"
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: "custom", parent_context: nil, **attributes)
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: "custom", **data)
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) { yield }
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: "request", started_at:, ended_at:, **attributes)
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: "gauge", tags: {})
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: "gauge", tags: tags)
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: "counter", tags: tags)
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: "histogram", tags: tags)
85
+ record_metric(name, value: value, kind: 'histogram', tags: tags)
86
86
  end
87
87
 
88
88
  def ensure_provisioned!