brainzlab 0.1.1 → 0.1.3

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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +6 -21
  3. data/README.md +24 -2
  4. data/lib/brainzlab/beacon/client.rb +207 -0
  5. data/lib/brainzlab/beacon/provisioner.rb +44 -0
  6. data/lib/brainzlab/beacon.rb +215 -0
  7. data/lib/brainzlab/configuration.rb +372 -32
  8. data/lib/brainzlab/context.rb +2 -3
  9. data/lib/brainzlab/cortex/cache.rb +59 -0
  10. data/lib/brainzlab/cortex/client.rb +139 -0
  11. data/lib/brainzlab/cortex/provisioner.rb +49 -0
  12. data/lib/brainzlab/cortex.rb +223 -0
  13. data/lib/brainzlab/dendrite/client.rb +230 -0
  14. data/lib/brainzlab/dendrite/provisioner.rb +44 -0
  15. data/lib/brainzlab/dendrite.rb +195 -0
  16. data/lib/brainzlab/devtools/assets/devtools.css +1106 -0
  17. data/lib/brainzlab/devtools/assets/devtools.js +322 -0
  18. data/lib/brainzlab/devtools/assets/logo.svg +6 -0
  19. data/lib/brainzlab/devtools/assets/templates/debug_panel.html.erb +500 -0
  20. data/lib/brainzlab/devtools/assets/templates/error_page.html.erb +1086 -0
  21. data/lib/brainzlab/devtools/data/collector.rb +248 -0
  22. data/lib/brainzlab/devtools/middleware/asset_server.rb +63 -0
  23. data/lib/brainzlab/devtools/middleware/database_handler.rb +177 -0
  24. data/lib/brainzlab/devtools/middleware/debug_panel.rb +126 -0
  25. data/lib/brainzlab/devtools/middleware/error_page.rb +377 -0
  26. data/lib/brainzlab/devtools/renderers/debug_panel_renderer.rb +159 -0
  27. data/lib/brainzlab/devtools/renderers/error_page_renderer.rb +98 -0
  28. data/lib/brainzlab/devtools.rb +75 -0
  29. data/lib/brainzlab/flux/buffer.rb +96 -0
  30. data/lib/brainzlab/flux/client.rb +68 -0
  31. data/lib/brainzlab/flux/provisioner.rb +57 -0
  32. data/lib/brainzlab/flux.rb +174 -0
  33. data/lib/brainzlab/instrumentation/action_mailer.rb +14 -13
  34. data/lib/brainzlab/instrumentation/active_record.rb +28 -13
  35. data/lib/brainzlab/instrumentation/aws.rb +183 -0
  36. data/lib/brainzlab/instrumentation/dalli.rb +108 -0
  37. data/lib/brainzlab/instrumentation/delayed_job.rb +27 -29
  38. data/lib/brainzlab/instrumentation/elasticsearch.rb +23 -24
  39. data/lib/brainzlab/instrumentation/excon.rb +152 -0
  40. data/lib/brainzlab/instrumentation/faraday.rb +3 -4
  41. data/lib/brainzlab/instrumentation/good_job.rb +102 -0
  42. data/lib/brainzlab/instrumentation/grape.rb +24 -24
  43. data/lib/brainzlab/instrumentation/graphql.rb +24 -23
  44. data/lib/brainzlab/instrumentation/httparty.rb +13 -14
  45. data/lib/brainzlab/instrumentation/mongodb.rb +7 -7
  46. data/lib/brainzlab/instrumentation/net_http.rb +6 -6
  47. data/lib/brainzlab/instrumentation/redis.rb +14 -21
  48. data/lib/brainzlab/instrumentation/resque.rb +114 -0
  49. data/lib/brainzlab/instrumentation/sidekiq.rb +29 -28
  50. data/lib/brainzlab/instrumentation/solid_queue.rb +194 -0
  51. data/lib/brainzlab/instrumentation/stripe.rb +163 -0
  52. data/lib/brainzlab/instrumentation/typhoeus.rb +106 -0
  53. data/lib/brainzlab/instrumentation.rb +84 -12
  54. data/lib/brainzlab/nerve/client.rb +215 -0
  55. data/lib/brainzlab/nerve/provisioner.rb +44 -0
  56. data/lib/brainzlab/nerve.rb +219 -0
  57. data/lib/brainzlab/pulse/client.rb +15 -11
  58. data/lib/brainzlab/pulse/instrumentation.rb +90 -53
  59. data/lib/brainzlab/pulse/propagation.rb +29 -29
  60. data/lib/brainzlab/pulse/provisioner.rb +12 -12
  61. data/lib/brainzlab/pulse/tracer.rb +4 -4
  62. data/lib/brainzlab/pulse.rb +14 -14
  63. data/lib/brainzlab/rails/log_formatter.rb +127 -121
  64. data/lib/brainzlab/rails/log_subscriber.rb +70 -77
  65. data/lib/brainzlab/rails/railtie.rb +96 -86
  66. data/lib/brainzlab/recall/buffer.rb +1 -1
  67. data/lib/brainzlab/recall/client.rb +14 -10
  68. data/lib/brainzlab/recall/logger.rb +16 -18
  69. data/lib/brainzlab/recall/provisioner.rb +29 -12
  70. data/lib/brainzlab/recall.rb +14 -11
  71. data/lib/brainzlab/reflex/breadcrumbs.rb +2 -2
  72. data/lib/brainzlab/reflex/client.rb +14 -10
  73. data/lib/brainzlab/reflex/provisioner.rb +12 -12
  74. data/lib/brainzlab/reflex.rb +31 -31
  75. data/lib/brainzlab/sentinel/client.rb +216 -0
  76. data/lib/brainzlab/sentinel/provisioner.rb +44 -0
  77. data/lib/brainzlab/sentinel.rb +165 -0
  78. data/lib/brainzlab/signal/client.rb +60 -0
  79. data/lib/brainzlab/signal/provisioner.rb +55 -0
  80. data/lib/brainzlab/signal.rb +136 -0
  81. data/lib/brainzlab/synapse/client.rb +288 -0
  82. data/lib/brainzlab/synapse/provisioner.rb +44 -0
  83. data/lib/brainzlab/synapse.rb +270 -0
  84. data/lib/brainzlab/utilities/circuit_breaker.rb +261 -0
  85. data/lib/brainzlab/utilities/health_check.rb +294 -0
  86. data/lib/brainzlab/utilities/log_formatter.rb +254 -0
  87. data/lib/brainzlab/utilities/rate_limiter.rb +230 -0
  88. data/lib/brainzlab/utilities.rb +17 -0
  89. data/lib/brainzlab/vault/cache.rb +80 -0
  90. data/lib/brainzlab/vault/client.rb +196 -0
  91. data/lib/brainzlab/vault/provisioner.rb +49 -0
  92. data/lib/brainzlab/vault.rb +262 -0
  93. data/lib/brainzlab/version.rb +1 -1
  94. data/lib/brainzlab/vision/client.rb +128 -0
  95. data/lib/brainzlab/vision/provisioner.rb +136 -0
  96. data/lib/brainzlab/vision.rb +155 -0
  97. data/lib/brainzlab-sdk.rb +1 -1
  98. data/lib/brainzlab.rb +112 -13
  99. data/lib/generators/brainzlab/install/install_generator.rb +29 -27
  100. metadata +60 -1
