feat(yabeda): Add sentry-yabeda adapter gem#2925
Conversation
Introduces sentry-yabeda, a Yabeda adapter that forwards metrics to Sentry. Covers all four Yabeda metric types (counter, gauge, histogram, summary), a periodic collector to drive gauge collection in push-based environments, and a full spec suite including unit and integration tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Endless method syntax (def m() = val) requires Ruby 3.0+. Replace with conventional empty method bodies (def m; end) so RuboCop using the Ruby 2.7 parser does not reject the file. Co-Authored-By: Claude Sonnet 4.6 <noreply@example.com>
The app is configured as api_only but inherited from ActionController::Base, which includes CSRF protection middleware. Switch to ActionController::API to align with the api_only setting and eliminate the CSRF warning. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| class ApplicationController < ActionController::API | ||
| around_action :track_metrics | ||
|
|
||
| private | ||
|
|
||
| def track_metrics | ||
| start = Process.clock_gettime(Process::CLOCK_MONOTONIC) | ||
| yield | ||
| ensure | ||
| duration_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000 | ||
| Yabeda.app.request_duration.measure( | ||
| { controller: controller_name, action: action_name }, | ||
| duration_ms | ||
| ) | ||
| Yabeda.app.requests_total.increment( | ||
| { controller: controller_name, action: action_name, status: response.status.to_s } | ||
| ) | ||
| end | ||
| end |
Check failure
Code scanning / CodeQL
CSRF protection not enabled High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 5 hours ago
In general, to fix this type of issue in a Rails app you either (1) enable CSRF protection on controllers that are used with browser sessions, typically via protect_from_forgery with: :exception, or (2) if the app is a stateless API where CSRF is not applicable (e.g., no cookie auth), you make that explicit by inheriting from ActionController::API and disabling session/cookie use, or by documenting/structuring the API to use header‑based tokens instead. For a hybrid or small app, the safest approach when unsure is to enable CSRF protection in the base controller and, if necessary, skip it on specific JSON endpoints that are truly stateless.
For this specific file, the minimal change that addresses CodeQL’s concern without altering existing runtime behavior more than necessary is to (a) add protect_from_forgery with: :exception to ApplicationController and (b) because ApplicationController currently inherits from ActionController::API, explicitly include ActionController::RequestForgeryProtection to make protect_from_forgery available and functional. This keeps the app API‑only (no automatic cookie/session middleware is introduced by changing the superclass) but still provides CSRF protection for any endpoints that do use cookies/session. If, in the broader project, some controllers or actions should remain exempt, they can individually call skip_forgery_protection, but we will not assume that here.
Concretely:
- Edit
spec/apps/yabeda-mini/app.rbwhereApplicationControlleris defined. - Inside
ApplicationController, includeActionController::RequestForgeryProtection. - Add a
protect_from_forgery with: :exceptioncall (at the top of the class, before filters). - Keep the existing
around_action :track_metricsand all other logic unchanged.
No other files need changes based on the provided snippet.
| @@ -101,6 +101,8 @@ | ||
|
|
||
| # Controllers | ||
| class ApplicationController < ActionController::API | ||
| include ActionController::RequestForgeryProtection | ||
| protect_from_forgery with: :exception | ||
| around_action :track_metrics | ||
|
|
||
| private |
Sentry Ruby gem that connects Yabeda metrics to Sentry Metrics.
What it does
counter➡️Sentry.metrics.countgauge➡️Sentry.metrics.gaugehistogram/summary➡️Sentry.metrics.distributionYabeda.collect!(needed because Yabeda is pull-based, while Sentry is push-based).
start_collector!andstop_collector!to control this worker (must run afterSentry.init).Fixes RUBY-161
Fixes #2899