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
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "net/http"
4
- require "json"
5
- require "uri"
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'uri'
6
6
 
7
7
  module BrainzLab
8
8
  module Synapse
9
9
  class Client
10
10
  def initialize(config)
11
11
  @config = config
12
- @base_url = config.synapse_url || "https://synapse.brainzlab.ai"
12
+ @base_url = config.synapse_url || 'https://synapse.brainzlab.ai'
13
13
  end
14
14
 
15
15
  # List all projects
@@ -17,14 +17,14 @@ module BrainzLab
17
17
  params = { page: page, per_page: per_page }
18
18
  params[:status] = status if status
19
19
 
20
- response = request(:get, "/api/v1/projects", params: params)
20
+ response = request(:get, '/api/v1/projects', params: params)
21
21
 
22
22
  return [] unless response.is_a?(Net::HTTPSuccess)
23
23
 
24
24
  data = JSON.parse(response.body, symbolize_names: true)
25
25
  data[:projects] || []
26
26
  rescue StandardError => e
27
- log_error("list_projects", e)
27
+ log_error('list_projects', e)
28
28
  []
29
29
  end
30
30
 
@@ -36,7 +36,7 @@ module BrainzLab
36
36
 
37
37
  JSON.parse(response.body, symbolize_names: true)
38
38
  rescue StandardError => e
39
- log_error("get_project", e)
39
+ log_error('get_project', e)
40
40
  nil
41
41
  end
42
42
 
@@ -44,7 +44,7 @@ module BrainzLab
44
44
  def create_project(name:, repos: [], description: nil, **options)
45
45
  response = request(
46
46
  :post,
47
- "/api/v1/projects",
47
+ '/api/v1/projects',
48
48
  body: {
49
49
  name: name,
50
50
  description: description,
@@ -57,7 +57,7 @@ module BrainzLab
57
57
 
58
58
  JSON.parse(response.body, symbolize_names: true)
59
59
  rescue StandardError => e
60
- log_error("create_project", e)
60
+ log_error('create_project', e)
61
61
  nil
62
62
  end
63
63
 
@@ -66,7 +66,7 @@ module BrainzLab
66
66
  response = request(:post, "/api/v1/projects/#{project_id}/up")
67
67
  response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPAccepted)
68
68
  rescue StandardError => e
69
- log_error("start_project", e)
69
+ log_error('start_project', e)
70
70
  false
71
71
  end
72
72
 
@@ -75,7 +75,7 @@ module BrainzLab
75
75
  response = request(:post, "/api/v1/projects/#{project_id}/down")
76
76
  response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPAccepted)
77
77
  rescue StandardError => e
78
- log_error("stop_project", e)
78
+ log_error('stop_project', e)
79
79
  false
80
80
  end
81
81
 
@@ -84,7 +84,7 @@ module BrainzLab
84
84
  response = request(:post, "/api/v1/projects/#{project_id}/restart")
85
85
  response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPAccepted)
86
86
  rescue StandardError => e
87
- log_error("restart_project", e)
87
+ log_error('restart_project', e)
88
88
  false
89
89
  end
90
90
 
@@ -103,7 +103,7 @@ module BrainzLab
103
103
 
104
104
  JSON.parse(response.body, symbolize_names: true)
105
105
  rescue StandardError => e
106
- log_error("deploy", e)
106
+ log_error('deploy', e)
107
107
  nil
108
108
  end
109
109
 
@@ -115,7 +115,7 @@ module BrainzLab
115
115
 
116
116
  JSON.parse(response.body, symbolize_names: true)
117
117
  rescue StandardError => e
118
- log_error("get_deployment", e)
118
+ log_error('get_deployment', e)
119
119
  nil
120
120
  end
121
121
 
@@ -123,7 +123,7 @@ module BrainzLab
123
123
  def create_task(project_id:, description:, type: nil, priority: nil, **options)