@@ -4,6 +4,9 @@ module BrainzLab
4
4
  class Configuration
5
5
  LEVELS = %i[debug info warn error fatal].freeze
6
6
 
7
+ # recall_min_level has a custom setter with validation
8
+ attr_reader :recall_min_level
9
+
7
10
  attr_accessor :secret_key,
8
11
  :environment,
9
12
  :service,
@@ -14,7 +17,6 @@ module BrainzLab
14
17
  :debug,
15
18
  :recall_enabled,
16
19
  :recall_url,
17
- :recall_min_level,
18
20
  :recall_buffer_size,
19
21
  :recall_flush_interval,
20
22
  :recall_master_key,
@@ -37,6 +39,70 @@ module BrainzLab
37
39
  :pulse_flush_interval,
38
40
  :pulse_sample_rate,
39
41
  :pulse_excluded_paths,
42
+ :flux_enabled,
43
+ :flux_url,
44
+ :flux_api_key,
45
+ :flux_ingest_key,
46
+ :flux_master_key,
47
+ :flux_auto_provision,
48
+ :flux_buffer_size,
49
+ :flux_flush_interval,
50
+ :signal_enabled,
51
+ :signal_url,
52
+ :signal_api_key,
53
+ :signal_master_key,
54
+ :signal_auto_provision,
55
+ :vault_enabled,
56
+ :vault_url,
57
+ :vault_api_key,
58
+ :vault_master_key,
59
+ :vault_auto_provision,
60
+ :vault_cache_enabled,
61
+ :vault_cache_ttl,
62
+ :vault_auto_load,
63
+ :vault_load_provider_keys,
64
+ :vision_enabled,
65
+ :vision_url,
66
+ :vision_api_key,
67
+ :vision_ingest_key,
68
+ :vision_master_key,
69
+ :vision_auto_provision,
70
+ :vision_default_model,
71
+ :vision_default_browser_provider,
72
+ :cortex_enabled,
73
+ :cortex_url,
74
+ :cortex_api_key,
75
+ :cortex_master_key,
76
+ :cortex_auto_provision,
77
+ :cortex_cache_enabled,
78
+ :cortex_cache_ttl,
79
+ :cortex_default_context,
80
+ :beacon_enabled,
81
+ :beacon_url,
82
+ :beacon_api_key,
83
+ :beacon_master_key,
84
+ :beacon_auto_provision,
85
+ :nerve_enabled,
86
+ :nerve_url,
87
+ :nerve_api_key,
88
+ :nerve_master_key,
89
+ :nerve_auto_provision,
90
+ :dendrite_enabled,
91
+ :dendrite_url,
92
+ :dendrite_api_key,
93
+ :dendrite_master_key,
94
+ :dendrite_auto_provision,
95
+ :sentinel_enabled,
96
+ :sentinel_url,
97
+ :sentinel_api_key,
98
+ :sentinel_agent_key,
99
+ :sentinel_master_key,
100
+ :sentinel_auto_provision,
101
+ :synapse_enabled,
102
+ :synapse_url,
103
+ :synapse_api_key,
104
+ :synapse_master_key,
105
+ :synapse_auto_provision,
40
106
  :scrub_fields,
