diff options
author | John Keiser <john@johnkeiser.com> | 2015-07-31 17:21:53 -0600 |
---|---|---|
committer | John Keiser <john@johnkeiser.com> | 2015-07-31 17:21:53 -0600 |
commit | 69a2369edf9a3a7171ac7a38cf49e22183251f5e (patch) | |
tree | 000e0b16f51c7bf06440bb5ec9ce6c4b9c85f693 | |
parent | 50ec55964ce19d3a8a14050be9a23c4b8990e2f0 (diff) | |
download | mixlib-log-jk/warn_once.tar.gz |
Add Log.warn_oncejk/warn_once
-rw-r--r-- | lib/mixlib/log.rb | 19 | ||||
-rw-r--r-- | spec/mixlib/log_spec.rb | 30 |
2 files changed, 46 insertions, 3 deletions
diff --git a/lib/mixlib/log.rb b/lib/mixlib/log.rb index 5ff243d..118c58e 100644 --- a/lib/mixlib/log.rb +++ b/lib/mixlib/log.rb @@ -19,6 +19,7 @@ require 'logger' require 'mixlib/log/version' require 'mixlib/log/formatter' +require 'set' module Mixlib module Log @@ -30,7 +31,7 @@ module Mixlib def reset! - @logger, @loggers = nil, nil + @logger, @loggers, @warned_from = nil, nil end # An Array of log devices that will be logged to. Defaults to just the default @@ -116,6 +117,18 @@ module Mixlib METHOD_DEFN end + # + # Warn the user about something, but only once per caller. Subsequent log + # messages are logged at debug level. + # + def warn_once(msg=nil, &block) + if warned_from.add?(caller[0]) + warn(msg, &block) + else + debug("WARN: #{msg}", &block) + end + end + # Define the methods to interrogate the logger for the current log level. # Note that we *only* query the default logger (@logger) and not any other # loggers that may have been added, even though it is possible to configure @@ -147,6 +160,10 @@ module Mixlib private + def warned_from + @warned_from ||= Set.new + end + def logger_for(*opts) if opts.empty? Logger.new(STDOUT) diff --git a/spec/mixlib/log_spec.rb b/spec/mixlib/log_spec.rb index 640ae81..813cc6e 100644 --- a/spec/mixlib/log_spec.rb +++ b/spec/mixlib/log_spec.rb @@ -130,6 +130,32 @@ describe Mixlib::Log do lambda { Logit.debug("Gimme some sugar!") }.should_not raise_error end + context "#warn_once" do + it "should warn the first time a given caller logs, but not subsequent times" do + expect(Logit).to receive(:warn).with("hi").exactly(1).times + expect(Logit).to receive(:debug).with("WARN: hi").exactly(2).times + 1.upto(3) do + Logit.warn_once("hi") + end + end + + it "should warn the first time a given caller logs, but not subsequent times, even if the message is different" do + expect(Logit).to receive(:warn).with("hi 1").exactly(1).times + expect(Logit).to receive(:debug).with("WARN: hi 2").exactly(1).times + expect(Logit).to receive(:debug).with("WARN: hi 3").exactly(1).times + 1.upto(3) do |i| + Logit.warn_once("hi #{i}") + end + end + + it "should warn each time for different callers" do + expect(Logit).to receive(:warn).with("hi").exactly(3).times + Logit.warn_once("hi") + Logit.warn_once("hi") + Logit.warn_once("hi") + end + end + it "should pass add method calls directly to logger" do logdev = StringIO.new Logit.init(logdev) @@ -141,14 +167,14 @@ describe Mixlib::Log do it "should default to STDOUT if init is called with no arguments" do logger_mock = Struct.new(:formatter, :level).new - Logger.stub!(:new).and_return(logger_mock) + Logger.stub(:new).and_return(logger_mock) Logger.should_receive(:new).with(STDOUT).and_return(logger_mock) Logit.init end it "should have by default a base log level of warn" do logger_mock = Struct.new(:formatter, :level).new - Logger.stub!(:new).and_return(logger_mock) + Logger.stub(:new).and_return(logger_mock) Logit.init Logit.level.should eql(:warn) end |