mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-05 11:23:47 +08:00
Follow up to 7c8139ec50
Can't parse the header at the rails level as it seems like some browser
doesn't conform to the right format.
180 lines
6.2 KiB
Ruby
180 lines
6.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
if ENV["ENABLE_LOGSTASH_LOGGER"] == "1"
|
|
require "lograge"
|
|
|
|
Rails.application.config.after_initialize do
|
|
def unsubscribe(component_name, subscriber)
|
|
subscriber
|
|
.public_methods(false)
|
|
.reject { |method| method.to_s == "call" }
|
|
.each do |event|
|
|
ActiveSupport::Notifications
|
|
.notifier
|
|
.all_listeners_for("#{event}.#{component_name}")
|
|
.each do |listener|
|
|
if listener
|
|
.instance_variable_get("@delegate")
|
|
.class
|
|
.to_s
|
|
.start_with?("#{component_name.to_s.classify}::LogSubscriber")
|
|
ActiveSupport::Notifications.unsubscribe listener
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# This is doing what the `lograge` gem is doing but has stopped working after we upgraded to Rails 7.1 and the `lograge`
|
|
# gem does not seem to be maintained anymore so we're shipping our own fix. In the near term, we are considering
|
|
# dropping the lograge gem and just port the relevant code to our codebase.
|
|
#
|
|
# Basically, this code silences log events coming from `ActionView::Logsubscriber` and `ActionController::LogSubscriber`
|
|
# since those are just noise.
|
|
ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
|
|
case subscriber
|
|
when ActionView::LogSubscriber
|
|
unsubscribe(:action_view, subscriber)
|
|
when ActionController::LogSubscriber
|
|
unsubscribe(:action_controller, subscriber)
|
|
end
|
|
end
|
|
end
|
|
|
|
Rails.application.config.to_prepare do
|
|
if Rails.configuration.multisite
|
|
Rails.logger.formatter =
|
|
ActiveSupport::Logger::SimpleFormatter.new.extend(ActiveSupport::TaggedLogging::Formatter)
|
|
end
|
|
|
|
Rails.application.configure do
|
|
config.lograge.enabled = true
|
|
|
|
# Monkey patch Rails::Rack::Logger#logger to silence its logs.
|
|
# The `lograge` gem is supposed to do this but it broke after we upgraded to Rails 7.1.
|
|
# This patch is a temporary workaround until we find a proper fix.
|
|
Rails::Rack::Logger.prepend(Module.new { def logger = (@logger ||= Logger.new(IO::NULL)) })
|
|
|
|
Lograge.ignore(
|
|
lambda do |event|
|
|
# this is our hijack magic status,
|
|
# no point logging this cause we log again
|
|
# direct from hijack
|
|
event.payload[:status] == 418
|
|
end,
|
|
)
|
|
|
|
config.lograge.custom_payload do |controller|
|
|
begin
|
|
username =
|
|
begin
|
|
controller.current_user&.username if controller.respond_to?(:current_user)
|
|
rescue Discourse::InvalidAccess, Discourse::ReadOnly, ActiveRecord::ReadOnlyError
|
|
nil
|
|
end
|
|
|
|
ip =
|
|
begin
|
|
controller.request.remote_ip
|
|
rescue ActionDispatch::RemoteIp::IpSpoofAttackError
|
|
nil
|
|
end
|
|
|
|
{ ip: ip, username: username }
|
|
rescue => e
|
|
Rails.logger.warn(
|
|
"Failed to append custom payload: #{e.message}\n#{e.backtrace.join("\n")}",
|
|
)
|
|
{}
|
|
end
|
|
end
|
|
|
|
config.lograge.custom_options =
|
|
lambda do |event|
|
|
begin
|
|
exceptions = %w[controller action format id]
|
|
|
|
params = event.payload[:params].except(*exceptions)
|
|
|
|
if (file = params[:file]) && file.respond_to?(:headers)
|
|
params[:file] = file.headers
|
|
end
|
|
|
|
if (files = params[:files]) && files.respond_to?(:map)
|
|
params[:files] = files.map { |f| f.respond_to?(:headers) ? f.headers : f }
|
|
end
|
|
|
|
output = {
|
|
params: params.to_query,
|
|
database: RailsMultisite::ConnectionManagement.current_db,
|
|
}
|
|
|
|
if ENV["LOGRAGE_INCLUDE_HTTP_ACCEPT_LANGUAGE_HEADER"] == "1" &&
|
|
(
|
|
http_accept_language_request_header =
|
|
event.payload[:headers]["HTTP_ACCEPT_LANGUAGE"]
|
|
).present?
|
|
output["request.headers.http_accept_language"] = http_accept_language_request_header
|
|
end
|
|
|
|
if data = (Thread.current[:_method_profiler] || event.payload[:timings])
|
|
if sql = data[:sql]
|
|
output[:db] = sql[:duration] * 1000
|
|
output[:db_calls] = sql[:calls]
|
|
end
|
|
|
|
if redis = data[:redis]
|
|
output[:redis] = redis[:duration] * 1000
|
|
output[:redis_calls] = redis[:calls]
|
|
end
|
|
|
|
if net = data[:net]
|
|
output[:net] = net[:duration] * 1000
|
|
output[:net_calls] = net[:calls]
|
|
end
|
|
|
|
# MethodProfiler.stop is called after this lambda, so the delta
|
|
# must be computed here.
|
|
if data[:__start_gc_heap_live_slots]
|
|
output[:heap_live_slots] = GC.stat[:heap_live_slots] -
|
|
data[:__start_gc_heap_live_slots]
|
|
end
|
|
end
|
|
|
|
output
|
|
rescue RateLimiter::LimitExceeded
|
|
# no idea who this is, but they are limited
|
|
{}
|
|
rescue => e
|
|
Rails.logger.warn(
|
|
"Failed to append custom options: #{e.message}\n#{e.backtrace.join("\n")}",
|
|
)
|
|
{}
|
|
end
|
|
end
|
|
|
|
config.lograge.formatter = Lograge::Formatters::Logstash.new
|
|
|
|
require "discourse_logstash_logger"
|
|
|
|
config.lograge.logger =
|
|
DiscourseLogstashLogger.logger(
|
|
logdev: Rails.root.join("log", "#{Rails.env}.log"),
|
|
type: :rails,
|
|
customize_event:
|
|
lambda { |event| event["database"] = RailsMultisite::ConnectionManagement.current_db },
|
|
level: Rails.application.config.log_level,
|
|
)
|
|
|
|
config.lograge.log_level = Rails.application.config.log_level
|
|
|
|
# Stop broadcasting to Rails' default logger
|
|
Rails.logger.stop_broadcasting_to(
|
|
Rails.logger.broadcasts.find { |logger| logger.is_a?(ActiveSupport::Logger) },
|
|
)
|
|
|
|
Logster.logger.subscribe do |severity, message, progname, opts, &block|
|
|
config.lograge.logger.add_with_opts(severity, message, progname, opts, &block)
|
|
end
|
|
end
|
|
end
|
|
end
|