41
107
  :logger,
42
108
  :instrument_http,
@@ -49,64 +115,178 @@ module BrainzLab
49
115
  :instrument_action_mailer,
50
116
  :instrument_delayed_job,
51
117
  :instrument_grape,
118
+ :instrument_solid_queue,
119
+ :instrument_good_job,
120
+ :instrument_resque,
121
+ :instrument_excon,
122
+ :instrument_typhoeus,
123
+ :instrument_dalli,
124
+ :instrument_aws,
125
+ :instrument_stripe,
52
126
  :http_ignore_hosts,
53
127
  :redis_ignore_commands,
54
128
  :log_formatter_enabled,
55
129
  :log_formatter_colors,
56
130
  :log_formatter_hide_assets,
57
131
  :log_formatter_compact_assets,
58
- :log_formatter_show_params
132
+ :log_formatter_show_params,
133
+ :disable_self_tracking,
134
+ :devtools_enabled,
135
+ :devtools_error_page_enabled,
136
+ :devtools_debug_panel_enabled,
137
+ :devtools_allowed_environments,
138
+ :devtools_allowed_ips,
139
+ :devtools_asset_path,
140
+ :devtools_panel_position,
141
+ :devtools_expand_by_default
142
+
143
+ # Services that should not track themselves to avoid circular dependencies
144
+ SELF_TRACKING_SERVICES = {
145
+ 'recall' => :recall_enabled,
146
+ 'reflex' => :reflex_enabled,
147
+ 'pulse' => :pulse_enabled,
148
+ 'flux' => :flux_enabled,
149
+ 'signal' => :signal_enabled
150
+ }.freeze
59
151
 
60
152
  def initialize
61
153
  # Authentication
62
- @secret_key = ENV["BRAINZLAB_SECRET_KEY"]
154
+ @secret_key = ENV.fetch('BRAINZLAB_SECRET_KEY', nil)
63
155
 
64
156
  # Environment
65
- @environment = ENV["BRAINZLAB_ENVIRONMENT"] || detect_environment
66
- @service = ENV["BRAINZLAB_SERVICE"]
67
- @host = ENV["BRAINZLAB_HOST"] || detect_host
157
+ @environment = ENV['BRAINZLAB_ENVIRONMENT'] || detect_environment
158
+ @service = ENV.fetch('BRAINZLAB_SERVICE', nil)
159
+ @host = ENV['BRAINZLAB_HOST'] || detect_host
68
160
 