124
124
  response = request(
125
125
  :post,
126
- "/api/v1/tasks",
126
+ '/api/v1/tasks',
127
127
  body: {
128
128
  project_id: project_id,
129
129
  description: description,
@@ -137,7 +137,7 @@ module BrainzLab
137
137
 
138
138
  JSON.parse(response.body, symbolize_names: true)
139
139
  rescue StandardError => e
140
- log_error("create_task", e)
140
+ log_error('create_task', e)
141
141
  nil
142
142
  end
143
143
 
@@ -149,7 +149,7 @@ module BrainzLab
149
149
 
150
150
  JSON.parse(response.body, symbolize_names: true)
151
151
  rescue StandardError => e
152
- log_error("get_task", e)
152
+ log_error('get_task', e)
153
153
  nil
154
154
  end
155
155
 
@@ -161,7 +161,7 @@ module BrainzLab
161
161
 
162
162
  JSON.parse(response.body, symbolize_names: true)
163
163
  rescue StandardError => e
164
- log_error("get_task_status", e)
164
+ log_error('get_task_status', e)
165
165
  nil
166
166
  end
167
167
 
@@ -171,14 +171,14 @@ module BrainzLab
171
171
  params[:project_id] = project_id if project_id
172
172
  params[:status] = status if status
173
173
 
174
- response = request(:get, "/api/v1/tasks", params: params)
174
+ response = request(:get, '/api/v1/tasks', params: params)
175
175
 
176
176
  return [] unless response.is_a?(Net::HTTPSuccess)
177
177
 
178
178
  data = JSON.parse(response.body, symbolize_names: true)
179
179
  data[:tasks] || []
180
180
  rescue StandardError => e
181
- log_error("list_tasks", e)
181
+ log_error('list_tasks', e)
182
182
  []
183
183
  end
184
184
 
@@ -187,7 +187,7 @@ module BrainzLab
187
187
  response = request(:post, "/api/v1/tasks/#{task_id}/cancel")
188
188
  response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPAccepted)
189
189
  rescue StandardError => e
190
- log_error("cancel_task", e)
190
+ log_error('cancel_task', e)
191
191
  false
192
192
  end
193
193
 
@@ -203,7 +203,7 @@ module BrainzLab
203
203
 
204
204
  JSON.parse(response.body, symbolize_names: true)
205
205
  rescue StandardError => e
206
- log_error("get_logs", e)
206
+ log_error('get_logs', e)
207
207
  nil
208
208
  end
209
209
 
@@ -223,21 +223,21 @@ module BrainzLab
223
223
 
224
224
  JSON.parse(response.body, symbolize_names: true)
225
225
  rescue StandardError => e
226
- log_error("exec", e)
226
+ log_error('exec', e)
227
227
  nil
228
228
  end
229
229
 
230
230
  def provision(project_id:, app_name:)
231
231
  response = request(
232
232
  :post,
233
- "/api/v1/projects/provision",
233
+ '/api/v1/projects/provision',
234
234
  body: { project_id: project_id, app_name: app_name },
235
235
  use_service_key: true
236
236
  )
237
237
 
238
238
  response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPCreated)
239
239
  rescue StandardError => e
240
- log_error("provision", e)
240
+ log_error('provision', e)
241
241
  false
242
242
  end
243
243
 
@@ -246,34 +246,32 @@ module BrainzLab
246
246
  def request(method, path, headers: {}, body: nil, params: nil, use_service_key: false)
247
247
  uri = URI.parse("#{@base_url}#{path}")
248
248
 
249
- if params
250
- uri.query = URI.encode_www_form(params)
251
- end
249
+ uri.query = URI.encode_www_form(params) if params
252
250
 
253
251
  http = Net::HTTP.new(uri.host, uri.port)
254
- http.use_ssl = uri.scheme == "https"
252
+ http.use_ssl = uri.scheme == 'https'
255
253
  http.open_timeout = 10
256
- http.read_timeout = 120 # Longer timeout for AI tasks
254
+ http.read_timeout = 120 # Longer timeout for AI tasks
257
255
 
258
256
  request = case method
259
- when :get
260
- Net::HTTP::Get.new(uri)
261
- when :post
262
- Net::HTTP::Post.new(uri)
263
- when :put
264
- Net::HTTP::Put.new(uri)
265
- when :delete
266
- Net::HTTP::Delete.new(uri)
267
- end
268
-
269
- request["Content-Type"] = "application/json"
270
- request["Accept"] = "application/json"
257
+ when :get
258
+ Net::HTTP::Get.new(uri)
259
+ when :post
260
+ Net::HTTP::Post.new(uri)
261
+ when :put
262
+ Net::HTTP::Put.new(uri)
263
+ when :delete
264
+ Net::HTTP::Delete.new(uri)
265
+ end
266
+
267
+ request['Content-Type'] = 'application/json'
268
+ request['Accept'] = 'application/json'
271
269
 
