summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@chef.io>2018-01-17 10:34:57 +0000
committerThom May <thom@chef.io>2018-01-17 10:34:57 +0000
commit62249f18082129fb956804ecfa2f90529a6adc6d (patch)
tree50a5d844719b75e4ccbb5a7500721212b332cb2c
parent989553b118791268db96f75afba002da05506b88 (diff)
downloadmixlib-log-62249f18082129fb956804ecfa2f90529a6adc6d.tar.gz
Add child loggers
Child loggers mean that we can create new instances of a logger for subsystems or specific classes, but still only have a single set of outputs. Signed-off-by: Thom May <thom@chef.io>
-rw-r--r--lib/mixlib/log.rb15
-rw-r--r--lib/mixlib/log/child.rb63
-rw-r--r--spec/mixlib/log/child_spec.rb60
-rw-r--r--spec/mixlib/log_spec.rb2
4 files changed, 139 insertions, 1 deletions
diff --git a/lib/mixlib/log.rb b/lib/mixlib/log.rb
index 7152a90..c6dc839 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 "mixlib/log/child"
module Mixlib
module Log
@@ -69,6 +70,19 @@ module Mixlib
@configured = true
end
+ def with_child
+ child = Child.new(self)
+ if block_given?
+ yield child
+ else
+ child
+ end
+ end
+
+ def pass(severity, args, progname = nil, &block)
+ add(severity, args, progname, &block)
+ end
+
# Use Mixlib::Log.init when you want to set up the logger manually. Arguments to this method
# get passed directly to Logger.new, so check out the documentation for the standard Logger class
# to understand what to do here.
@@ -82,6 +96,7 @@ module Mixlib
@logger.formatter = Mixlib::Log::Formatter.new() if @logger.respond_to?(:formatter=)
@logger.level = Logger::WARN
@configured = true
+ @parent = nil
@logger
end
diff --git a/lib/mixlib/log/child.rb b/lib/mixlib/log/child.rb
new file mode 100644
index 0000000..2676b69
--- /dev/null
+++ b/lib/mixlib/log/child.rb
@@ -0,0 +1,63 @@
+#
+# Copyright:: Copyright (c) 2018 Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module Mixlib
+ module Log
+ class Child
+ # include Mixlib::Log
+
+ attr_reader :parent
+ def initialize(parent)
+ @parent = parent
+ end
+
+ def level
+ parent.level
+ end
+
+ def pass(severity, args, progname = nil, &block)
+ parent.pass(severity, args, progname, &block)
+ 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
+ # two (or more) loggers at different log levels.
+ [:debug?, :info?, :warn?, :error?, :fatal?].each do |method_name|
+ class_eval(<<-METHOD_DEFN, __FILE__, __LINE__)
+ def #{method_name}
+ parent.#{method_name}
+ end
+ METHOD_DEFN
+ end
+
+ # Define the standard logger methods on this class programmatically.
+ # No need to incur method_missing overhead on every log call.
+ [:debug, :info, :warn, :error, :fatal].each do |method_name|
+ class_eval(<<-METHOD_DEFN, __FILE__, __LINE__)
+ def #{method_name}(msg=nil, &block)
+ pass(:#{method_name}, msg, &block)
+ end
+ METHOD_DEFN
+ end
+
+ def add(severity, message = nil, progname = nil, &block)
+ parent.pass(severity, message, progname, &block)
+ end
+
+ end
+ end
+end
diff --git a/spec/mixlib/log/child_spec.rb b/spec/mixlib/log/child_spec.rb
new file mode 100644
index 0000000..daf3734
--- /dev/null
+++ b/spec/mixlib/log/child_spec.rb
@@ -0,0 +1,60 @@
+#
+# Copyright:: Copyright (c) 2018 Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "tempfile"
+require "stringio"
+require "spec_helper"
+
+RSpec.describe Mixlib::Log::Child do
+ before do
+ Logit.reset!
+ Logit.init(io)
+ Logit.level = :warn
+ end
+
+ let(:io) { StringIO.new }
+
+ let(:child) { Logit.with_child }
+
+ it "has a parent" do
+ expect(child.parent).to be(Logit)
+ end
+
+ it "accepts a message" do
+ Logit.with_child { |l| l.add(Logger::WARN, "a message") }
+ expect(io.string).to match(/a message$/)
+ end
+
+ context "sends a message to the parent" do
+ %i{ debug info warn error fatal }.each do |level|
+ it "at #{level}" do
+ expect(Logit).to receive(:pass).with(level, "a #{level} message", nil)
+ child.send(level, "a #{level} message")
+ end
+ end
+ end
+
+ context "can query the parent's level" do
+ %i{ debug info warn error fatal }.each do |level|
+ it "at #{level}" do
+ query = "#{level}?".to_sym
+ Logit.level = level
+ expect(child.send(query)).to be(true)
+ end
+ end
+ end
+end
diff --git a/spec/mixlib/log_spec.rb b/spec/mixlib/log_spec.rb
index 277035d..69eebd5 100644
--- a/spec/mixlib/log_spec.rb
+++ b/spec/mixlib/log_spec.rb
@@ -19,7 +19,7 @@
require "tempfile"
require "stringio"
-require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
+require "spec_helper"
class LoggerLike
attr_accessor :level