69
161
  # App name for auto-provisioning
70
- @app_name = ENV["BRAINZLAB_APP_NAME"]
162
+ @app_name = ENV.fetch('BRAINZLAB_APP_NAME', nil)
71
163
 
72
164
  # Git context
73
- @commit = ENV["GIT_COMMIT"] || ENV["COMMIT_SHA"] || detect_git_commit
74
- @branch = ENV["GIT_BRANCH"] || ENV["BRANCH_NAME"] || detect_git_branch
165
+ @commit = ENV['GIT_COMMIT'] || ENV['COMMIT_SHA'] || detect_git_commit
166
+ @branch = ENV['GIT_BRANCH'] || ENV['BRANCH_NAME'] || detect_git_branch
75
167
 
76
168
  # Debug mode - enables verbose logging
77
- @debug = ENV["BRAINZLAB_DEBUG"] == "true"
169
+ @debug = ENV['BRAINZLAB_DEBUG'] == 'true'
170
+
171
+ # Disable self-tracking - prevents services from tracking to themselves
172
+ # e.g., Recall won't log to itself, Reflex won't track errors to itself
173
+ @disable_self_tracking = ENV.fetch('BRAINZLAB_DISABLE_SELF_TRACKING', 'true') == 'true'
78
174
 
79
175
  # Recall settings
80
176
  @recall_enabled = true
81
- @recall_url = ENV["RECALL_URL"] || "https://recall.brainzlab.ai"
177
+ @recall_url = ENV['RECALL_URL'] || 'https://recall.brainzlab.ai'
82
178
  @recall_min_level = :debug
83
179
  @recall_buffer_size = 50
84
180
  @recall_flush_interval = 5
85
- @recall_master_key = ENV["RECALL_MASTER_KEY"]
181
+ @recall_master_key = ENV.fetch('RECALL_MASTER_KEY', nil)
86
182
  @recall_auto_provision = true
87
183
 
88
184
  # Reflex settings
89
185
  @reflex_enabled = true
90
- @reflex_url = ENV["REFLEX_URL"] || "https://reflex.brainzlab.ai"
91
- @reflex_api_key = ENV["REFLEX_API_KEY"]
92
- @reflex_master_key = ENV["REFLEX_MASTER_KEY"]
186
+ @reflex_url = ENV['REFLEX_URL'] || 'https://reflex.brainzlab.ai'
187
+ @reflex_api_key = ENV.fetch('REFLEX_API_KEY', nil)
188
+ @reflex_master_key = ENV.fetch('REFLEX_MASTER_KEY', nil)
93
189
  @reflex_auto_provision = true
94
190
  @reflex_excluded_exceptions = []
95
191
  @reflex_before_send = nil
96
192
  @reflex_sample_rate = nil
97
- @reflex_fingerprint = nil # Custom fingerprint callback
193
+ @reflex_fingerprint = nil # Custom fingerprint callback
98
194
 
99
195
  # Pulse settings
100
196
  @pulse_enabled = true
101
- @pulse_url = ENV["PULSE_URL"] || "https://pulse.brainzlab.ai"
102
- @pulse_api_key = ENV["PULSE_API_KEY"]
103
- @pulse_master_key = ENV["PULSE_MASTER_KEY"]
197
+ @pulse_url = ENV['PULSE_URL'] || 'https://pulse.brainzlab.ai'
198
+ @pulse_api_key = ENV.fetch('PULSE_API_KEY', nil)
199
+ @pulse_master_key = ENV.fetch('PULSE_MASTER_KEY', nil)
104
200
  @pulse_auto_provision = true
105
201
  @pulse_buffer_size = 50
106
202
  @pulse_flush_interval = 5
107
203
  @pulse_sample_rate = nil
108
204
  @pulse_excluded_paths = %w[/health /ping /up /assets]
109
205
 