272
270
  if use_service_key
273
- request["X-Service-Key"] = @config.synapse_master_key || @config.secret_key
271
+ request['X-Service-Key'] = @config.synapse_master_key || @config.secret_key
274
272
  else
275
273
  auth_key = @config.synapse_api_key || @config.secret_key
276
- request["Authorization"] = "Bearer #{auth_key}" if auth_key
274
+ request['Authorization'] = "Bearer #{auth_key}" if auth_key
277
275
  end
278
276
 
279
277
  headers.each { |k, v| request[k] = v }
@@ -37,7 +37,7 @@ module BrainzLab
37
37
  end
38
38
 
39
39
  def detect_project_id
40
- ENV["BRAINZLAB_PROJECT_ID"]
40
+ ENV.fetch('BRAINZLAB_PROJECT_ID', nil)
41
41
  end
42
42
  end
43
43
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "synapse/client"
4
- require_relative "synapse/provisioner"
3
+ require_relative 'synapse/client'
4
+ require_relative 'synapse/provisioner'
5
5
 
6
6
  module BrainzLab
7
7
  module Synapse
@@ -49,13 +49,13 @@ module BrainzLab
49
49
  # ]
50
50
  # )
51
51
  #
52
- def create_project(name:, repos: [], description: nil, **options)
52
+ def create_project(name:, repos: [], description: nil, **)
53
53
  return nil unless enabled?
54
54
 
55
55
  ensure_provisioned!
56
56
  return nil unless BrainzLab.configuration.synapse_valid?
57
57
 
58
- client.create_project(name: name, repos: repos, description: description, **options)
58
+ client.create_project(name: name, repos: repos, description: description, **)
59
59
  end
60
60
 
61
61
  # Start project containers
@@ -139,7 +139,7 @@ module BrainzLab
139
139
  # priority: :high
140
140
  # )
141
141
  #
142
- def task(project_id:, description:, type: nil, priority: nil, **options)
142
+ def task(project_id:, description:, type: nil, priority: nil, **)
143
143
  return nil unless enabled?
144
144
 
145
145
  ensure_provisioned!
@@ -150,7 +150,7 @@ module BrainzLab
150
150
  description: description,
151
151
  type: type,
152
152
  priority: priority,
153
- **options
153
+ **
154
154
  )
155
155
  end
156
156
 
@@ -31,7 +31,8 @@ module BrainzLab
31
31
 
32
32
  attr_reader :name, :state, :failure_count, :success_count, :last_failure_at
33
33
 
34
- def initialize(name:, failure_threshold: 5, success_threshold: 2, recovery_timeout: 30, timeout: nil, exclude_exceptions: [])
34
+ def initialize(name:, failure_threshold: 5, success_threshold: 2, recovery_timeout: 30, timeout: nil,
35
+ exclude_exceptions: [])
35
36
  @name = name
36
37
  @failure_threshold = failure_threshold
37
38
  @success_threshold = success_threshold
@@ -47,19 +48,18 @@ module BrainzLab
47
48
  end
48
49
 
49
50
  # Execute a block with circuit breaker protection
50
- def call(fallback: nil)
51
+ def call(fallback: nil, &)
51
52
  check_state_transition!
52
53
 
53
54
  case @state
54
55
  when :open
55
56
  track_rejected
56
- if fallback
57
- fallback.respond_to?(:call) ? fallback.call : fallback
58
- else
59
- raise CircuitOpenError, "Circuit '#{@name}' is open"
60
- end
57
+ raise CircuitOpenError, "Circuit '#{@name}' is open" unless fallback
58
+
59
+ fallback.respond_to?(:call) ? fallback.call : fallback
60
+
61
61
  when :closed, :half_open
62
- execute_with_protection(fallback) { yield }
62
+ execute_with_protection(fallback, &)
63
63
  end
64
64
  end
65
65
 
@@ -112,13 +112,13 @@ module BrainzLab
112
112
  registry[name.to_s]
113
113
  end
114
114
 
115
- def register(name, **options)
116
- registry[name.to_s] = new(name: name, **options)
115
+ def register(name, **)
116
+ registry[name.to_s] = new(name: name, **)
117
117
  end
118
118
 
119
- def call(name, **options, &block)
119
+ def call(name, **options, &)
120
120
  breaker = get(name) || register(name, **options)
121
- breaker.call(**options.slice(:fallback), &block)
121
+ breaker.call(**options.slice(:fallback), &)
122
122
  end
