diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b16ed049..8b9a45a9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -4,6 +4,8 @@ class ApplicationController < ActionController::Base include ApplicationHelper include Pagy::Backend before_action :authenticate_user! + before_action :set_sentry_context + # Custom flash logging (optional) def flash @@ -64,4 +66,13 @@ def log_exception(exception) logger.error("!!!!!!! StandardError: #{exception.class} - #{exception.message}") logger.error(exception.backtrace.join("\n")) end + + def set_sentry_context + Sentry.set_user(id: current_user.id, email: current_user.email) if current_user + Sentry.set_context('request', { + controller: controller_name, + action: action_name, + params: params.except(:controller, :action) + }) + end end diff --git a/app/helpers/sentry_helper.rb b/app/helpers/sentry_helper.rb new file mode 100644 index 00000000..7aa73495 --- /dev/null +++ b/app/helpers/sentry_helper.rb @@ -0,0 +1,9 @@ +module SentryHelper + def set_sentry_user(user) + Sentry.set_user(id: user.id, email: user.email) + end + + def set_sentry_context(key, value) + Sentry.set_context(key, value) + end +end diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb index 772b5870..7e93053b 100644 --- a/config/initializers/sentry.rb +++ b/config/initializers/sentry.rb @@ -7,11 +7,22 @@ # Only enable in production and staging environments config.enabled_environments = %w[production staging] + # Environment-specific configuration + config.environment = Rails.env + config.release = Rails.application.class.module_parent_name.underscore.dasherize + # Logging configuration config.breadcrumbs_logger = [ :active_support_logger, :http_logger ] - # Add user context data (PII) - config.send_default_pii = true + # Enable logging integration (this is the correct way for sentry-rails) + # The sentry-rails gem automatically integrates with Rails logger + # To send logs to Sentry, use: Sentry.capture_message("Your log message", level: :info) + + # Add user context data (PII) - be careful with this in production + config.send_default_pii = Rails.env.development? || Rails.env.test? + + # Server name for better debugging + config.server_name = Socket.gethostname # Performance monitoring # In production, you might want to lower this to something like 0.1 (10%) @@ -33,14 +44,42 @@ end # Add additional context to errors - config.before_send = lambda do |event, hint| - # You can add custom data here + config.before_send = lambda do |event, _hint| + # Add request context + if event.request + event.request.data = { + user_agent: event.request.headers['User-Agent'], + referer: event.request.headers['Referer'], + remote_addr: event.request.headers['X-Forwarded-For'] || event.request.headers['Remote-Addr'] + } + end + + # Add user context if available if defined?(Current) && Current.user event.user = { id: Current.user.id, - email: Current.user.email + email: Current.user.email, + username: Current.user.try(:username) } end + + # Add custom tags + event.tags = event.tags.merge( + environment: Rails.env, + version: Rails.application.class.module_parent_name.underscore.dasherize + ) + + # Filter out sensitive data + if event.exception + event.exception.values.each do |exception| + next unless exception.value + # Remove potential passwords, tokens, etc. + exception.value.gsub!(/password[=:]\s*[^\s&]+/i, 'password=[FILTERED]') + exception.value.gsub!(/token[=:]\s*[^\s&]+/i, 'token=[FILTERED]') + exception.value.gsub!(/secret[=:]\s*[^\s&]+/i, 'secret=[FILTERED]') + end + end + event end @@ -48,4 +87,35 @@ config.backtrace_cleanup_callback = lambda do |backtrace| Rails.backtrace_cleaner.clean(backtrace) end + + # Configure error filtering + config.before_send_transaction = lambda do |event, _hint| + # Filter out health check transactions + return nil if event.transaction&.include?('health_check') + + # Filter out static asset requests + return nil if event.transaction&.match?(/\.(css|js|png|jpg|jpeg|gif|ico|svg)$/) + + event + end + + # Configure breadcrumb filtering + config.before_breadcrumb = lambda do |breadcrumb, _hint| + # Filter out sensitive breadcrumbs + return nil if breadcrumb.message&.match?(/password|token|secret/i) + + # Filter out noisy breadcrumbs + return nil if breadcrumb.message&.match?(/SELECT.*FROM.*users/i) + + breadcrumb + end + + # Configure sampling for different types of events + config.sample_rate = Rails.env.production? ? 0.1 : 1.0 + + # Configure max breadcrumbs + config.max_breadcrumbs = 50 + + # Configure debug mode (only in development) + config.debug = Rails.env.development? end