206
+ # Flux settings
207
+ @flux_enabled = true
208
+ @flux_url = ENV['FLUX_URL'] || 'https://flux.brainzlab.ai'
209
+ @flux_api_key = ENV.fetch('FLUX_API_KEY', nil)
210
+ @flux_ingest_key = ENV.fetch('FLUX_INGEST_KEY', nil)
211
+ @flux_master_key = ENV.fetch('FLUX_MASTER_KEY', nil)
212
+ @flux_auto_provision = true
213
+ @flux_buffer_size = 100
214
+ @flux_flush_interval = 5
215
+
216
+ # Signal settings
217
+ @signal_enabled = true
218
+ @signal_url = ENV['SIGNAL_URL'] || 'https://signal.brainzlab.ai'
219
+ @signal_api_key = ENV.fetch('SIGNAL_API_KEY', nil)
220
+ @signal_master_key = ENV.fetch('SIGNAL_MASTER_KEY', nil)
221
+ @signal_auto_provision = true
222
+
223
+ # Vault settings
224
+ @vault_enabled = true
225
+ @vault_url = ENV['VAULT_URL'] || 'https://vault.brainzlab.ai'
226
+ @vault_api_key = ENV.fetch('VAULT_API_KEY', nil)
227
+ @vault_master_key = ENV.fetch('VAULT_MASTER_KEY', nil)
228
+ @vault_auto_provision = true
229
+ @vault_cache_enabled = true
230
+ @vault_cache_ttl = 300 # 5 minutes
231
+ @vault_auto_load = ENV.fetch('VAULT_AUTO_LOAD', 'false') == 'true' # Auto-load secrets into ENV
232
+ @vault_load_provider_keys = true # Also load provider keys (OpenAI, etc.)
233
+
234
+ # Vision settings (AI browser automation)
235
+ @vision_enabled = true
236
+ @vision_url = ENV['VISION_URL'] || 'https://vision.brainzlab.ai'
237
+ @vision_api_key = ENV.fetch('VISION_API_KEY', nil)
238
+ @vision_ingest_key = ENV.fetch('VISION_INGEST_KEY', nil)
239
+ @vision_master_key = ENV.fetch('VISION_MASTER_KEY', nil)
240
+ @vision_auto_provision = true
241
+ @vision_default_model = ENV['VISION_DEFAULT_MODEL'] || 'claude-sonnet-4'
242
+ @vision_default_browser_provider = ENV['VISION_DEFAULT_BROWSER_PROVIDER'] || 'local'
243
+
244
+ # Cortex settings (feature flags)
245
+ @cortex_enabled = true
246
+ @cortex_url = ENV['CORTEX_URL'] || 'https://cortex.brainzlab.ai'
247
+ @cortex_api_key = ENV.fetch('CORTEX_API_KEY', nil)
248
+ @cortex_master_key = ENV.fetch('CORTEX_MASTER_KEY', nil)
249
+ @cortex_auto_provision = true
250
+ @cortex_cache_enabled = true
251
+ @cortex_cache_ttl = 60 # 1 minute
252
+ @cortex_default_context = {}
253
+
254
+ # Beacon settings (uptime monitoring)
255
+ @beacon_enabled = true
256
+ @beacon_url = ENV['BEACON_URL'] || 'https://beacon.brainzlab.ai'
257
+ @beacon_api_key = ENV.fetch('BEACON_API_KEY', nil)
258
+ @beacon_master_key = ENV.fetch('BEACON_MASTER_KEY', nil)
259
+ @beacon_auto_provision = true
260
+
261
+ # Nerve settings (job monitoring)
262
+ @nerve_enabled = true
263
+ @nerve_url = ENV['NERVE_URL'] || 'https://nerve.brainzlab.ai'
264
+ @nerve_api_key = ENV.fetch('NERVE_API_KEY', nil)
265
+ @nerve_master_key = ENV.fetch('NERVE_MASTER_KEY', nil)
266
+ @nerve_auto_provision = true
267
+
268
+ # Dendrite settings (AI documentation)
269
+ @dendrite_enabled = true
270
+ @dendrite_url = ENV['DENDRITE_URL'] || 'https://dendrite.brainzlab.ai'
271
+ @dendrite_api_key = ENV.fetch('DENDRITE_API_KEY', nil)
272
+ @dendrite_master_key = ENV.fetch('DENDRITE_MASTER_KEY', nil)
273
+ @dendrite_auto_provision = true
274
+
275
+ # Sentinel settings (host monitoring)
276
+ @sentinel_enabled = true
277
+ @sentinel_url = ENV['SENTINEL_URL'] || 'https://sentinel.brainzlab.ai'
278
+ @sentinel_api_key = ENV.fetch('SENTINEL_API_KEY', nil)
279
+ @sentinel_agent_key = ENV.fetch('SENTINEL_AGENT_KEY', nil)
280
+ @sentinel_master_key = ENV.fetch('SENTINEL_MASTER_KEY', nil)
281
+ @sentinel_auto_provision = true
282
+
283
+ # Synapse settings (AI development orchestration)
284
+ @synapse_enabled = true
285
+ @synapse_url = ENV['SYNAPSE_URL'] || 'https://synapse.brainzlab.ai'
286
+ @synapse_api_key = ENV.fetch('SYNAPSE_API_KEY', nil)
287
+ @synapse_master_key = ENV.fetch('SYNAPSE_MASTER_KEY', nil)
288
+ @synapse_auto_provision = true
289
+
110
290
  # Filtering
