brainzlab 0.1.33 → 0.1.35

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -0
  3. data/lib/brainzlab/beacon/client.rb +4 -6
  4. data/lib/brainzlab/configuration.rb +363 -258
  5. data/lib/brainzlab/cortex/client.rb +4 -6
  6. data/lib/brainzlab/debug.rb +6 -6
  7. data/lib/brainzlab/dendrite/client.rb +4 -6
  8. data/lib/brainzlab/development/logger.rb +2 -2
  9. data/lib/brainzlab/development/store.rb +2 -4
  10. data/lib/brainzlab/devtools/middleware/error_page.rb +1 -1
  11. data/lib/brainzlab/errors.rb +5 -12
  12. data/lib/brainzlab/instrumentation/action_cable.rb +4 -4
  13. data/lib/brainzlab/instrumentation/action_controller.rb +12 -12
  14. data/lib/brainzlab/instrumentation/action_dispatch.rb +1 -1
  15. data/lib/brainzlab/instrumentation/action_mailbox.rb +7 -13
  16. data/lib/brainzlab/instrumentation/action_view.rb +29 -33
  17. data/lib/brainzlab/instrumentation/active_job.rb +6 -10
  18. data/lib/brainzlab/instrumentation/active_record.rb +53 -25
  19. data/lib/brainzlab/instrumentation/active_storage.rb +4 -4
  20. data/lib/brainzlab/instrumentation/active_support_cache.rb +6 -8
  21. data/lib/brainzlab/instrumentation/aws.rb +10 -7
  22. data/lib/brainzlab/instrumentation/grape.rb +37 -2
  23. data/lib/brainzlab/instrumentation/rails_deprecation.rb +1 -1
  24. data/lib/brainzlab/instrumentation/railties.rb +2 -2
  25. data/lib/brainzlab/nerve/client.rb +4 -6
  26. data/lib/brainzlab/pulse/client.rb +1 -1
  27. data/lib/brainzlab/pulse/explain_capture.rb +123 -0
  28. data/lib/brainzlab/pulse.rb +6 -1
  29. data/lib/brainzlab/rails/railtie.rb +1 -3
  30. data/lib/brainzlab/reflex/client.rb +1 -1
  31. data/lib/brainzlab/sentinel/client.rb +4 -6
  32. data/lib/brainzlab/signal/client.rb +16 -2
  33. data/lib/brainzlab/signal.rb +8 -0
  34. data/lib/brainzlab/synapse/client.rb +4 -6
  35. data/lib/brainzlab/testing/event_store.rb +3 -3
  36. data/lib/brainzlab/testing/matchers.rb +4 -4
  37. data/lib/brainzlab/testing.rb +5 -3
  38. data/lib/brainzlab/utilities/route_path_normalizer.rb +91 -0
  39. data/lib/brainzlab/utilities.rb +1 -0
  40. data/lib/brainzlab/vault/client.rb +4 -6
  41. data/lib/brainzlab/version.rb +1 -1
  42. data/lib/brainzlab/vision/client.rb +3 -3
  43. data/lib/brainzlab.rb +1 -0
  44. data/lib/fluyenta-ruby.rb +1 -1
  45. metadata +3 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9a9a15a426d4a6853086c9a36851e57bd14736c5d11dbeb70fb510fe5fc1c10
4
- data.tar.gz: 19f26af342b3d9150eacb2615da08fa063cc671388f7b97a87b207cd210cf6fc
3
+ metadata.gz: bf1207ec18676d63267312a25c4bcbe2519a1ddc70ceb5bb34ac58f7a83e29d2
4
+ data.tar.gz: d8ea421af25cae73f94d4741eed9a404c6297477088eaf3df9b4a000675824da
5
5
  SHA512:
6
- metadata.gz: b149c1fbf2c0f13fa34d0b2d2e6df634a1dc01f087f8174ba58fcc0bf05ea0301365721131e03441bf0af7e3b443d5a86acc5dfa141ba4fa9af2c24c610782a9
7
- data.tar.gz: 737cd856a43c4c3555a566653692fd32d04798e464e24bad80d189610b82e81c0d0b2860cda232fae66063477b21687858c14e5178050a771af6745b9741d46f
6
+ metadata.gz: 2bee3ad0497520af5744ccd898360f389ac30bf599382d4af14f871d2b1f30659a5879a8ad5a6dfcfd1bf008445e0262a1d2fa5887d00146128099cda99410b3
7
+ data.tar.gz: 0760d616e2b3a32c2c408098d5a69d4a68d3d3ab52f3dbde121d2994c4498bb5c26cbc24fd6d569a3f41d6614cceca3075a9f06df1bbdea1bd5f9da399da2861
data/README.md CHANGED
@@ -198,6 +198,44 @@ config.pulse_excluded_paths = ['/health', '/ping', '/up', '/assets']
198
198
  config.pulse_sample_rate = 1.0 # 1.0 = 100%
199
199
  ```
200
200
 
201
+ ### Query plans (EXPLAIN)
202
+
203
+ Off by default. When enabled, a query slower than the threshold gets an
204
+ `EXPLAIN` run against your own database and the plan travels with the span, so
205
+ Pulse can tell you *why* a query is slow instead of only that it is.
206
+
207
+ ```ruby
208
+ config.pulse_explain_enabled = true # default: false
209
+ config.pulse_explain_threshold = 500 # ms; defaults to slow_query_threshold
210
+ config.pulse_explain_timeout = 2 # seconds to wait for a plan
211
+ ```
212
+
213
+ Or via environment: `BRAINZLAB_PULSE_EXPLAIN_ENABLED`,
214
+ `BRAINZLAB_PULSE_EXPLAIN_THRESHOLD`, `BRAINZLAB_PULSE_EXPLAIN_TIMEOUT`.
215
+
216
+ What it will and will not do:
217
+
218
+ - **Read-only statements only.** A write is never explained.
219
+ - **Plain `EXPLAIN`, never `EXPLAIN ANALYZE`** — the statement is planned, not run.
220
+ - **One plan per distinct statement**, not one per occurrence.
221
+ - **A timeout**, so a slow planner cannot stall a request.
222
+ - **Failures are swallowed.** If the database refuses the `EXPLAIN`, the span is
223
+ recorded without a plan; instrumentation never breaks the app.
224
+
225
+ It does issue one extra query per newly-seen slow statement, which is why you opt
226
+ in rather than opt out.
227
+
228
+ ### Configuration validation
229
+
230
+ `BrainzLab.configure` validates the configuration when your block finishes and
231
+ raises `BrainzLab::ConfigurationError` listing everything that is wrong, rather
232
+ than letting a typo turn into missing telemetry. The common one:
233
+
234
+ ```ruby
235
+ config.pulse_sample_rate = 50 # raises — sample rates are fractions
236
+ config.pulse_sample_rate = 0.5 # 50%
237
+ ```
238
+
201
239
  ### Distributed Tracing
202
240
 
203
241
  Pulse supports distributed tracing across services using W3C Trace Context and B3 propagation.
@@ -204,9 +204,9 @@ module BrainzLab
204
204
  BrainzLab.debug_log("[Beacon::Client] #{operation} failed: #{structured_error.message}")
205
205
 
206
206
  # Call on_error callback if configured
207
- if @config.on_error
208
- @config.on_error.call(structured_error, { service: 'Beacon', operation: operation })
209
- end
207
+ return unless @config.on_error
208
+
209
+ @config.on_error.call(structured_error, { service: 'Beacon', operation: operation })
210
210
  end
211
211
 
212
212
  def handle_response_error(response, operation)
@@ -216,9 +216,7 @@ module BrainzLab
216
216
  BrainzLab.debug_log("[Beacon::Client] #{operation} failed: #{structured_error.message}")
217
217
 
218
218
  # Call on_error callback if configured
219
- if @config.on_error
220
- @config.on_error.call(structured_error, { service: 'Beacon', operation: operation })
221
- end
219
+ @config.on_error&.call(structured_error, { service: 'Beacon', operation: operation })
222
220
 
223
221
  structured_error
224
222
  end