summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2015-07-31 17:21:53 -0600
committerJohn Keiser <john@johnkeiser.com>2015-07-31 17:21:53 -0600
commit69a2369edf9a3a7171ac7a38cf49e22183251f5e (patch)
tree000e0b16f51c7bf06440bb5ec9ce6c4b9c85f693
parent50ec55964ce19d3a8a14050be9a23c4b8990e2f0 (diff)
downloadmixlib-log-jk/warn_once.tar.gz
Add Log.warn_oncejk/warn_once
-rw-r--r--lib/mixlib/log.rb19
-rw-r--r--spec/mixlib/log_spec.rb30
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