OpenProject is the leading open source project management software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openproject/lib/open_project/logging/sentry_logger.rb

85 lines
2.6 KiB

module OpenProject
module Logging
class SentryLogger
class << self
##
# Capture a message to sentry
def log(message, log_context = {})
Sentry.configure_scope do |sentry_scope|
build_sentry_context(sentry_scope, log_context.to_h)
if log_context[:exception]
Sentry.capture_exception(log_context[:exception])
else
Sentry.capture_message(message, level: sentry_level(log_context[:level]))
end
end
end
##
# Whether sentry logging is enabled?
def enabled?
sentry_dsn.present?
end
##
# Sentry logging DSN
def sentry_dsn
@sentry_dsn ||= OpenProject::Configuration.sentry_dsn.presence || ENV["SENTRY_DSN"].presence
end
private
##
# Build the sentry warning level from context
#
# Sentry uses "warning" as the warn level
# and is consistent with rails otherwise
def sentry_level(level)
return 'warning' if level.to_s == 'warn'
level
end
##
# Build the sentry context from the openproject logging context
def build_sentry_context(sentry_scope, log_context)
if (user = log_context[:current_user])
sentry_scope.set_user id: user.id, email: user.mail, username: user.login.presence || 'unknown'
sentry_scope.set_tags 'user.locale': user.language.presence || Setting.default_language
end
if (params = log_context[:params])
sentry_scope.set_context 'params', filter_params(params)
end
if (rack_env = log_context[:request]&.env)
sentry_scope.set_rack_env(rack_env)
end
if (ref = log_context[:reference])
sentry_scope.set_fingerprint [ref]
end
sentry_scope.set_tags code_origin: 'backend'
# Collect extra information from payload extender
# e.g., with saas tenant information
extra = ::OpenProject::Logging.extend_payload! log_context[:extra] || {}, { sentry_scope: sentry_scope }
sentry_scope.set_extras extra
end
def filter_params(params)
f = ActiveSupport::ParameterFilter.new(Rails.application.config.filter_parameters)
res = f.filter(params)
# make sure to return plain hash rather than ActionController::Parameters
res.respond_to?(:to_unsafe_h) ? res.to_unsafe_h : res.to_h
rescue StandardError => e
{ filter_failed: e.message }
end
end
end
end
end