Create error handler and helper for streaming to multiple receivers

This commit is contained in:
Oliver Günther
2019-01-22 13:33:18 +01:00
parent cbe310a816
commit 14c6e82882
4 changed files with 129 additions and 0 deletions
@@ -44,6 +44,7 @@ class ApplicationController < ActionController::Base
include HookHelper
include ::OpenProject::Authentication::SessionExpiry
include AdditionalUrlHelpers
include OpenProjectErrorHelper
layout 'base'
+35
View File
@@ -0,0 +1,35 @@
##
# Logging helper to forward to the OpenProject log delegator
# which will log and report errors appropriately.
module OpenProjectErrorHelper
def op_logger
::OpenProject.logger
end
def op_handle_error(message_or_exception, context = {})
::OpenProject.logger.error message_or_exception, context.merge(op_logging_context)
end
def op_handle_warning(message_or_exception, context = {})
::OpenProject.logger.warn message_or_exception, context.merge(op_logging_context)
end
def op_handle_info(message_or_exception, context = {})
::OpenProject.logger.info message_or_exception, context.merge(op_logging_context)
end
def op_handle_debug(message_or_exception, context = {})
::OpenProject.logger.debug message_or_exception, context.merge(op_logging_context)
end
private
def op_logging_context
{
current_user: current_user,
params: params,
request: try(:request),
env: try(:env),
}
end
end
+11
View File
@@ -32,6 +32,7 @@ require 'redmine/menu_manager'
require 'redmine/activity'
require 'redmine/search'
require 'open_project/custom_field_format'
require 'open_project/logging/log_delegator'
require 'redmine/mime_type'
require 'redmine/core_ext'
require 'open_project/design'
@@ -41,3 +42,13 @@ require 'redmine/plugin'
require 'redmine/notifiable'
require 'csv'
module OpenProject
##
# Shortcut to the OpenProject log delegator, which extends
# default Rails error handling with other error handlers such as sentry.
def self.logger
::OpenProject::Logging::LogDelegator
end
end
+82
View File
@@ -0,0 +1,82 @@
module OpenProject
module Logging
class LogDelegator
class << self
##
# Consume a message and let it be handled
# by all handlers
def log(exception, context = {})
message =
if exception.is_a? Exception
context[:exception] = exception
context[:backtrace] = clean_backtrace(exception)
message = "#{exception}: #{exception.message}"
else
exception.to_s
end
# Set current contexts
context[:level] ||= context[:exception] ? :error : :info
context[:current_user] ||= User.current
registered_handlers.each do |handler|
handler.call message, context
end
nil
end
%i(debug info warn error fatal unknown).each do |level|
define_method(level) do |*args|
message = args.shift
context = args.shift || {}
log(message, context.merge(level: level))
end
end
##
# Get a clean backtrace
def clean_backtrace(exception)
return nil unless exception&.backtrace
Rails.backtrace_cleaner.clean exception.backtrace
end
##
# The active set of error handlers
def registered_handlers
@handlers ||= default_handlers
end
private
def default_handlers
[method(:rails_logger_handler)]
end
##
# A lambda handler for logging the error
# to rails.
def rails_logger_handler(message, context = {})
Rails.logger.public_send(
context[:level],
message + context_string(context)
)
if backtrace = context[:backtrace]
Rails.logger.debug { backtrace.join($/) }
end
end
##
# Create a context string
def context_string(context)
''.tap do |str|
str << " [user=#{context[:user].id}]" if context[:user]
end
end
end
end
end
end