Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Honor Logger#level overrides #41

Merged
merged 1 commit into from
Sep 10, 2019
Merged

Honor Logger#level overrides #41

merged 1 commit into from
Sep 10, 2019

Conversation

georgeclaghorn
Copy link
Contributor

We attempt to override Logger#level in Rails’s Logger subclass to allow setting a different level per thread (and thus per request). But Logger#add checks the new message’s severity against the @level instance variable, so overriding #level doesn’t have the intended effect. (We also prepend a check against #level to #add, so you can only set the thread-local level greater than or equal to @level, not less. We’d like to allow setting any thread-local level.)

This patch modifies Logger#add to check #level so that third-party loggers can customize how the current level is determined without needing to reimplement #add or juggle multiple underlying Logger instances.

@ioquatix
Copy link
Member

ioquatix commented Sep 6, 2019

What's the perf impact? I assume it's minimal, but it's the only thing that might block this being merged. Can you show it's minimal?

@georgeclaghorn
Copy link
Contributor Author

Yes, it’s minimal:

Warming up --------------------------------------
                ivar    18.201k i/100ms
              method    18.234k i/100ms
Calculating -------------------------------------
                ivar    196.802k (± 4.3%) i/s -    982.854k in   5.004753s
              method    197.455k (± 2.5%) i/s -      1.003M in   5.082262s

Comparison:
              method:   197455.1 i/s
                ivar:   196801.8 i/s - same-ish: difference falls within error
Benchmarking script
require 'benchmark/ips'
require 'logger'

class Logger
  def add_using_method(severity, message = nil, progname = nil)
    severity ||= UNKNOWN
    if @logdev.nil? or severity < level
      return true
    end
    if progname.nil?
      progname = @progname
    end
    if message.nil?
      if block_given?
        message = yield
      else
        message = progname
        progname = @progname
      end
    end
    @logdev.write(
      format_message(format_severity(severity), Time.now, progname, message))
    true
  end
end

logger = Logger.new(File.open("/dev/null", "w"))

Benchmark.ips do |x|
  x.config :time => 5, :warmup => 2

  x.report("ivar")   { logger.add(Logger::DEBUG, "Test") }
  x.report("method") { logger.add_using_method(Logger::DEBUG, "Test") }

  x.compare!
end

@ioquatix ioquatix self-assigned this Sep 6, 2019
@ioquatix ioquatix self-requested a review September 6, 2019 23:00
Copy link
Member

@ioquatix ioquatix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change is minimal, doesn't appear to break backwards compatibility, and performance impact is minimal.

@ioquatix ioquatix requested a review from sonots September 6, 2019 23:00
@ioquatix ioquatix added the enhancement New feature or request label Sep 6, 2019
@ioquatix ioquatix merged commit 7365c99 into ruby:master Sep 10, 2019
@ioquatix
Copy link
Member

I am happy with this.

@georgeclaghorn georgeclaghorn deleted the log-level-overrides branch September 10, 2019 13:36
georgeclaghorn added a commit to rails/rails that referenced this pull request Sep 13, 2019
We prepend a check against the thread-local level to Logger#add, but because it proceeds to check against the thread-global level, only setting a quieter thread-local level works. The quietest of the two wins. Fix by reimplementing #add entirely.

It's unfortunate to have to do this, but I've already patched upstream Logger to prefer the level instance method over the @Level instance variable, so we'll be able to avoid touching #add at all in the future. See ruby/logger#41.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

Successfully merging this pull request may close these issues.

2 participants