123
123
 
124
124
  def reset_all!
@@ -132,35 +132,31 @@ module BrainzLab
132
132
 
133
133
  private
134
134
 
135
- def execute_with_protection(fallback)
135
+ def execute_with_protection(fallback, &)
136
136
  result = if @timeout
137
- Timeout.timeout(@timeout) { yield }
137
+ Timeout.timeout(@timeout, &)
138
138
  else
139
139
  yield
140
140
  end
141
141
 
142
142
  record_success
143
143
  result
144
- rescue *excluded_exceptions => e
144
+ rescue *excluded_exceptions
145
145
  # Don't count excluded exceptions as failures
146
146
  raise
147
147
  rescue StandardError => e
148
148
  record_failure(e)
149
149
 
150
- if fallback
151
- fallback.respond_to?(:call) ? fallback.call : fallback
152
- else
153
- raise
154
- end
150
+ raise unless fallback
151
+
152
+ fallback.respond_to?(:call) ? fallback.call : fallback
155
153
  end
156
154
 
157
155
  def record_success
158
156
  @mutex.synchronize do
159
157
  if @state == :half_open
160
158
  @success_count += 1
161
- if @success_count >= @success_threshold
162
- transition_to(:closed)
163
- end
159
+ transition_to(:closed) if @success_count >= @success_threshold
164
160
  else
165
161
  @failure_count = 0
166
162
  end
@@ -187,10 +183,10 @@ module BrainzLab
187
183
  def check_state_transition!
188
184
  return unless @state == :open && @last_failure_at
189
185
 
190
- if Time.now - @last_failure_at >= @recovery_timeout
191
- @mutex.synchronize do
192
- transition_to(:half_open) if @state == :open
193
- end
186
+ return unless Time.now - @last_failure_at >= @recovery_timeout
187
+
188
+ @mutex.synchronize do
189
+ transition_to(:half_open) if @state == :open
194
190
  end
195
191
  end
196
192
 
@@ -220,39 +216,39 @@ module BrainzLab
220
216
  def track_success
221
217
  return unless BrainzLab.configuration.flux_effectively_enabled?
222
218
 
223
- BrainzLab::Flux.increment("circuit_breaker.success", tags: { name: @name, state: @state.to_s })
219
+ BrainzLab::Flux.increment('circuit_breaker.success', tags: { name: @name, state: @state.to_s })
224
220
  end
225
221
 
226
222
  def track_failure(error)
227
223
  return unless BrainzLab.configuration.flux_effectively_enabled?
228
224
 
229
- BrainzLab::Flux.increment("circuit_breaker.failure", tags: {
230
- name: @name,
231
- state: @state.to_s,
232
- error_class: error.class.name
233
- })
225
+ BrainzLab::Flux.increment('circuit_breaker.failure', tags: {
226
+ name: @name,
227
+ state: @state.to_s,
228
+ error_class: error.class.name
229
+ })
234
230
  end
235
231
 
236
232
  def track_rejected
237
233
  return unless BrainzLab.configuration.flux_effectively_enabled?
238
234
 
239
- BrainzLab::Flux.increment("circuit_breaker.rejected", tags: { name: @name })
235
+ BrainzLab::Flux.increment('circuit_breaker.rejected', tags: { name: @name })
240
236
  end
241
237
 
242
238
  def track_state_change(new_state, old_state = nil)
243
239
  return unless BrainzLab.configuration.flux_effectively_enabled?
244
240
 
245
- BrainzLab::Flux.track("circuit_breaker.state_change", {
246
- name: @name,
247
- new_state: new_state.to_s,
248
- old_state: old_state&.to_s,
249
- failure_count: @failure_count
250
- })
241
+ BrainzLab::Flux.track('circuit_breaker.state_change', {
242
+ name: @name,
243
+ new_state: new_state.to_s,
244
+ old_state: old_state&.to_s,
245
+ failure_count: @failure_count
246
+ })
251
247
 
252
248
  # Also add breadcrumb for debugging
253
249
  BrainzLab::Reflex.add_breadcrumb(
254
250
  "Circuit '#{@name}' transitioned to #{new_state}",
255
- category: "circuit_breaker",
251
+ category: 'circuit_breaker',
256
252
  level: new_state == :open ? :warning : :info,
257
253
  data: { name: @name, old_state: old_state, new_state: new_state }
258
254
  )