111
291
  @scrub_fields = %i[password password_confirmation token api_key secret]
112
292
 
@@ -114,18 +294,26 @@ module BrainzLab
114
294
  @logger = nil
115
295
 
116
296
  # Instrumentation
117
- @instrument_http = true # Enable HTTP client instrumentation (Net::HTTP, Faraday, HTTParty)
118
- @instrument_active_record = true # AR breadcrumbs for Reflex
119
- @instrument_redis = true # Redis command instrumentation
297
+ @instrument_http = true # Enable HTTP client instrumentation (Net::HTTP, Faraday, HTTParty)
298
+ @instrument_active_record = true # AR breadcrumbs for Reflex
299
+ @instrument_redis = true # Redis command instrumentation
120
300
  @instrument_sidekiq = true # Sidekiq job instrumentation
121
301
  @instrument_graphql = true # GraphQL query instrumentation
122
302
  @instrument_mongodb = true # MongoDB/Mongoid instrumentation
123
303
  @instrument_elasticsearch = true # Elasticsearch instrumentation
124
304
  @instrument_action_mailer = true # ActionMailer instrumentation
125
- @instrument_delayed_job = true # Delayed::Job instrumentation
126
- @instrument_grape = true # Grape API instrumentation
305
+ @instrument_delayed_job = true # Delayed::Job instrumentation
306
+ @instrument_grape = true # Grape API instrumentation
307
+ @instrument_solid_queue = true # Solid Queue job instrumentation
308
+ @instrument_good_job = true # GoodJob instrumentation
309
+ @instrument_resque = true # Resque instrumentation
310
+ @instrument_excon = true # Excon HTTP client instrumentation
311
+ @instrument_typhoeus = true # Typhoeus HTTP client instrumentation
312
+ @instrument_dalli = true # Dalli/Memcached instrumentation
313
+ @instrument_aws = true # AWS SDK instrumentation
314
+ @instrument_stripe = true # Stripe API instrumentation
127
315
  @http_ignore_hosts = %w[localhost 127.0.0.1]
128
- @redis_ignore_commands = %w[ping info] # Commands to skip tracking
316
+ @redis_ignore_commands = %w[ping info] # Commands to skip tracking
129
317
 
130
318
  # Log formatter settings
131
319
  @log_formatter_enabled = true
@@ -133,6 +321,16 @@ module BrainzLab
133
321
  @log_formatter_hide_assets = false
134
322
  @log_formatter_compact_assets = true
135
323
  @log_formatter_show_params = true
324
+
325
+ # DevTools settings (development error page and debug panel)
326
+ @devtools_enabled = true
327
+ @devtools_error_page_enabled = true
328
+ @devtools_debug_panel_enabled = true
329
+ @devtools_allowed_environments = %w[development test]
330
+ @devtools_allowed_ips = ['127.0.0.1', '::1', '172.16.0.0/12', '192.168.0.0/16', '10.0.0.0/8']
331
+ @devtools_asset_path = '/__brainzlab__'
332
+ @devtools_panel_position = 'bottom-right'
333
+ @devtools_expand_by_default = false
136
334
  end
137
335
 
138
336
  def recall_min_level=(level)
