fluyenta-ruby 0.1.14
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 +7 -0
- data/CHANGELOG.md +68 -0
- data/LICENSE +11 -0
- data/README.md +571 -0
- data/lib/brainzlab/beacon/client.rb +227 -0
- data/lib/brainzlab/beacon/provisioner.rb +44 -0
- data/lib/brainzlab/beacon.rb +215 -0
- data/lib/brainzlab/configuration.rb +676 -0
- data/lib/brainzlab/context.rb +90 -0
- data/lib/brainzlab/cortex/cache.rb +59 -0
- data/lib/brainzlab/cortex/client.rb +159 -0
- data/lib/brainzlab/cortex/provisioner.rb +49 -0
- data/lib/brainzlab/cortex.rb +223 -0
- data/lib/brainzlab/debug.rb +305 -0
- data/lib/brainzlab/dendrite/client.rb +250 -0
- data/lib/brainzlab/dendrite/provisioner.rb +44 -0
- data/lib/brainzlab/dendrite.rb +195 -0
- data/lib/brainzlab/development/logger.rb +150 -0
- data/lib/brainzlab/development/store.rb +121 -0
- data/lib/brainzlab/development.rb +72 -0
- data/lib/brainzlab/devtools/assets/devtools.css +1329 -0
- data/lib/brainzlab/devtools/assets/devtools.js +396 -0
- data/lib/brainzlab/devtools/assets/logo.svg +6 -0
- data/lib/brainzlab/devtools/assets/templates/debug_panel.html.erb +511 -0
- data/lib/brainzlab/devtools/assets/templates/error_page.html.erb +1086 -0
- data/lib/brainzlab/devtools/data/collector.rb +248 -0
- data/lib/brainzlab/devtools/middleware/asset_server.rb +63 -0
- data/lib/brainzlab/devtools/middleware/database_handler.rb +177 -0
- data/lib/brainzlab/devtools/middleware/debug_panel.rb +126 -0
- data/lib/brainzlab/devtools/middleware/error_page.rb +377 -0
- data/lib/brainzlab/devtools/renderers/debug_panel_renderer.rb +159 -0
- data/lib/brainzlab/devtools/renderers/error_page_renderer.rb +98 -0
- data/lib/brainzlab/devtools.rb +75 -0
- data/lib/brainzlab/errors.rb +490 -0
- data/lib/brainzlab/flux/buffer.rb +96 -0
- data/lib/brainzlab/flux/client.rb +68 -0
- data/lib/brainzlab/flux/provisioner.rb +124 -0
- data/lib/brainzlab/flux.rb +184 -0
- 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 +182 -0
- 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 +559 -0
- data/lib/brainzlab/instrumentation/active_storage.rb +541 -0
- data/lib/brainzlab/instrumentation/active_support_cache.rb +730 -0
- data/lib/brainzlab/instrumentation/aws.rb +183 -0
- data/lib/brainzlab/instrumentation/dalli.rb +108 -0
- data/lib/brainzlab/instrumentation/delayed_job.rb +234 -0
- data/lib/brainzlab/instrumentation/elasticsearch.rb +209 -0
- data/lib/brainzlab/instrumentation/excon.rb +152 -0
- data/lib/brainzlab/instrumentation/faraday.rb +181 -0
- data/lib/brainzlab/instrumentation/good_job.rb +102 -0
- data/lib/brainzlab/instrumentation/grape.rb +293 -0
- data/lib/brainzlab/instrumentation/graphql.rb +252 -0
- data/lib/brainzlab/instrumentation/httparty.rb +193 -0
- data/lib/brainzlab/instrumentation/mongodb.rb +187 -0
- data/lib/brainzlab/instrumentation/net_http.rb +114 -0
- data/lib/brainzlab/instrumentation/rails_deprecation.rb +139 -0
- data/lib/brainzlab/instrumentation/railties.rb +134 -0
- data/lib/brainzlab/instrumentation/redis.rb +324 -0
- data/lib/brainzlab/instrumentation/resque.rb +114 -0
- data/lib/brainzlab/instrumentation/sidekiq.rb +265 -0
- data/lib/brainzlab/instrumentation/solid_queue.rb +194 -0
- data/lib/brainzlab/instrumentation/stripe.rb +163 -0
- data/lib/brainzlab/instrumentation/typhoeus.rb +106 -0
- data/lib/brainzlab/instrumentation.rb +360 -0
- data/lib/brainzlab/nerve/client.rb +235 -0
- data/lib/brainzlab/nerve/provisioner.rb +44 -0
- data/lib/brainzlab/nerve.rb +219 -0
- data/lib/brainzlab/pulse/client.rb +203 -0
- data/lib/brainzlab/pulse/instrumentation.rb +401 -0
- data/lib/brainzlab/pulse/propagation.rb +241 -0
- data/lib/brainzlab/pulse/provisioner.rb +114 -0
- data/lib/brainzlab/pulse/tracer.rb +111 -0
- data/lib/brainzlab/pulse.rb +294 -0
- data/lib/brainzlab/rails/log_formatter.rb +807 -0
- data/lib/brainzlab/rails/log_subscriber.rb +334 -0
- data/lib/brainzlab/rails/railtie.rb +606 -0
- data/lib/brainzlab/recall/buffer.rb +66 -0
- data/lib/brainzlab/recall/client.rb +158 -0
- data/lib/brainzlab/recall/logger.rb +116 -0
- data/lib/brainzlab/recall/provisioner.rb +130 -0
- data/lib/brainzlab/recall.rb +175 -0
- data/lib/brainzlab/reflex/breadcrumbs.rb +55 -0
- data/lib/brainzlab/reflex/client.rb +150 -0
- data/lib/brainzlab/reflex/provisioner.rb +116 -0
- data/lib/brainzlab/reflex.rb +421 -0
- data/lib/brainzlab/sentinel/client.rb +236 -0
- data/lib/brainzlab/sentinel/provisioner.rb +44 -0
- data/lib/brainzlab/sentinel.rb +165 -0
- data/lib/brainzlab/signal/client.rb +60 -0
- data/lib/brainzlab/signal/provisioner.rb +115 -0
- data/lib/brainzlab/signal.rb +136 -0
- data/lib/brainzlab/synapse/client.rb +308 -0
- data/lib/brainzlab/synapse/provisioner.rb +44 -0
- data/lib/brainzlab/synapse.rb +270 -0
- data/lib/brainzlab/testing/event_store.rb +377 -0
- data/lib/brainzlab/testing/helpers.rb +650 -0
- data/lib/brainzlab/testing/matchers.rb +391 -0
- data/lib/brainzlab/testing.rb +327 -0
- data/lib/brainzlab/utilities/circuit_breaker.rb +290 -0
- data/lib/brainzlab/utilities/health_check.rb +294 -0
- data/lib/brainzlab/utilities/log_formatter.rb +254 -0
- data/lib/brainzlab/utilities/rate_limiter.rb +230 -0
- data/lib/brainzlab/utilities.rb +17 -0
- data/lib/brainzlab/vault/cache.rb +80 -0
- data/lib/brainzlab/vault/client.rb +216 -0
- data/lib/brainzlab/vault/provisioner.rb +49 -0
- data/lib/brainzlab/vault.rb +262 -0
- data/lib/brainzlab/version.rb +5 -0
- data/lib/brainzlab/vision/client.rb +175 -0
- data/lib/brainzlab/vision/provisioner.rb +136 -0
- data/lib/brainzlab/vision.rb +155 -0
- data/lib/brainzlab-sdk.rb +3 -0
- data/lib/brainzlab.rb +306 -0
- data/lib/generators/brainzlab/install/install_generator.rb +63 -0
- data/lib/generators/brainzlab/install/templates/brainzlab.rb.tt +77 -0
- metadata +251 -0
|
@@ -0,0 +1,676 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BrainzLab
|
|
4
|
+
class Configuration
|
|
5
|
+
LEVELS = %i[debug info warn error fatal].freeze
|
|
6
|
+
|
|
7
|
+
# recall_min_level has a custom setter with validation
|
|
8
|
+
attr_reader :recall_min_level
|
|
9
|
+
|
|
10
|
+
# mode has a custom setter with validation
|
|
11
|
+
attr_reader :mode
|
|
12
|
+
|
|
13
|
+
attr_accessor :enabled,
|
|
14
|
+
:secret_key,
|
|
15
|
+
:environment,
|
|
16
|
+
:service,
|
|
17
|
+
:host,
|
|
18
|
+
:commit,
|
|
19
|
+
:branch,
|
|
20
|
+
:app_name,
|
|
21
|
+
:debug,
|
|
22
|
+
:recall_enabled,
|
|
23
|
+
:recall_url,
|
|
24
|
+
:recall_buffer_size,
|
|
25
|
+
:recall_flush_interval,
|
|
26
|
+
:recall_master_key,
|
|
27
|
+
:recall_auto_provision,
|
|
28
|
+
:reflex_enabled,
|
|
29
|
+
:reflex_url,
|
|
30
|
+
:reflex_api_key,
|
|
31
|
+
:reflex_master_key,
|
|
32
|
+
:reflex_auto_provision,
|
|
33
|
+
:reflex_excluded_exceptions,
|
|
34
|
+
:reflex_before_send,
|
|
35
|
+
:reflex_sample_rate,
|
|
36
|
+
:reflex_fingerprint,
|
|
37
|
+
:pulse_enabled,
|
|
38
|
+
:pulse_url,
|
|
39
|
+
:pulse_api_key,
|
|
40
|
+
:pulse_master_key,
|
|
41
|
+
:pulse_auto_provision,
|
|
42
|
+
:pulse_buffer_size,
|
|
43
|
+
:pulse_flush_interval,
|
|
44
|
+
:pulse_sample_rate,
|
|
45
|
+
:pulse_excluded_paths,
|
|
46
|
+
:flux_enabled,
|
|
47
|
+
:flux_url,
|
|
48
|
+
:flux_api_key,
|
|
49
|
+
:flux_ingest_key,
|
|
50
|
+
:flux_master_key,
|
|
51
|
+
:flux_auto_provision,
|
|
52
|
+
:flux_buffer_size,
|
|
53
|
+
:flux_flush_interval,
|
|
54
|
+
:signal_enabled,
|
|
55
|
+
:signal_url,
|
|
56
|
+
:signal_api_key,
|
|
57
|
+
:signal_ingest_key,
|
|
58
|
+
:signal_master_key,
|
|
59
|
+
:signal_auto_provision,
|
|
60
|
+
:vault_enabled,
|
|
61
|
+
:vault_url,
|
|
62
|
+
:vault_api_key,
|
|
63
|
+
:vault_master_key,
|
|
64
|
+
:vault_auto_provision,
|
|
65
|
+
:vault_cache_enabled,
|
|
66
|
+
:vault_cache_ttl,
|
|
67
|
+
:vault_auto_load,
|
|
68
|
+
:vault_load_provider_keys,
|
|
69
|
+
:vision_enabled,
|
|
70
|
+
:vision_url,
|
|
71
|
+
:vision_api_key,
|
|
72
|
+
:vision_ingest_key,
|
|
73
|
+
:vision_master_key,
|
|
74
|
+
:vision_auto_provision,
|
|
75
|
+
:vision_default_model,
|
|
76
|
+
:vision_default_browser_provider,
|
|
77
|
+
:cortex_enabled,
|
|
78
|
+
:cortex_url,
|
|
79
|
+
:cortex_api_key,
|
|
80
|
+
:cortex_master_key,
|
|
81
|
+
:cortex_auto_provision,
|
|
82
|
+
:cortex_cache_enabled,
|
|
83
|
+
:cortex_cache_ttl,
|
|
84
|
+
:cortex_default_context,
|
|
85
|
+
:beacon_enabled,
|
|
86
|
+
:beacon_url,
|
|
87
|
+
:beacon_api_key,
|
|
88
|
+
:beacon_master_key,
|
|
89
|
+
:beacon_auto_provision,
|
|
90
|
+
:nerve_enabled,
|
|
91
|
+
:nerve_url,
|
|
92
|
+
:nerve_api_key,
|
|
93
|
+
:nerve_master_key,
|
|
94
|
+
:nerve_auto_provision,
|
|
95
|
+
:dendrite_enabled,
|
|
96
|
+
:dendrite_url,
|
|
97
|
+
:dendrite_api_key,
|
|
98
|
+
:dendrite_master_key,
|
|
99
|
+
:dendrite_auto_provision,
|
|
100
|
+
:sentinel_enabled,
|
|
101
|
+
:sentinel_url,
|
|
102
|
+
:sentinel_api_key,
|
|
103
|
+
:sentinel_agent_key,
|
|
104
|
+
:sentinel_master_key,
|
|
105
|
+
:sentinel_auto_provision,
|
|
106
|
+
:synapse_enabled,
|
|
107
|
+
:synapse_url,
|
|
108
|
+
:synapse_api_key,
|
|
109
|
+
:synapse_master_key,
|
|
110
|
+
:synapse_auto_provision,
|
|
111
|
+
:scrub_fields,
|
|
112
|
+
:logger,
|
|
113
|
+
:on_error,
|
|
114
|
+
:on_send,
|
|
115
|
+
:instrument_http,
|
|
116
|
+
:instrument_active_record,
|
|
117
|
+
:instrument_redis,
|
|
118
|
+
:instrument_sidekiq,
|
|
119
|
+
:instrument_graphql,
|
|
120
|
+
:instrument_mongodb,
|
|
121
|
+
:instrument_elasticsearch,
|
|
122
|
+
:instrument_action_controller,
|
|
123
|
+
:instrument_action_view,
|
|
124
|
+
:instrument_action_mailer,
|
|
125
|
+
:instrument_active_job,
|
|
126
|
+
:instrument_active_support_cache,
|
|
127
|
+
:instrument_delayed_job,
|
|
128
|
+
:instrument_grape,
|
|
129
|
+
:instrument_solid_queue,
|
|
130
|
+
:instrument_good_job,
|
|
131
|
+
:instrument_resque,
|
|
132
|
+
:instrument_excon,
|
|
133
|
+
:instrument_typhoeus,
|
|
134
|
+
:instrument_dalli,
|
|
135
|
+
:instrument_aws,
|
|
136
|
+
:instrument_stripe,
|
|
137
|
+
:instrument_active_storage,
|
|
138
|
+
:instrument_action_cable,
|
|
139
|
+
:instrument_action_dispatch,
|
|
140
|
+
:instrument_rails_deprecation,
|
|
141
|
+
:instrument_action_mailbox,
|
|
142
|
+
:instrument_railties,
|
|
143
|
+
:http_ignore_hosts,
|
|
144
|
+
:redis_ignore_commands,
|
|
145
|
+
:log_formatter_enabled,
|
|
146
|
+
:log_formatter_colors,
|
|
147
|
+
:log_formatter_hide_assets,
|
|
148
|
+
:log_formatter_compact_assets,
|
|
149
|
+
:log_formatter_show_params,
|
|
150
|
+
:disable_self_tracking,
|
|
151
|
+
:devtools_enabled,
|
|
152
|
+
:devtools_error_page_enabled,
|
|
153
|
+
:devtools_debug_panel_enabled,
|
|
154
|
+
:devtools_allowed_environments,
|
|
155
|
+
:devtools_allowed_ips,
|
|
156
|
+
:devtools_asset_path,
|
|
157
|
+
:devtools_panel_position,
|
|
158
|
+
:devtools_expand_by_default,
|
|
159
|
+
:rails_instrumentation_handled_externally,
|
|
160
|
+
:development_db_path,
|
|
161
|
+
:development_log_output
|
|
162
|
+
|
|
163
|
+
# Services that should not track themselves to avoid circular dependencies
|
|
164
|
+
SELF_TRACKING_SERVICES = {
|
|
165
|
+
'recall' => :recall_enabled,
|
|
166
|
+
'reflex' => :reflex_enabled,
|
|
167
|
+
'pulse' => :pulse_enabled,
|
|
168
|
+
'flux' => :flux_enabled,
|
|
169
|
+
'signal' => :signal_enabled
|
|
170
|
+
}.freeze
|
|
171
|
+
|
|
172
|
+
def initialize
|
|
173
|
+
# SDK enabled flag — set BRAINZLAB_SDK_ENABLED=false to completely disable
|
|
174
|
+
@enabled = ENV.fetch('BRAINZLAB_SDK_ENABLED', 'true') != 'false'
|
|
175
|
+
|
|
176
|
+
# Authentication
|
|
177
|
+
@secret_key = ENV.fetch('BRAINZLAB_SECRET_KEY', nil)
|
|
178
|
+
|
|
179
|
+
# Environment
|
|
180
|
+
@environment = ENV['BRAINZLAB_ENVIRONMENT'] || detect_environment
|
|
181
|
+
@service = ENV.fetch('BRAINZLAB_SERVICE', nil)
|
|
182
|
+
@host = ENV['BRAINZLAB_HOST'] || detect_host
|
|
183
|
+
|
|
184
|
+
# App name for auto-provisioning
|
|
185
|
+
@app_name = ENV.fetch('BRAINZLAB_APP_NAME', nil)
|
|
186
|
+
|
|
187
|
+
# Git context
|
|
188
|
+
@commit = ENV['GIT_COMMIT'] || ENV['COMMIT_SHA'] || detect_git_commit
|
|
189
|
+
@branch = ENV['GIT_BRANCH'] || ENV['BRANCH_NAME'] || detect_git_branch
|
|
190
|
+
|
|
191
|
+
# Debug mode - enables verbose logging
|
|
192
|
+
@debug = ENV['BRAINZLAB_DEBUG'] == 'true'
|
|
193
|
+
|
|
194
|
+
# SDK mode - :production (default) or :development (offline, local storage)
|
|
195
|
+
@mode = ENV['BRAINZLAB_MODE']&.to_sym || :production
|
|
196
|
+
|
|
197
|
+
# Development mode settings
|
|
198
|
+
@development_db_path = ENV['BRAINZLAB_DEV_DB_PATH'] || 'tmp/brainzlab.sqlite3'
|
|
199
|
+
@development_log_output = $stdout
|
|
200
|
+
|
|
201
|
+
# Disable self-tracking - prevents services from tracking to themselves
|
|
202
|
+
# e.g., Recall won't log to itself, Reflex won't track errors to itself
|
|
203
|
+
@disable_self_tracking = ENV.fetch('BRAINZLAB_DISABLE_SELF_TRACKING', 'true') == 'true'
|
|
204
|
+
|
|
205
|
+
# Recall settings
|
|
206
|
+
@recall_enabled = true
|
|
207
|
+
@recall_url = ENV['RECALL_URL'] || detect_product_url('recall')
|
|
208
|
+
@recall_min_level = :debug
|
|
209
|
+
@recall_buffer_size = 50
|
|
210
|
+
@recall_flush_interval = 5
|
|
211
|
+
@recall_master_key = ENV.fetch('RECALL_MASTER_KEY', nil)
|
|
212
|
+
@recall_auto_provision = true
|
|
213
|
+
|
|
214
|
+
# Reflex settings
|
|
215
|
+
@reflex_enabled = true
|
|
216
|
+
@reflex_url = ENV['REFLEX_URL'] || detect_product_url('reflex')
|
|
217
|
+
@reflex_api_key = ENV.fetch('REFLEX_API_KEY', nil)
|
|
218
|
+
@reflex_master_key = ENV.fetch('REFLEX_MASTER_KEY', nil)
|
|
219
|
+
@reflex_auto_provision = true
|
|
220
|
+
@reflex_excluded_exceptions = []
|
|
221
|
+
@reflex_before_send = nil
|
|
222
|
+
@reflex_sample_rate = nil
|
|
223
|
+
@reflex_fingerprint = nil # Custom fingerprint callback
|
|
224
|
+
|
|
225
|
+
# Pulse settings
|
|
226
|
+
@pulse_enabled = true
|
|
227
|
+
@pulse_url = ENV['PULSE_URL'] || detect_product_url('pulse')
|
|
228
|
+
@pulse_api_key = ENV.fetch('PULSE_API_KEY', nil)
|
|
229
|
+
@pulse_master_key = ENV.fetch('PULSE_MASTER_KEY', nil)
|
|
230
|
+
@pulse_auto_provision = true
|
|
231
|
+
@pulse_buffer_size = 50
|
|
232
|
+
@pulse_flush_interval = 5
|
|
233
|
+
@pulse_sample_rate = nil
|
|
234
|
+
@pulse_excluded_paths = %w[/health /ping /up /assets]
|
|
235
|
+
|
|
236
|
+
# Flux settings
|
|
237
|
+
@flux_enabled = true
|
|
238
|
+
@flux_url = ENV['FLUX_URL'] || 'https://flux.brainzlab.ai'
|
|
239
|
+
@flux_api_key = ENV.fetch('FLUX_API_KEY', nil)
|
|
240
|
+
@flux_ingest_key = ENV.fetch('FLUX_INGEST_KEY', nil)
|
|
241
|
+
@flux_master_key = ENV.fetch('FLUX_MASTER_KEY', nil)
|
|
242
|
+
@flux_auto_provision = true
|
|
243
|
+
@flux_buffer_size = 100
|
|
244
|
+
@flux_flush_interval = 5
|
|
245
|
+
|
|
246
|
+
# Signal settings
|
|
247
|
+
@signal_enabled = true
|
|
248
|
+
@signal_url = ENV['SIGNAL_URL'] || detect_product_url('signal')
|
|
249
|
+
@signal_api_key = ENV.fetch('SIGNAL_API_KEY', nil)
|
|
250
|
+
@signal_ingest_key = ENV.fetch('SIGNAL_INGEST_KEY', nil)
|
|
251
|
+
@signal_master_key = ENV.fetch('SIGNAL_MASTER_KEY', nil)
|
|
252
|
+
@signal_auto_provision = true
|
|
253
|
+
|
|
254
|
+
# Vault settings
|
|
255
|
+
@vault_enabled = true
|
|
256
|
+
@vault_url = ENV['VAULT_URL'] || 'https://vault.brainzlab.ai'
|
|
257
|
+
@vault_api_key = ENV.fetch('VAULT_API_KEY', nil)
|
|
258
|
+
@vault_master_key = ENV.fetch('VAULT_MASTER_KEY', nil)
|
|
259
|
+
@vault_auto_provision = true
|
|
260
|
+
@vault_cache_enabled = true
|
|
261
|
+
@vault_cache_ttl = 300 # 5 minutes
|
|
262
|
+
@vault_auto_load = ENV.fetch('VAULT_AUTO_LOAD', 'false') == 'true' # Auto-load secrets into ENV
|
|
263
|
+
@vault_load_provider_keys = true # Also load provider keys (OpenAI, etc.)
|
|
264
|
+
|
|
265
|
+
# Vision settings (AI browser automation)
|
|
266
|
+
@vision_enabled = true
|
|
267
|
+
@vision_url = ENV['VISION_URL'] || 'https://vision.brainzlab.ai'
|
|
268
|
+
@vision_api_key = ENV.fetch('VISION_API_KEY', nil)
|
|
269
|
+
@vision_ingest_key = ENV.fetch('VISION_INGEST_KEY', nil)
|
|
270
|
+
@vision_master_key = ENV.fetch('VISION_MASTER_KEY', nil)
|
|
271
|
+
@vision_auto_provision = true
|
|
272
|
+
@vision_default_model = ENV['VISION_DEFAULT_MODEL'] || 'claude-sonnet-4'
|
|
273
|
+
@vision_default_browser_provider = ENV['VISION_DEFAULT_BROWSER_PROVIDER'] || 'local'
|
|
274
|
+
|
|
275
|
+
# Cortex settings (feature flags)
|
|
276
|
+
@cortex_enabled = true
|
|
277
|
+
@cortex_url = ENV['CORTEX_URL'] || 'https://cortex.brainzlab.ai'
|
|
278
|
+
@cortex_api_key = ENV.fetch('CORTEX_API_KEY', nil)
|
|
279
|
+
@cortex_master_key = ENV.fetch('CORTEX_MASTER_KEY', nil)
|
|
280
|
+
@cortex_auto_provision = true
|
|
281
|
+
@cortex_cache_enabled = true
|
|
282
|
+
@cortex_cache_ttl = 60 # 1 minute
|
|
283
|
+
@cortex_default_context = {}
|
|
284
|
+
|
|
285
|
+
# Beacon settings (uptime monitoring)
|
|
286
|
+
@beacon_enabled = true
|
|
287
|
+
@beacon_url = ENV['BEACON_URL'] || 'https://beacon.brainzlab.ai'
|
|
288
|
+
@beacon_api_key = ENV.fetch('BEACON_API_KEY', nil)
|
|
289
|
+
@beacon_master_key = ENV.fetch('BEACON_MASTER_KEY', nil)
|
|
290
|
+
@beacon_auto_provision = true
|
|
291
|
+
|
|
292
|
+
# Nerve settings (job monitoring)
|
|
293
|
+
@nerve_enabled = true
|
|
294
|
+
@nerve_url = ENV['NERVE_URL'] || 'https://nerve.brainzlab.ai'
|
|
295
|
+
@nerve_api_key = ENV.fetch('NERVE_API_KEY', nil)
|
|
296
|
+
@nerve_master_key = ENV.fetch('NERVE_MASTER_KEY', nil)
|
|
297
|
+
@nerve_auto_provision = true
|
|
298
|
+
|
|
299
|
+
# Dendrite settings (AI documentation)
|
|
300
|
+
@dendrite_enabled = true
|
|
301
|
+
@dendrite_url = ENV['DENDRITE_URL'] || 'https://dendrite.brainzlab.ai'
|
|
302
|
+
@dendrite_api_key = ENV.fetch('DENDRITE_API_KEY', nil)
|
|
303
|
+
@dendrite_master_key = ENV.fetch('DENDRITE_MASTER_KEY', nil)
|
|
304
|
+
@dendrite_auto_provision = true
|
|
305
|
+
|
|
306
|
+
# Sentinel settings (host monitoring)
|
|
307
|
+
@sentinel_enabled = true
|
|
308
|
+
@sentinel_url = ENV['SENTINEL_URL'] || 'https://sentinel.brainzlab.ai'
|
|
309
|
+
@sentinel_api_key = ENV.fetch('SENTINEL_API_KEY', nil)
|
|
310
|
+
@sentinel_agent_key = ENV.fetch('SENTINEL_AGENT_KEY', nil)
|
|
311
|
+
@sentinel_master_key = ENV.fetch('SENTINEL_MASTER_KEY', nil)
|
|
312
|
+
@sentinel_auto_provision = true
|
|
313
|
+
|
|
314
|
+
# Synapse settings (AI development orchestration)
|
|
315
|
+
@synapse_enabled = true
|
|
316
|
+
@synapse_url = ENV['SYNAPSE_URL'] || 'https://synapse.brainzlab.ai'
|
|
317
|
+
@synapse_api_key = ENV.fetch('SYNAPSE_API_KEY', nil)
|
|
318
|
+
@synapse_master_key = ENV.fetch('SYNAPSE_MASTER_KEY', nil)
|
|
319
|
+
@synapse_auto_provision = true
|
|
320
|
+
|
|
321
|
+
# Filtering
|
|
322
|
+
@scrub_fields = %i[password password_confirmation token api_key secret]
|
|
323
|
+
|
|
324
|
+
# Internal logger for debugging SDK issues
|
|
325
|
+
@logger = nil
|
|
326
|
+
|
|
327
|
+
# Debug callbacks
|
|
328
|
+
# Called when an SDK error occurs (lambda/proc receiving error object and context hash)
|
|
329
|
+
@on_error = nil
|
|
330
|
+
# Called before each API request (lambda/proc receiving service, method, path, and payload)
|
|
331
|
+
@on_send = nil
|
|
332
|
+
|
|
333
|
+
# Instrumentation
|
|
334
|
+
@instrument_http = true # Enable HTTP client instrumentation (Net::HTTP, Faraday, HTTParty)
|
|
335
|
+
@instrument_active_record = true # AR breadcrumbs for Reflex
|
|
336
|
+
@instrument_redis = true # Redis command instrumentation
|
|
337
|
+
@instrument_sidekiq = true # Sidekiq job instrumentation
|
|
338
|
+
@instrument_graphql = true # GraphQL query instrumentation
|
|
339
|
+
@instrument_mongodb = true # MongoDB/Mongoid instrumentation
|
|
340
|
+
@instrument_elasticsearch = true # Elasticsearch instrumentation
|
|
341
|
+
@instrument_action_controller = true # ActionController instrumentation (requests, redirects, filters)
|
|
342
|
+
@instrument_action_view = true # ActionView instrumentation (templates, partials, collections)
|
|
343
|
+
@instrument_action_mailer = true # ActionMailer instrumentation
|
|
344
|
+
@instrument_active_job = true # ActiveJob instrumentation (enqueue, perform, retry, discard)
|
|
345
|
+
@instrument_active_support_cache = true # ActiveSupport::Cache instrumentation (read, write, fetch)
|
|
346
|
+
@instrument_delayed_job = true # Delayed::Job instrumentation
|
|
347
|
+
@instrument_grape = true # Grape API instrumentation
|
|
348
|
+
@instrument_solid_queue = true # Solid Queue job instrumentation
|
|
349
|
+
@instrument_good_job = true # GoodJob instrumentation
|
|
350
|
+
@instrument_resque = true # Resque instrumentation
|
|
351
|
+
@instrument_excon = true # Excon HTTP client instrumentation
|
|
352
|
+
@instrument_typhoeus = true # Typhoeus HTTP client instrumentation
|
|
353
|
+
@instrument_dalli = true # Dalli/Memcached instrumentation
|
|
354
|
+
@instrument_aws = true # AWS SDK instrumentation
|
|
355
|
+
@instrument_stripe = true # Stripe API instrumentation
|
|
356
|
+
@instrument_active_storage = true # ActiveStorage instrumentation (uploads, downloads, transforms)
|
|
357
|
+
@instrument_action_cable = true # ActionCable WebSocket instrumentation
|
|
358
|
+
@instrument_action_dispatch = true # ActionDispatch instrumentation (middleware, redirects, requests)
|
|
359
|
+
@instrument_rails_deprecation = true # Rails deprecation warnings tracking
|
|
360
|
+
@instrument_action_mailbox = true # ActionMailbox inbound email processing instrumentation
|
|
361
|
+
@instrument_railties = true # Railties config initializer loading instrumentation
|
|
362
|
+
@http_ignore_hosts = %w[localhost 127.0.0.1]
|
|
363
|
+
@redis_ignore_commands = %w[ping info] # Commands to skip tracking
|
|
364
|
+
|
|
365
|
+
# Log formatter settings
|
|
366
|
+
@log_formatter_enabled = true
|
|
367
|
+
@log_formatter_colors = nil # auto-detect TTY
|
|
368
|
+
@log_formatter_hide_assets = false
|
|
369
|
+
@log_formatter_compact_assets = true
|
|
370
|
+
@log_formatter_show_params = true
|
|
371
|
+
|
|
372
|
+
# DevTools settings (development error page and debug panel)
|
|
373
|
+
@devtools_enabled = true
|
|
374
|
+
@devtools_error_page_enabled = true
|
|
375
|
+
@devtools_debug_panel_enabled = true
|
|
376
|
+
@devtools_allowed_environments = %w[development test]
|
|
377
|
+
@devtools_allowed_ips = ['127.0.0.1', '::1', '172.16.0.0/12', '192.168.0.0/16', '10.0.0.0/8']
|
|
378
|
+
@devtools_asset_path = '/__brainzlab__'
|
|
379
|
+
@devtools_panel_position = 'bottom-right'
|
|
380
|
+
@devtools_expand_by_default = false
|
|
381
|
+
|
|
382
|
+
# Rails instrumentation delegation
|
|
383
|
+
# When true, brainzlab-rails gem handles Rails-specific instrumentation
|
|
384
|
+
# SDK will only install non-Rails instrumentation (HTTP clients, Redis, etc.)
|
|
385
|
+
@rails_instrumentation_handled_externally = false
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def recall_min_level=(level)
|
|
389
|
+
level = level.to_sym
|
|
390
|
+
unless LEVELS.include?(level)
|
|
391
|
+
raise ValidationError.new(
|
|
392
|
+
"Invalid log level: #{level}",
|
|
393
|
+
hint: "Valid log levels are: #{LEVELS.join(', ')}",
|
|
394
|
+
code: 'invalid_log_level',
|
|
395
|
+
field: 'recall_min_level',
|
|
396
|
+
context: { provided: level, valid_values: LEVELS }
|
|
397
|
+
)
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
@recall_min_level = level
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
MODES = %i[production development].freeze
|
|
404
|
+
|
|
405
|
+
def mode=(mode)
|
|
406
|
+
mode = mode.to_sym
|
|
407
|
+
unless MODES.include?(mode)
|
|
408
|
+
raise ValidationError.new(
|
|
409
|
+
"Invalid mode: #{mode}",
|
|
410
|
+
hint: "Valid modes are: #{MODES.join(', ')}. Use :development for offline mode with local storage.",
|
|
411
|
+
code: 'invalid_mode',
|
|
412
|
+
field: 'mode',
|
|
413
|
+
context: { provided: mode, valid_values: MODES }
|
|
414
|
+
)
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
@mode = mode
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
def development_mode?
|
|
421
|
+
@mode == :development
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
def level_enabled?(level)
|
|
425
|
+
LEVELS.index(level.to_sym) >= LEVELS.index(@recall_min_level)
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
def valid?
|
|
429
|
+
@enabled && !@secret_key.nil? && !@secret_key.empty?
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def enabled?
|
|
433
|
+
@enabled == true
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def reflex_valid?
|
|
437
|
+
key = reflex_api_key || secret_key
|
|
438
|
+
!key.nil? && !key.empty?
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
def reflex_auth_key
|
|
442
|
+
reflex_api_key || secret_key
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
def pulse_valid?
|
|
446
|
+
key = pulse_api_key || secret_key
|
|
447
|
+
!key.nil? && !key.empty?
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def pulse_auth_key
|
|
451
|
+
pulse_api_key || secret_key
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
def flux_valid?
|
|
455
|
+
key = flux_ingest_key || flux_api_key || secret_key
|
|
456
|
+
!key.nil? && !key.empty?
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def flux_auth_key
|
|
460
|
+
flux_ingest_key || flux_api_key || secret_key
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
def signal_valid?
|
|
464
|
+
key = signal_ingest_key || signal_api_key || secret_key
|
|
465
|
+
!key.nil? && !key.empty?
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
def signal_auth_key
|
|
469
|
+
signal_ingest_key || signal_api_key || secret_key
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
def vault_valid?
|
|
473
|
+
key = vault_api_key || secret_key
|
|
474
|
+
!key.nil? && !key.empty?
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def vault_auth_key
|
|
478
|
+
vault_api_key || secret_key
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
def vision_valid?
|
|
482
|
+
key = vision_ingest_key || vision_api_key || secret_key
|
|
483
|
+
!key.nil? && !key.empty?
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
def vision_auth_key
|
|
487
|
+
vision_ingest_key || vision_api_key || secret_key
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
def beacon_valid?
|
|
491
|
+
key = beacon_api_key || secret_key
|
|
492
|
+
!key.nil? && !key.empty?
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
def beacon_auth_key
|
|
496
|
+
beacon_api_key || secret_key
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
def nerve_valid?
|
|
500
|
+
key = nerve_api_key || secret_key
|
|
501
|
+
!key.nil? && !key.empty?
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def nerve_auth_key
|
|
505
|
+
nerve_api_key || secret_key
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
def cortex_valid?
|
|
509
|
+
key = cortex_api_key || secret_key
|
|
510
|
+
!key.nil? && !key.empty?
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
def cortex_auth_key
|
|
514
|
+
cortex_api_key || secret_key
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
def dendrite_valid?
|
|
518
|
+
key = dendrite_api_key || secret_key
|
|
519
|
+
!key.nil? && !key.empty?
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
def dendrite_auth_key
|
|
523
|
+
dendrite_api_key || secret_key
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
def sentinel_valid?
|
|
527
|
+
key = sentinel_api_key || secret_key
|
|
528
|
+
!key.nil? && !key.empty?
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
def sentinel_auth_key
|
|
532
|
+
sentinel_api_key || secret_key
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
def synapse_valid?
|
|
536
|
+
key = synapse_api_key || secret_key
|
|
537
|
+
!key.nil? && !key.empty?
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
def synapse_auth_key
|
|
541
|
+
synapse_api_key || secret_key
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
def debug?
|
|
545
|
+
@debug == true
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
# Returns hostnames of all configured SDK service URLs
|
|
549
|
+
# Used by Net::HTTP instrumentation to skip tracking SDK's own HTTP calls
|
|
550
|
+
def sdk_service_hosts
|
|
551
|
+
@sdk_service_hosts ||= begin
|
|
552
|
+
urls = [
|
|
553
|
+
@recall_url, @reflex_url, @pulse_url, @flux_url,
|
|
554
|
+
@signal_url, @vault_url, @vision_url, @cortex_url,
|
|
555
|
+
@beacon_url, @nerve_url, @dendrite_url, @sentinel_url,
|
|
556
|
+
@synapse_url
|
|
557
|
+
].compact
|
|
558
|
+
|
|
559
|
+
urls.filter_map { |url| URI.parse(url).host rescue nil }.uniq
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
# Check if recall is effectively enabled (considering self-tracking)
|
|
564
|
+
def recall_effectively_enabled?
|
|
565
|
+
return false unless @enabled
|
|
566
|
+
return false unless @recall_enabled
|
|
567
|
+
return true unless @disable_self_tracking
|
|
568
|
+
|
|
569
|
+
# Disable if this is the Recall service itself
|
|
570
|
+
normalized_app_name = @app_name.to_s.downcase.strip
|
|
571
|
+
normalized_app_name != 'recall'
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
# Check if reflex is effectively enabled (considering self-tracking)
|
|
575
|
+
def reflex_effectively_enabled?
|
|
576
|
+
return false unless @enabled
|
|
577
|
+
return false unless @reflex_enabled
|
|
578
|
+
return true unless @disable_self_tracking
|
|
579
|
+
|
|
580
|
+
# Disable if this is the Reflex service itself
|
|
581
|
+
normalized_app_name = @app_name.to_s.downcase.strip
|
|
582
|
+
normalized_app_name != 'reflex'
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
# Check if pulse is effectively enabled (considering self-tracking)
|
|
586
|
+
def pulse_effectively_enabled?
|
|
587
|
+
return false unless @enabled
|
|
588
|
+
return false unless @pulse_enabled
|
|
589
|
+
return true unless @disable_self_tracking
|
|
590
|
+
|
|
591
|
+
# Disable if this is the Pulse service itself
|
|
592
|
+
normalized_app_name = @app_name.to_s.downcase.strip
|
|
593
|
+
normalized_app_name != 'pulse'
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
# Check if flux is effectively enabled (considering self-tracking)
|
|
597
|
+
def flux_effectively_enabled?
|
|
598
|
+
return false unless @enabled
|
|
599
|
+
return false unless @flux_enabled
|
|
600
|
+
return true unless @disable_self_tracking
|
|
601
|
+
|
|
602
|
+
# Disable if this is the Flux service itself
|
|
603
|
+
normalized_app_name = @app_name.to_s.downcase.strip
|
|
604
|
+
normalized_app_name != 'flux'
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
# Check if signal is effectively enabled (considering self-tracking)
|
|
608
|
+
def signal_effectively_enabled?
|
|
609
|
+
return false unless @enabled
|
|
610
|
+
return false unless @signal_enabled
|
|
611
|
+
return true unless @disable_self_tracking
|
|
612
|
+
|
|
613
|
+
# Disable if this is the Signal service itself
|
|
614
|
+
normalized_app_name = @app_name.to_s.downcase.strip
|
|
615
|
+
normalized_app_name != 'signal'
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
def debug_log(message)
|
|
619
|
+
return unless debug?
|
|
620
|
+
|
|
621
|
+
log_message = "[BrainzLab::Debug] #{message}"
|
|
622
|
+
if logger
|
|
623
|
+
logger.debug(log_message)
|
|
624
|
+
else
|
|
625
|
+
warn(log_message)
|
|
626
|
+
end
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
private
|
|
630
|
+
|
|
631
|
+
def detect_environment
|
|
632
|
+
return ::Rails.env.to_s if defined?(::Rails) && ::Rails.respond_to?(:env)
|
|
633
|
+
return ENV['RACK_ENV'] if ENV['RACK_ENV']
|
|
634
|
+
return ENV['RUBY_ENV'] if ENV['RUBY_ENV']
|
|
635
|
+
|
|
636
|
+
'development'
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
def detect_host
|
|
640
|
+
require 'socket'
|
|
641
|
+
Socket.gethostname
|
|
642
|
+
rescue StandardError
|
|
643
|
+
nil
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
def detect_git_commit
|
|
647
|
+
result = `git rev-parse HEAD 2>/dev/null`.strip
|
|
648
|
+
result.empty? ? nil : result
|
|
649
|
+
rescue StandardError
|
|
650
|
+
nil
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
def detect_git_branch
|
|
654
|
+
result = `git rev-parse --abbrev-ref HEAD 2>/dev/null`.strip
|
|
655
|
+
result.empty? ? nil : result
|
|
656
|
+
rescue StandardError
|
|
657
|
+
nil
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
def detect_product_url(product)
|
|
661
|
+
# In development, use .localhost domains (works with Traefik)
|
|
662
|
+
# In production, use the real brainzlab.ai domains
|
|
663
|
+
if development?
|
|
664
|
+
"http://#{product}.localhost"
|
|
665
|
+
else
|
|
666
|
+
"https://#{product}.brainzlab.ai"
|
|
667
|
+
end
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
def development?
|
|
671
|
+
@environment == 'development' ||
|
|
672
|
+
ENV['RAILS_ENV'] == 'development' ||
|
|
673
|
+
ENV['RACK_ENV'] == 'development'
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
end
|