Last active
August 29, 2015 13:57
-
-
Save kares/9374772 to your computer and use it in GitHub Desktop.
Silencing a Rails.logger is (still) not thread-safe ... these initializers will try it's best to avoid your loggers being silenced (and more)! Must have for JRuby.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# put this under **#{Rails.root}/config/initializers** directory | |
# `silence` is like Chuck Norris you can't kill it, this biuty got yet again | |
# re-invented in Rails 4 right after Logger#silence got deprecated in 3.2 :) | |
begin | |
require 'active_support/logger' | |
require 'active_support/logger_silence' | |
ActiveSupport::Logger.silencer = false # silence simply yields | |
# if 'active_support/core_ext/logger' is loaded | |
# the LoggerSilencer gets included into Logger | |
Logger.silencer = false if Logger.respond_to?(:silencer) | |
rescue LoadError | |
begin | |
require 'active_support/buffered_logger' | |
ActiveSupport::BufferedLogger.silencer = false | |
rescue LoadError | |
end | |
# it's deprecated since 4.0 but not on 3.2 (been around since 2.3) | |
require 'active_support/core_ext/logger' | |
Logger.silencer = false | |
end | |
# the final frontier is ActiveRecord::Base.silence (2.3 - 3.2) | |
# used mostly in ActiveRecord::SessionStore, that one comes | |
# from "abusing" the extended ActiveSupport::Benchmarkable | |
if ActiveSupport.const_defined?(:Benchmarkable) | |
ActiveSupport::Benchmarkable.module_eval do | |
# NOTE: there's no other way but to monkey-patch : | |
def silence | |
# if the logger manages to handle silence "thread-safe" | |
# it will work, otherwise the logger's silencer = false | |
if ( logger = self.logger ).respond_to?(:silence) | |
logger.silence { yield } | |
else | |
yield | |
end | |
end | |
end | |
else | |
ActiveRecord::Base.class_eval do | |
# Method implemented directly on AR::Base (2.3) : | |
def self.silence | |
# if the logger manages to handle silence thread-safe | |
# it will work, otherwise the logger's silencer = false | |
if ( logger = self.logger ).respond_to?(:silence) | |
logger.silence { yield } | |
else | |
yield | |
end | |
end | |
end if defined? ActiveRecord::Base.silence | |
end | |
# NOTE: a "simple" alternative for all of the above might be : | |
# | |
# logger = Rails.logger; def logger.level=(level) end | |
# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
begin | |
require 'active_support/core_ext/kernel/reporting' | |
rescue LoadError | |
end | |
module Kernel | |
def warn(message) | |
super if is_current_thread_verbose? | |
end | |
def silence_warnings | |
verbose = is_current_thread_verbose? | |
set_current_thread_verbose(false) | |
yield | |
ensure | |
set_current_thread_verbose(verbose) | |
end | |
def enable_warnings | |
verbose = is_current_thread_verbose? | |
set_current_thread_verbose(true) | |
yield | |
ensure | |
set_current_thread_verbose(verbose) | |
end | |
# used from methods such as {#quietly} : | |
# silence_stream(STDOUT) do | |
# silence_stream(STDERR) do | |
# yield | |
# end | |
# end | |
# or {#silence_stderr} `silence_stream(STDERR) { yield }` | |
def silence_stream(stream) | |
do_silence_stream!(stream, true) | |
yield | |
ensure | |
do_silence_stream!(stream, false) | |
end | |
# since AS 3.1 {#silence} is aliased as {#capture}, | |
# we leave `capture` as is but "re-invent" `silence` | |
def silence(stream); silence_stream(stream); nil end | |
private | |
# a `$VERBOSE = verbose` replacement | |
def set_current_thread_verbose(verbose) | |
verbose # not implemented | |
end | |
def is_current_thread_verbose? | |
$VERBOSE | |
end | |
# a `$VERBOSE = verbose` replacement | |
def do_silence_stream!(stream, silence) | |
return stream if silence || true # not implemented | |
end | |
end if defined? Kernel.silence_stream |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@kares Thanks for the clarification. On Puma this issue is very frequent. When I changed Puma configuration to one Thread per Process, this problem disappeared.
So if we have to use Puma with Threading even on MRI your Gist is necessary.
I am curious about how your Gist impacts the amount logs that get generated. Will keep you posted on how it goes.