@@ -168,10 +366,150 @@ module BrainzLab
168
366
  pulse_api_key || secret_key
169
367
  end
170
368
 
369
+ def flux_valid?
370
+ key = flux_ingest_key || flux_api_key || secret_key
371
+ !key.nil? && !key.empty?
372
+ end
373
+
374
+ def flux_auth_key
375
+ flux_ingest_key || flux_api_key || secret_key
376
+ end
377
+
378
+ def signal_valid?
379
+ key = signal_api_key || secret_key
380
+ !key.nil? && !key.empty?
381
+ end
382
+
383
+ def signal_auth_key
384
+ signal_api_key || secret_key
385
+ end
386
+
387
+ def vault_valid?
388
+ key = vault_api_key || secret_key
389
+ !key.nil? && !key.empty?
390
+ end
391
+
392
+ def vault_auth_key
393
+ vault_api_key || secret_key
394
+ end
395
+
396
+ def vision_valid?
397
+ key = vision_ingest_key || vision_api_key || secret_key
398
+ !key.nil? && !key.empty?
399
+ end
400
+
401
+ def vision_auth_key
402
+ vision_ingest_key || vision_api_key || secret_key
403
+ end
404
+
405
+ def beacon_valid?
406
+ key = beacon_api_key || secret_key
407
+ !key.nil? && !key.empty?
408
+ end
409
+
410
+ def beacon_auth_key
411
+ beacon_api_key || secret_key
412
+ end
413
+
414
+ def nerve_valid?
415
+ key = nerve_api_key || secret_key
416
+ !key.nil? && !key.empty?
417
+ end
418
+
419
+ def nerve_auth_key
420
+ nerve_api_key || secret_key
421
+ end
422
+
423
+ def cortex_valid?
424
+ key = cortex_api_key || secret_key
425
+ !key.nil? && !key.empty?
426
+ end
427
+
428
+ def cortex_auth_key
429
+ cortex_api_key || secret_key
430
+ end
431
+
432
+ def dendrite_valid?
433
+ key = dendrite_api_key || secret_key
434
+ !key.nil? && !key.empty?
435
+ end
436
+
437
+ def dendrite_auth_key
438
+ dendrite_api_key || secret_key
439
+ end
440
+
441
+ def sentinel_valid?
442
+ key = sentinel_api_key || secret_key
443
+ !key.nil? && !key.empty?
444
+ end
445
+
446
+ def sentinel_auth_key
447
+ sentinel_api_key || secret_key
448
+ end
449
+
450
+ def synapse_valid?
451
+ key = synapse_api_key || secret_key
452
+ !key.nil? && !key.empty?
453
+ end
454
+
455
+ def synapse_auth_key
456
+ synapse_api_key || secret_key
457
+ end
458
+
171
459
  def debug?
172
460
  @debug == true
173
461
  end
174
462
 
463
+ # Check if recall is effectively enabled (considering self-tracking)
464
+ def recall_effectively_enabled?
465
+ return false unless @recall_enabled
466
+ return true unless @disable_self_tracking
467
+
468
+ # Disable if this is the Recall service itself
469
+ normalized_app_name = @app_name.to_s.downcase.strip
470
+ normalized_app_name != 'recall'
471
+ end
472
+
473
+ # Check if reflex is effectively enabled (considering self-tracking)
474
+ def reflex_effectively_enabled?
475
+ return false unless @reflex_enabled
476
+ return true unless @disable_self_tracking
477
+
478
+ # Disable if this is the Reflex service itself
479
+ normalized_app_name = @app_name.to_s.downcase.strip
480
+ normalized_app_name != 'reflex'
481
+ end
482
+
483
+ # Check if pulse is effectively enabled (considering self-tracking)
484
+ def pulse_effectively_enabled?
485
+ return false unless @pulse_enabled
486
+ return true unless @disable_self_tracking
487
+
488
+ # Disable if this is the Pulse service itself
489
+ normalized_app_name = @app_name.to_s.downcase.strip
490
+ normalized_app_name != 'pulse'
491
+ end
492
+
493
+ # Check if flux is effectively enabled (considering self-tracking)
494
+ def flux_effectively_enabled?
495
+ return false unless @flux_enabled
496
+ return true unless @disable_self_tracking
497
+
498
+ # Disable if this is the Flux service itself
499
+ normalized_app_name = @app_name.to_s.downcase.strip
500
+ normalized_app_name != 'flux'
501
+ end
502
+
503
+ # Check if signal is effectively enabled (considering self-tracking)
504
+ def signal_effectively_enabled?
505
+ return false unless @signal_enabled
506
+ return true unless @disable_self_tracking
507
+
508
+ # Disable if this is the Signal service itself
509
+ normalized_app_name = @app_name.to_s.downcase.strip
510
+ normalized_app_name != 'signal'
511
+ end
512
+
175
513
  def debug_log(message)
