mixlib-log 1.7.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile +0 -1
- data/README.md +6 -2
- data/Rakefile +1 -1
- data/lib/mixlib/log.rb +32 -22
- data/lib/mixlib/log/child.rb +60 -0
- data/lib/mixlib/log/formatter.rb +12 -2
- data/lib/mixlib/log/logger.rb +106 -0
- data/lib/mixlib/log/logging.rb +53 -0
- data/lib/mixlib/log/version.rb +1 -1
- data/mixlib-log.gemspec +4 -3
- data/spec/mixlib/log/child_spec.rb +99 -0
- data/spec/mixlib/log/formatter_spec.rb +14 -1
- data/spec/mixlib/log_spec.rb +29 -16
- data/spec/spec_helper.rb +5 -1
- metadata +16 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 032aa8e0efc805397575ca65b6ac96af30afc37e027f21268d4ff3c17ab854d4
|
4
|
+
data.tar.gz: 6b599cf65fa6814a5d600db8530e036197a9960b52afea9f886495095d5573b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8bbbc21e0f7108f3ccc9a93ccd8ddbc43e05244ec982c1cd70c2353992f15926417e17190ee09a1c9e84e178b5f4533a14ce27612797e53509e07b60fdc62b5
|
7
|
+
data.tar.gz: ffe35cc1471bf287c4d616a812c5406caeadc38c98ad071294d077e6b29a11d4a15ed2c00f3de6d2467a9bed2fdc644a35b4d74f3e2bd58dbb5bcf23b1e83123
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -22,7 +22,7 @@ Log.error('baz')
|
|
22
22
|
Log.fatal('wewt')
|
23
23
|
```
|
24
24
|
|
25
|
-
By default, `Mixlib::Logger` logs to STDOUT. To alter this, you should call
|
25
|
+
By default, `Mixlib::Logger` logs to STDOUT. To alter this, you should call `Log.init`, passing any arguments to the standard Ruby Logger. For example:
|
26
26
|
|
27
27
|
```ruby
|
28
28
|
Log.init('/tmp/logfile') # log to /tmp/logfile
|
@@ -31,7 +31,11 @@ Log.init('/tmp/logfile', 7) # log to /tmp/logfile, rotate every day
|
|
31
31
|
|
32
32
|
Enjoy!
|
33
33
|
|
34
|
-
##
|
34
|
+
## Contributing
|
35
|
+
|
36
|
+
For information on contributing to this project see <https://github.com/chef/chef/blob/master/CONTRIBUTING.md>
|
37
|
+
|
38
|
+
## License
|
35
39
|
|
36
40
|
- Copyright:: Copyright (c) 2008-2016 Chef Software, Inc.
|
37
41
|
- License:: Apache License, Version 2.0
|
data/Rakefile
CHANGED
data/lib/mixlib/log.rb
CHANGED
@@ -19,15 +19,15 @@
|
|
19
19
|
require "logger"
|
20
20
|
require "mixlib/log/version"
|
21
21
|
require "mixlib/log/formatter"
|
22
|
+
require "mixlib/log/child"
|
23
|
+
require "mixlib/log/logging"
|
22
24
|
|
23
25
|
module Mixlib
|
24
26
|
module Log
|
25
27
|
|
28
|
+
include Logging
|
26
29
|
@logger, @loggers = nil
|
27
30
|
|
28
|
-
LEVELS = { :debug => Logger::DEBUG, :info => Logger::INFO, :warn => Logger::WARN, :error => Logger::ERROR, :fatal => Logger::FATAL }.freeze
|
29
|
-
LEVEL_NAMES = LEVELS.invert.freeze
|
30
|
-
|
31
31
|
def reset!
|
32
32
|
close!
|
33
33
|
@logger, @loggers = nil, nil
|
@@ -82,6 +82,8 @@ module Mixlib
|
|
82
82
|
@logger.formatter = Mixlib::Log::Formatter.new() if @logger.respond_to?(:formatter=)
|
83
83
|
@logger.level = Logger::WARN
|
84
84
|
@configured = true
|
85
|
+
@parent = nil
|
86
|
+
@metadata = {}
|
85
87
|
@logger
|
86
88
|
end
|
87
89
|
|
@@ -92,6 +94,7 @@ module Mixlib
|
|
92
94
|
|
93
95
|
# Sets the level for the Logger object by symbol. Valid arguments are:
|
94
96
|
#
|
97
|
+
# :trace
|
95
98
|
# :debug
|
96
99
|
# :info
|
97
100
|
# :warn
|
@@ -101,7 +104,7 @@ module Mixlib
|
|
101
104
|
# Throws an ArgumentError if you feed it a bogus log level.
|
102
105
|
def level=(new_level)
|
103
106
|
level_int = LEVEL_NAMES.key?(new_level) ? new_level : LEVELS[new_level]
|
104
|
-
raise ArgumentError, "Log level must be one of :debug, :info, :warn, :error, or :fatal" if level_int.nil?
|
107
|
+
raise ArgumentError, "Log level must be one of :trace, :debug, :info, :warn, :error, or :fatal" if level_int.nil?
|
105
108
|
loggers.each { |l| l.level = level_int }
|
106
109
|
end
|
107
110
|
|
@@ -113,38 +116,45 @@ module Mixlib
|
|
113
116
|
end
|
114
117
|
end
|
115
118
|
|
116
|
-
# Define the standard logger methods on this class programmatically.
|
117
|
-
# No need to incur method_missing overhead on every log call.
|
118
|
-
[:debug, :info, :warn, :error, :fatal].each do |method_name|
|
119
|
-
class_eval(<<-METHOD_DEFN, __FILE__, __LINE__)
|
120
|
-
def #{method_name}(msg=nil, &block)
|
121
|
-
loggers.each {|l| l.#{method_name}(msg, &block) }
|
122
|
-
end
|
123
|
-
METHOD_DEFN
|
124
|
-
end
|
125
|
-
|
126
119
|
# Define the methods to interrogate the logger for the current log level.
|
127
120
|
# Note that we *only* query the default logger (@logger) and not any other
|
128
121
|
# loggers that may have been added, even though it is possible to configure
|
129
122
|
# two (or more) loggers at different log levels.
|
130
|
-
[:debug?, :info?, :warn?, :error?, :fatal?].each do |method_name|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
end
|
135
|
-
METHOD_DEFN
|
123
|
+
[:trace?, :debug?, :info?, :warn?, :error?, :fatal?].each do |method_name|
|
124
|
+
define_method(method_name) do
|
125
|
+
logger.send(method_name)
|
126
|
+
end
|
136
127
|
end
|
137
128
|
|
138
129
|
def <<(msg)
|
139
130
|
loggers.each { |l| l << msg }
|
140
131
|
end
|
141
132
|
|
142
|
-
def add(severity, message = nil, progname = nil, &block)
|
143
|
-
|
133
|
+
def add(severity, message = nil, progname = nil, data: {}, &block)
|
134
|
+
message, progname, data = yield if block_given?
|
135
|
+
data = metadata.merge(data) if metadata.kind_of?(Hash) && data.kind_of?(Hash)
|
136
|
+
loggers.each do |l|
|
137
|
+
# if we don't have any metadata, let's not do the potentially expensive
|
138
|
+
# merging and managing that this call requires
|
139
|
+
if l.respond_to?(:add_data) && !data.nil? && !data.empty?
|
140
|
+
l.add_data(severity, message, progname, data: data)
|
141
|
+
else
|
142
|
+
l.add(severity, message, progname)
|
143
|
+
end
|
144
|
+
end
|
144
145
|
end
|
145
146
|
|
146
147
|
alias :log :add
|
147
148
|
|
149
|
+
def with_child(metadata = {})
|
150
|
+
child = Child.new(self, metadata)
|
151
|
+
if block_given?
|
152
|
+
yield child
|
153
|
+
else
|
154
|
+
child
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
148
158
|
# Passes any other method calls on directly to the underlying Logger object created with init. If
|
149
159
|
# this method gets hit before a call to Mixlib::Logger.init has been made, it will call
|
150
160
|
# Mixlib::Logger.init() with no arguments.
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2018 Chef Software, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require "mixlib/log/logging"
|
18
|
+
|
19
|
+
module Mixlib
|
20
|
+
module Log
|
21
|
+
class Child
|
22
|
+
include Mixlib::Log::Logging
|
23
|
+
|
24
|
+
attr_reader :parent
|
25
|
+
def initialize(parent, metadata = {})
|
26
|
+
@parent = parent
|
27
|
+
@metadata = metadata
|
28
|
+
end
|
29
|
+
|
30
|
+
def level
|
31
|
+
parent.level
|
32
|
+
end
|
33
|
+
|
34
|
+
# Define the methods to interrogate the logger for the current log level.
|
35
|
+
# Note that we *only* query the default logger (@logger) and not any other
|
36
|
+
# loggers that may have been added, even though it is possible to configure
|
37
|
+
# two (or more) loggers at different log levels.
|
38
|
+
[:trace?, :debug?, :info?, :warn?, :error?, :fatal?].each do |method_name|
|
39
|
+
define_method(method_name) do
|
40
|
+
parent.send(method_name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def add(severity, message = nil, progname = nil, data: {}, &block)
|
45
|
+
data = metadata.merge(data) if data.kind_of?(Hash)
|
46
|
+
parent.send(:pass, severity, message, progname, data: data, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def with_child(metadata = {})
|
50
|
+
child = Child.new(self, metadata)
|
51
|
+
if block_given?
|
52
|
+
yield child
|
53
|
+
else
|
54
|
+
child
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/mixlib/log/formatter.rb
CHANGED
@@ -42,15 +42,25 @@ module Mixlib
|
|
42
42
|
# put through "object.inspect"
|
43
43
|
def msg2str(msg)
|
44
44
|
case msg
|
45
|
+
when ::Hash
|
46
|
+
if msg.has_key?(:err)
|
47
|
+
format_exception(msg[:err])
|
48
|
+
else
|
49
|
+
msg[:msg]
|
50
|
+
end
|
45
51
|
when ::String
|
46
52
|
msg
|
47
53
|
when ::Exception
|
48
|
-
|
49
|
-
(msg.backtrace || []).join("\n")
|
54
|
+
format_exception(msg)
|
50
55
|
else
|
51
56
|
msg.inspect
|
52
57
|
end
|
53
58
|
end
|
59
|
+
|
60
|
+
def format_exception(msg)
|
61
|
+
"#{msg.message} (#{msg.class})\n" <<
|
62
|
+
(msg.backtrace || []).join("\n")
|
63
|
+
end
|
54
64
|
end
|
55
65
|
end
|
56
66
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require "logger"
|
2
|
+
require "mixlib/log/logging"
|
3
|
+
|
4
|
+
# A subclass of Ruby's stdlib Logger with all the mutex and logrotation stuff
|
5
|
+
# ripped out, and metadata added in.
|
6
|
+
module Mixlib
|
7
|
+
module Log
|
8
|
+
class Logger < ::Logger
|
9
|
+
|
10
|
+
include Logging
|
11
|
+
#
|
12
|
+
# === Synopsis
|
13
|
+
#
|
14
|
+
# Logger.new(name, shift_age = 7, shift_size = 1048576)
|
15
|
+
# Logger.new(name, shift_age = 'weekly')
|
16
|
+
#
|
17
|
+
# === Args
|
18
|
+
#
|
19
|
+
# +logdev+::
|
20
|
+
# The log device. This is a filename (String) or IO object (typically
|
21
|
+
# +STDOUT+, +STDERR+, or an open file).
|
22
|
+
# +shift_age+::
|
23
|
+
# Number of old log files to keep, *or* frequency of rotation (+daily+,
|
24
|
+
# +weekly+ or +monthly+).
|
25
|
+
# +shift_size+::
|
26
|
+
# Maximum logfile size (only applies when +shift_age+ is a number).
|
27
|
+
#
|
28
|
+
# === Description
|
29
|
+
#
|
30
|
+
# Create an instance.
|
31
|
+
#
|
32
|
+
def initialize(logdev)
|
33
|
+
@progname = nil
|
34
|
+
@level = DEBUG
|
35
|
+
@default_formatter = Formatter.new
|
36
|
+
@formatter = nil
|
37
|
+
@logdev = nil
|
38
|
+
if logdev
|
39
|
+
@logdev = LocklessLogDevice.new(logdev)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_data(severity, message, progname, data: {})
|
44
|
+
return true if @logdev.nil? || severity < @level
|
45
|
+
data ||= {}
|
46
|
+
if message.kind_of?(::Exception)
|
47
|
+
data[:err] = message
|
48
|
+
else
|
49
|
+
data[:msg] = message
|
50
|
+
end
|
51
|
+
@logdev.write(
|
52
|
+
format_message(format_severity(severity), Time.now, progname, data))
|
53
|
+
true
|
54
|
+
end
|
55
|
+
alias_method :add, :add_data
|
56
|
+
|
57
|
+
class LocklessLogDevice < LogDevice
|
58
|
+
|
59
|
+
def initialize(log = nil)
|
60
|
+
@dev = @filename = @shift_age = @shift_size = nil
|
61
|
+
if log.respond_to?(:write) && log.respond_to?(:close)
|
62
|
+
@dev = log
|
63
|
+
else
|
64
|
+
@dev = open_logfile(log)
|
65
|
+
@filename = log
|
66
|
+
end
|
67
|
+
@dev.sync = true
|
68
|
+
end
|
69
|
+
|
70
|
+
def write(message)
|
71
|
+
@dev.write(message)
|
72
|
+
rescue Exception => ignored
|
73
|
+
warn("log writing failed. #{ignored}")
|
74
|
+
end
|
75
|
+
|
76
|
+
def close
|
77
|
+
@dev.close rescue nil
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def open_logfile(filename)
|
83
|
+
if FileTest.exist?(filename)
|
84
|
+
open(filename, (File::WRONLY | File::APPEND))
|
85
|
+
else
|
86
|
+
create_logfile(filename)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_logfile(filename)
|
91
|
+
logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT))
|
92
|
+
add_log_header(logdev)
|
93
|
+
logdev
|
94
|
+
end
|
95
|
+
|
96
|
+
def add_log_header(file)
|
97
|
+
file.write(
|
98
|
+
"# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2018 Chef Software, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require "logger"
|
18
|
+
|
19
|
+
module Mixlib
|
20
|
+
module Log
|
21
|
+
module Logging
|
22
|
+
include ::Logger::Severity
|
23
|
+
|
24
|
+
TRACE = -1
|
25
|
+
|
26
|
+
SEV_LABEL = %w{TRACE DEBUG INFO WARN ERROR FATAL ANY}.each(&:freeze).freeze
|
27
|
+
|
28
|
+
def to_label(sev)
|
29
|
+
SEV_LABEL[sev + 1] || -"ANY"
|
30
|
+
end
|
31
|
+
|
32
|
+
LEVELS = { :trace => TRACE, :debug => DEBUG, :info => INFO, :warn => WARN, :error => ERROR, :fatal => FATAL }.freeze
|
33
|
+
LEVEL_NAMES = LEVELS.invert.freeze
|
34
|
+
|
35
|
+
attr_accessor :metadata
|
36
|
+
|
37
|
+
def pass(severity, args, progname = nil, data: {}, &block)
|
38
|
+
args, progname, data = yield if block_given?
|
39
|
+
add(severity, args, progname, data: data)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Define the standard logger methods on this class programmatically.
|
43
|
+
# No need to incur method_missing overhead on every log call.
|
44
|
+
[:trace, :debug, :info, :warn, :error, :fatal].each do |method_name|
|
45
|
+
level = LEVELS[method_name]
|
46
|
+
define_method(method_name) do |msg = nil, data: {}, &block|
|
47
|
+
pass(level, msg, data: data, &block)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/mixlib/log/version.rb
CHANGED
data/mixlib-log.gemspec
CHANGED
@@ -13,9 +13,10 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.has_rdoc = true
|
14
14
|
gem.extra_rdoc_files = ["README.md", "LICENSE", "NOTICE"]
|
15
15
|
gem.files = Dir["lib/**/*"] + Dir["spec/**/*"] + ["Gemfile", "Rakefile", ".gemtest", "mixlib-log.gemspec"]
|
16
|
+
gem.required_ruby_version = ">= 2.2"
|
16
17
|
gem.add_development_dependency "rake"
|
17
|
-
gem.add_development_dependency "rspec", "~> 3.
|
18
|
-
gem.add_development_dependency "chefstyle"
|
18
|
+
gem.add_development_dependency "rspec", "~> 3.7"
|
19
|
+
gem.add_development_dependency "chefstyle"
|
19
20
|
gem.add_development_dependency "cucumber"
|
20
|
-
gem.add_development_dependency "github_changelog_generator", "1.11.3"
|
21
|
+
gem.add_development_dependency "github_changelog_generator", ">= 1.11.3"
|
21
22
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2018 Chef Software, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "tempfile"
|
19
|
+
require "stringio"
|
20
|
+
require "spec_helper"
|
21
|
+
|
22
|
+
RSpec.describe Mixlib::Log::Child do
|
23
|
+
before do
|
24
|
+
Logit.reset!
|
25
|
+
Logit.init(io)
|
26
|
+
Logit.level = :warn
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:io) { StringIO.new }
|
30
|
+
|
31
|
+
let(:child) { Logit.with_child }
|
32
|
+
|
33
|
+
it "has a parent" do
|
34
|
+
expect(child.parent).to be(Logit)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "accepts a message" do
|
38
|
+
Logit.with_child { |l| l.add(Logger::WARN, "a message") }
|
39
|
+
expect(io.string).to match(/a message$/)
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with structured data" do
|
43
|
+
it "can be created with metadata" do
|
44
|
+
expect(Logit).to receive(:pass).with(Mixlib::Log::LEVELS[:warn], "a message", nil, data: { child: "true" })
|
45
|
+
Logit.with_child({ child: "true" }) { |l| l.warn("a message") }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "a message can be logged" do
|
49
|
+
expect(Logit).to receive(:pass).with(Mixlib::Log::LEVELS[:warn], "a message", nil, data: { child: "true" })
|
50
|
+
Logit.with_child { |l| l.warn("a message", data: { child: "true" }) }
|
51
|
+
end
|
52
|
+
|
53
|
+
context "merges properly" do
|
54
|
+
it "in the simple case" do
|
55
|
+
expect(Logit).to receive(:pass).with(Mixlib::Log::LEVELS[:warn], "a message", nil, data: { child: "true", meta: "data" })
|
56
|
+
Logit.with_child(meta: "data") { |l| l.warn("a message", data: { child: "true" }) }
|
57
|
+
end
|
58
|
+
|
59
|
+
it "when overwriting" do
|
60
|
+
expect(Logit).to receive(:pass).with(Mixlib::Log::LEVELS[:warn], "a message", nil, data: { child: "true", meta: "overwritten" })
|
61
|
+
Logit.with_child(meta: "data") { |l| l.warn("a message", data: { child: "true", meta: "overwritten" }) }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when receiving a message from a child" do
|
66
|
+
it "passes data on" do
|
67
|
+
expect(Logit).to receive(:pass).with(Mixlib::Log::LEVELS[:warn], "a message", nil, data: { child: "true", parent: "first" })
|
68
|
+
child.metadata = { parent: "first" }
|
69
|
+
child.with_child { |l| l.warn("a message", data: { child: "true" }) }
|
70
|
+
end
|
71
|
+
|
72
|
+
it "merges its own data" do
|
73
|
+
expect(Logit).to receive(:pass).with(Mixlib::Log::LEVELS[:warn], "a message", nil, data: { child: "true", parent: "second" })
|
74
|
+
child.metadata = { parent: "first" }
|
75
|
+
child.with_child { |l| l.warn("a message", data: { child: "true", parent: "second" }) }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "sends a message to the parent" do
|
81
|
+
%i{ debug info warn error fatal }.each do |level|
|
82
|
+
it "at #{level}" do
|
83
|
+
expect(Logit).to receive(:pass).with(Mixlib::Log::LEVELS[level], "a #{level} message", nil, data: {})
|
84
|
+
Logit.level = level
|
85
|
+
child.send(level, "a #{level} message")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "can query the parent's level" do
|
91
|
+
%i{ debug info warn error fatal }.each do |level|
|
92
|
+
it "at #{level}" do
|
93
|
+
query = "#{level}?".to_sym
|
94
|
+
Logit.level = level
|
95
|
+
expect(child.send(query)).to be(true)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -19,7 +19,7 @@
|
|
19
19
|
require "time"
|
20
20
|
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
21
21
|
|
22
|
-
describe Mixlib::Log::Formatter do
|
22
|
+
RSpec.describe Mixlib::Log::Formatter do
|
23
23
|
before(:each) do
|
24
24
|
@formatter = Mixlib::Log::Formatter.new
|
25
25
|
end
|
@@ -48,4 +48,17 @@ describe Mixlib::Log::Formatter do
|
|
48
48
|
expect(@formatter.call("monkey", Time.new, "test", "mos def")).to eq("monkey: mos def\n")
|
49
49
|
end
|
50
50
|
|
51
|
+
context "with structured data" do
|
52
|
+
let(:data) { {} }
|
53
|
+
|
54
|
+
it "should format a message" do
|
55
|
+
data[:msg] = "nuthin new"
|
56
|
+
expect(@formatter.msg2str(data)).to eq("nuthin new")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should format an exception" do
|
60
|
+
data[:err] = IOError.new("legendary roots crew")
|
61
|
+
expect(@formatter.msg2str(data)).to eq("legendary roots crew (IOError)\n")
|
62
|
+
end
|
63
|
+
end
|
51
64
|
end
|
data/spec/mixlib/log_spec.rb
CHANGED
@@ -19,16 +19,26 @@
|
|
19
19
|
|
20
20
|
require "tempfile"
|
21
21
|
require "stringio"
|
22
|
-
require
|
22
|
+
require "spec_helper"
|
23
23
|
|
24
24
|
class LoggerLike
|
25
25
|
attr_accessor :level
|
26
|
-
attr_reader :messages
|
26
|
+
attr_reader :messages, :data
|
27
27
|
def initialize
|
28
28
|
@messages = ""
|
29
|
+
@data = []
|
29
30
|
end
|
30
31
|
|
31
|
-
|
32
|
+
def add_data(severity, message = nil, progname = nil, data: {})
|
33
|
+
@messages << message
|
34
|
+
@data << data
|
35
|
+
end
|
36
|
+
|
37
|
+
def add(severity, message = nil, progname = nil, data: {})
|
38
|
+
@messages << message
|
39
|
+
end
|
40
|
+
|
41
|
+
[:trace, :debug, :info, :warn, :error, :fatal].each do |method_name|
|
32
42
|
class_eval(<<-E)
|
33
43
|
def #{method_name}(message)
|
34
44
|
@messages << message
|
@@ -37,7 +47,7 @@ class LoggerLike
|
|
37
47
|
end
|
38
48
|
end
|
39
49
|
|
40
|
-
describe Mixlib::Log do
|
50
|
+
RSpec.describe Mixlib::Log do
|
41
51
|
|
42
52
|
# Since we are testing class behaviour for an instance variable
|
43
53
|
# that gets set once, we need to reset it prior to each example [cb]
|
@@ -64,6 +74,7 @@ describe Mixlib::Log do
|
|
64
74
|
it "uses the logger provided when initialized with a logger like object" do
|
65
75
|
logger = LoggerLike.new
|
66
76
|
Logit.init(logger)
|
77
|
+
Logit.level = :debug
|
67
78
|
Logit.debug "qux"
|
68
79
|
expect(logger.messages).to match(/qux/)
|
69
80
|
end
|
@@ -84,13 +95,14 @@ describe Mixlib::Log do
|
|
84
95
|
expect(Logit.configured?).to be true
|
85
96
|
end
|
86
97
|
|
87
|
-
it "should set the log level using the binding form, with :debug, :info, :warn, :error, or :fatal" do
|
98
|
+
it "should set the log level using the binding form, with :trace, :debug, :info, :warn, :error, or :fatal" do
|
88
99
|
levels = {
|
89
|
-
:
|
90
|
-
:
|
91
|
-
:
|
92
|
-
:
|
93
|
-
:
|
100
|
+
:trace => Mixlib::Log::TRACE,
|
101
|
+
:debug => Mixlib::Log::DEBUG,
|
102
|
+
:info => Mixlib::Log::INFO,
|
103
|
+
:warn => Mixlib::Log::WARN,
|
104
|
+
:error => Mixlib::Log::ERROR,
|
105
|
+
:fatal => Mixlib::Log::FATAL,
|
94
106
|
}
|
95
107
|
levels.each do |symbol, constant|
|
96
108
|
Logit.level = symbol
|
@@ -106,13 +118,14 @@ describe Mixlib::Log do
|
|
106
118
|
expect(logdev.string).to match(/the_message/)
|
107
119
|
end
|
108
120
|
|
109
|
-
it "should set the log level using the method form, with :debug, :info, :warn, :error, or :fatal" do
|
121
|
+
it "should set the log level using the method form, with :trace, :debug, :info, :warn, :error, or :fatal" do
|
110
122
|
levels = {
|
111
|
-
:
|
112
|
-
:
|
113
|
-
:
|
114
|
-
:
|
115
|
-
:
|
123
|
+
:trace => Mixlib::Log::TRACE,
|
124
|
+
:debug => Mixlib::Log::DEBUG,
|
125
|
+
:info => Mixlib::Log::INFO,
|
126
|
+
:warn => Mixlib::Log::WARN,
|
127
|
+
:error => Mixlib::Log::ERROR,
|
128
|
+
:fatal => Mixlib::Log::FATAL,
|
116
129
|
}
|
117
130
|
levels.each do |symbol, constant|
|
118
131
|
Logit.level(symbol)
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Adam Jacob (<adam@chef.io>)
|
3
3
|
# Author:: Christopher Brown (<cb@chef.io>)
|
4
|
-
# Copyright:: Copyright (c) 2008-2016 Chef Software, Inc
|
4
|
+
# Copyright:: Copyright (c) 2008-2016 Chef Software, Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -24,6 +24,10 @@ require "rspec"
|
|
24
24
|
require "mixlib/log"
|
25
25
|
require "mixlib/log/formatter"
|
26
26
|
|
27
|
+
RSpec.configure do |config|
|
28
|
+
config.disable_monkey_patching!
|
29
|
+
end
|
30
|
+
|
27
31
|
class Logit
|
28
32
|
extend Mixlib::Log
|
29
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixlib-log
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chef Software, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -30,28 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '3.
|
33
|
+
version: '3.7'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '3.
|
40
|
+
version: '3.7'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: chefstyle
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: cucumber
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,14 +70,14 @@ dependencies:
|
|
70
70
|
name: github_changelog_generator
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: 1.11.3
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 1.11.3
|
83
83
|
description:
|
@@ -96,9 +96,13 @@ files:
|
|
96
96
|
- README.md
|
97
97
|
- Rakefile
|
98
98
|
- lib/mixlib/log.rb
|
99
|
+
- lib/mixlib/log/child.rb
|
99
100
|
- lib/mixlib/log/formatter.rb
|
101
|
+
- lib/mixlib/log/logger.rb
|
102
|
+
- lib/mixlib/log/logging.rb
|
100
103
|
- lib/mixlib/log/version.rb
|
101
104
|
- mixlib-log.gemspec
|
105
|
+
- spec/mixlib/log/child_spec.rb
|
102
106
|
- spec/mixlib/log/formatter_spec.rb
|
103
107
|
- spec/mixlib/log_spec.rb
|
104
108
|
- spec/spec_helper.rb
|
@@ -114,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
118
|
requirements:
|
115
119
|
- - ">="
|
116
120
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
121
|
+
version: '2.2'
|
118
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
123
|
requirements:
|
120
124
|
- - ">="
|
@@ -122,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
126
|
version: '0'
|
123
127
|
requirements: []
|
124
128
|
rubyforge_project:
|
125
|
-
rubygems_version: 2.
|
129
|
+
rubygems_version: 2.7.3
|
126
130
|
signing_key:
|
127
131
|
specification_version: 4
|
128
132
|
summary: A gem that provides a simple mixin for log functionality
|