fix: improve apm error reporting

Previously, errors were only being logged with logger.info and rendered
as JSON responses, but weren't being properly reported to APM services.
This meant that critical errors like 500s were only visible in application
logs but not in our monitoring systems, making it harder to track and debug
issues in production.

This commit ensures that all errors are properly reported to configured
APM services by:
1. Adding explicit APM error reporting alongside logging
2. Using proper APM reporting methods for each service
3. Maintaining consistent error handling across all APM integrations

These changes ensure that errors are properly captured in our monitoring
systems,improving our ability to track and debug production issues.
This commit is contained in:
Vishnu Narayanan
2025-03-25 00:36:40 +05:30
parent 07d19362d2
commit f32daa96ab
@@ -23,24 +23,29 @@ module RequestExceptionHandler
Current.reset
end
def render_error(message, status, error = nil)
log_handled_error(error) if error
render json: { error: message }, status: status
end
def render_unauthorized(message)
render json: { error: message }, status: :unauthorized
render_error(message, :unauthorized)
end
def render_not_found_error(message)
render json: { error: message }, status: :not_found
render_error(message, :not_found)
end
def render_could_not_create_error(message)
render json: { error: message }, status: :unprocessable_entity
render_error(message, :unprocessable_entity)
end
def render_payment_required(message)
render json: { error: message }, status: :payment_required
render_error(message, :payment_required)
end
def render_internal_server_error(message)
render json: { error: message }, status: :internal_server_error
render_error(message, :internal_server_error)
end
def render_record_invalid(exception)
@@ -57,6 +62,23 @@ module RequestExceptionHandler
end
def log_handled_error(exception)
return unless exception
logger.info("Handled error: #{exception.inspect}")
report_to_apms(exception)
end
def report_to_apms(exception)
apm_reporters = {
::NewRelic::Agent => -> { ::NewRelic::Agent.notice_error(exception) },
::Datadog::Tracing => -> { ::Datadog::Tracing.active_span&.set_error(exception) },
::ElasticAPM => -> { ::ElasticAPM.report(exception) },
::ScoutApm::Error => -> { ::ScoutApm::Error.capture(exception) },
::Sentry => -> { ::Sentry.capture_exception(exception) }
}
apm_reporters.each do |apm_module, reporter|
reporter.call if defined?(apm_module)
end
end
end