176
514
  return unless debug?
177
515
 
@@ -179,7 +517,7 @@ module BrainzLab
179
517
  if logger
180
518
  logger.debug(log_message)
181
519
  else
182
- $stderr.puts(log_message)
520
+ warn(log_message)
183
521
  end
184
522
  end
185
523
 
@@ -187,27 +525,29 @@ module BrainzLab
187
525
 
188
526
  def detect_environment
189
527
  return ::Rails.env.to_s if defined?(::Rails) && ::Rails.respond_to?(:env)
190
- return ENV["RACK_ENV"] if ENV["RACK_ENV"]
191
- return ENV["RUBY_ENV"] if ENV["RUBY_ENV"]
528
+ return ENV['RACK_ENV'] if ENV['RACK_ENV']
529
+ return ENV['RUBY_ENV'] if ENV['RUBY_ENV']
192
530
 
193
- "development"
531
+ 'development'
194
532
  end
195
533
 
196
534
  def detect_host
197
- require "socket"
535
+ require 'socket'
198
536
  Socket.gethostname
199
537
  rescue StandardError
200
538
  nil
201
539
  end
202
540
 
203
541
  def detect_git_commit
204
- `git rev-parse HEAD 2>/dev/null`.strip.presence
542
+ result = `git rev-parse HEAD 2>/dev/null`.strip
543
+ result.empty? ? nil : result
205
544
  rescue StandardError
206
545
  nil
207
546
  end
208
547
 
209
548
  def detect_git_branch
210
- `git rev-parse --abbrev-ref HEAD 2>/dev/null`.strip.presence
549
+ result = `git rev-parse --abbrev-ref HEAD 2>/dev/null`.strip
550
+ result.empty? ? nil : result
211
551
  rescue StandardError
212
552
  nil
213
553
  end
@@ -14,9 +14,8 @@ module BrainzLab
14
14
  end
15
15
  end
16
16
 
17
- attr_accessor :user, :request_id, :session_id
18
- attr_accessor :request_method, :request_path, :request_url, :request_params, :request_headers
19
- attr_accessor :controller, :action
17
+ attr_accessor :user, :request_id, :session_id, :request_method, :request_path, :request_url, :request_params,
18
+ :request_headers, :controller, :action
20
19
  attr_reader :extra, :tags, :breadcrumbs
21
20
 
22
21
  def initialize
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BrainzLab
4
+ module Cortex
5
+ class Cache
6
+ def initialize(ttl = 60)
7
+ @ttl = ttl
8
+ @store = {}
9
+ @timestamps = {}
10
+ @mutex = Mutex.new
11
+ end
12
+
13
+ def get(key)
14
+ @mutex.synchronize do
15
+ return nil unless @store.key?(key)
16
+ return nil if expired?(key)
17
+
18
+ @store[key]
19
+ end
20
+ end
21
+
22
+ def set(key, value)
23
+ @mutex.synchronize do
24
+ @store[key] = value
25
+ @timestamps[key] = Time.now
26
+ end
27
+ end
28
+
29
+ def has?(key)
30
+ @mutex.synchronize do
31
+ @store.key?(key) && !expired?(key)
32
+ end
33
+ end
34
+
35
+ def delete(key)
36
+ @mutex.synchronize do
37
+ @store.delete(key)
38
+ @timestamps.delete(key)
39
+ end
40
+ end
41
+
42
+ def clear!
43
+ @mutex.synchronize do
44
+ @store.clear
45
+ @timestamps.clear
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def expired?(key)
52
+ timestamp = @timestamps[key]
53
+ return true unless timestamp
54
+
55
+ Time.now - timestamp > @ttl
56
+ end
57
+ end
58
+ end
59
+ end