kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
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.
118 lines
3.3 KiB
118 lines
3.3 KiB
module OpenProject
|
|
module Logging
|
|
class LogDelegator
|
|
class << self
|
|
##
|
|
# Consume a message and let it be handled
|
|
# by all handlers
|
|
def log(exception, context = {})
|
|
# Doing the following because this is called with ActionController::Parameters from somewhere
|
|
# which leads to "failed to delegate" errors below ('expect the argument to be a Hash').
|
|
if context.respond_to?(:to_unsafe_h)
|
|
context = context.to_unsafe_h
|
|
else
|
|
context = context.to_h.dup
|
|
end
|
|
|
|
message =
|
|
if exception.is_a? Exception
|
|
context[:exception] = exception
|
|
"#{exception}: #{exception.message}"
|
|
else
|
|
exception.to_s
|
|
end
|
|
|
|
# Mark backtrace
|
|
if context[:exception]
|
|
context[:backtrace] = clean_backtrace(context[:exception])
|
|
end
|
|
|
|
# Set current contexts
|
|
context[:level] ||= context[:exception] ? :error : :info
|
|
context[:current_user] ||= User.current
|
|
|
|
registered_handlers.values.each do |handler|
|
|
handler.call message, context
|
|
rescue StandardError => e
|
|
Rails.logger.error "Failed to delegate log to #{handler.inspect}: #{e.inspect}\nMessage: #{message.inspect}"
|
|
end
|
|
|
|
nil
|
|
rescue StandardError => e
|
|
Rails.logger.error "Failed to process log message #{exception.inspect}: #{e.inspect}"
|
|
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, :full
|
|
end
|
|
|
|
##
|
|
# The active set of error handlers
|
|
def registered_handlers
|
|
@handlers ||= default_handlers
|
|
end
|
|
|
|
##
|
|
# Register a new handler
|
|
def register(key, handler)
|
|
raise "#{key} already registered" if registered_handlers.key?(key)
|
|
raise "handler must respond_to #call" unless handler.respond_to?(:call)
|
|
|
|
@handlers[key] = handler
|
|
end
|
|
|
|
##
|
|
# Create a payload for lograge from a controller request line
|
|
def controller_payload_hash(_controller)
|
|
{
|
|
user: User.current.try(:id)
|
|
}
|
|
end
|
|
|
|
private
|
|
|
|
def default_handlers
|
|
{ rails_logger: 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],
|
|
"#{context_string(context)} #{message}"
|
|
)
|
|
end
|
|
|
|
##
|
|
# Create a context string
|
|
def context_string(context)
|
|
%i[current_user project reference]
|
|
.map do |key|
|
|
value = context[key]
|
|
|
|
if value
|
|
"[#{key}=#{value}]"
|
|
end
|
|
end
|
|
.compact
|
|
.join(' ')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|