test-kitchen 1.7.0 → 1.7.1.dev
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 +4 -4
- data/.cane +8 -8
- data/.gitattributes +3 -0
- data/.github/ISSUE_TEMPLATE.md +55 -55
- data/.gitignore +28 -28
- data/.kitchen.ci.yml +23 -23
- data/.kitchen.proxy.yml +27 -27
- data/.rubocop.yml +3 -3
- data/.travis.yml +70 -70
- data/.yardopts +3 -3
- data/Berksfile +3 -3
- data/CHANGELOG.md +1090 -1083
- data/CONTRIBUTING.md +14 -14
- data/Gemfile +19 -19
- data/Gemfile.proxy_tests +4 -4
- data/Guardfile +42 -42
- data/LICENSE +15 -15
- data/MAINTAINERS.md +23 -23
- data/README.md +135 -135
- data/Rakefile +61 -61
- data/appveyor.yml +44 -44
- data/features/kitchen_action_commands.feature +164 -164
- data/features/kitchen_command.feature +16 -16
- data/features/kitchen_console_command.feature +34 -34
- data/features/kitchen_defaults.feature +38 -38
- data/features/kitchen_diagnose_command.feature +96 -96
- data/features/kitchen_driver_create_command.feature +64 -64
- data/features/kitchen_driver_discover_command.feature +25 -25
- data/features/kitchen_help_command.feature +16 -16
- data/features/kitchen_init_command.feature +274 -274
- data/features/kitchen_list_command.feature +104 -104
- data/features/kitchen_login_command.feature +62 -62
- data/features/kitchen_sink_command.feature +30 -30
- data/features/kitchen_test_command.feature +88 -88
- data/features/step_definitions/gem_steps.rb +36 -36
- data/features/step_definitions/git_steps.rb +5 -5
- data/features/step_definitions/output_steps.rb +5 -5
- data/features/support/env.rb +75 -75
- data/lib/kitchen.rb +150 -150
- data/lib/kitchen/base64_stream.rb +55 -55
- data/lib/kitchen/cli.rb +419 -419
- data/lib/kitchen/collection.rb +55 -55
- data/lib/kitchen/color.rb +65 -65
- data/lib/kitchen/command.rb +185 -185
- data/lib/kitchen/command/action.rb +45 -45
- data/lib/kitchen/command/console.rb +58 -58
- data/lib/kitchen/command/diagnose.rb +92 -92
- data/lib/kitchen/command/driver_discover.rb +105 -105
- data/lib/kitchen/command/exec.rb +41 -41
- data/lib/kitchen/command/list.rb +119 -119
- data/lib/kitchen/command/login.rb +43 -43
- data/lib/kitchen/command/sink.rb +54 -54
- data/lib/kitchen/command/test.rb +51 -51
- data/lib/kitchen/config.rb +322 -322
- data/lib/kitchen/configurable.rb +529 -529
- data/lib/kitchen/data_munger.rb +959 -959
- data/lib/kitchen/diagnostic.rb +141 -141
- data/lib/kitchen/driver.rb +56 -56
- data/lib/kitchen/driver/base.rb +134 -134
- data/lib/kitchen/driver/dummy.rb +108 -108
- data/lib/kitchen/driver/proxy.rb +72 -72
- data/lib/kitchen/driver/ssh_base.rb +357 -357
- data/lib/kitchen/errors.rb +229 -229
- data/lib/kitchen/generator/driver_create.rb +177 -177
- data/lib/kitchen/generator/init.rb +296 -296
- data/lib/kitchen/instance.rb +662 -662
- data/lib/kitchen/lazy_hash.rb +142 -142
- data/lib/kitchen/loader/yaml.rb +349 -349
- data/lib/kitchen/logger.rb +423 -423
- data/lib/kitchen/logging.rb +56 -56
- data/lib/kitchen/login_command.rb +52 -52
- data/lib/kitchen/metadata_chopper.rb +52 -52
- data/lib/kitchen/platform.rb +67 -67
- data/lib/kitchen/provisioner.rb +54 -54
- data/lib/kitchen/provisioner/base.rb +236 -236
- data/lib/kitchen/provisioner/chef/berkshelf.rb +114 -114
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -322
- data/lib/kitchen/provisioner/chef/librarian.rb +112 -112
- data/lib/kitchen/provisioner/chef_apply.rb +124 -124
- data/lib/kitchen/provisioner/chef_base.rb +341 -341
- data/lib/kitchen/provisioner/chef_solo.rb +88 -88
- data/lib/kitchen/provisioner/chef_zero.rb +245 -245
- data/lib/kitchen/provisioner/dummy.rb +79 -79
- data/lib/kitchen/provisioner/shell.rb +138 -138
- data/lib/kitchen/rake_tasks.rb +63 -63
- data/lib/kitchen/shell_out.rb +93 -93
- data/lib/kitchen/ssh.rb +276 -276
- data/lib/kitchen/state_file.rb +120 -120
- data/lib/kitchen/suite.rb +51 -51
- data/lib/kitchen/thor_tasks.rb +66 -66
- data/lib/kitchen/transport.rb +54 -54
- data/lib/kitchen/transport/base.rb +176 -176
- data/lib/kitchen/transport/dummy.rb +79 -79
- data/lib/kitchen/transport/ssh.rb +364 -364
- data/lib/kitchen/transport/winrm.rb +486 -486
- data/lib/kitchen/util.rb +147 -147
- data/lib/kitchen/verifier.rb +55 -55
- data/lib/kitchen/verifier/base.rb +235 -235
- data/lib/kitchen/verifier/busser.rb +277 -277
- data/lib/kitchen/verifier/dummy.rb +79 -79
- data/lib/kitchen/verifier/shell.rb +101 -101
- data/lib/kitchen/version.rb +21 -21
- data/lib/vendor/hash_recursive_merge.rb +82 -82
- data/spec/kitchen/base64_stream_spec.rb +77 -77
- data/spec/kitchen/cli_spec.rb +56 -56
- data/spec/kitchen/collection_spec.rb +80 -80
- data/spec/kitchen/color_spec.rb +54 -54
- data/spec/kitchen/config_spec.rb +408 -408
- data/spec/kitchen/configurable_spec.rb +1095 -1095
- data/spec/kitchen/data_munger_spec.rb +2694 -2694
- data/spec/kitchen/diagnostic_spec.rb +129 -129
- data/spec/kitchen/driver/base_spec.rb +121 -121
- data/spec/kitchen/driver/dummy_spec.rb +199 -199
- data/spec/kitchen/driver/proxy_spec.rb +138 -138
- data/spec/kitchen/driver/ssh_base_spec.rb +1115 -1115
- data/spec/kitchen/driver_spec.rb +112 -112
- data/spec/kitchen/errors_spec.rb +309 -309
- data/spec/kitchen/instance_spec.rb +1419 -1419
- data/spec/kitchen/lazy_hash_spec.rb +117 -117
- data/spec/kitchen/loader/yaml_spec.rb +774 -774
- data/spec/kitchen/logger_spec.rb +429 -429
- data/spec/kitchen/logging_spec.rb +59 -59
- data/spec/kitchen/login_command_spec.rb +68 -68
- data/spec/kitchen/metadata_chopper_spec.rb +82 -82
- data/spec/kitchen/platform_spec.rb +89 -89
- data/spec/kitchen/provisioner/base_spec.rb +386 -386
- data/spec/kitchen/provisioner/chef_apply_spec.rb +136 -136
- data/spec/kitchen/provisioner/chef_base_spec.rb +1161 -1161
- data/spec/kitchen/provisioner/chef_solo_spec.rb +557 -557
- data/spec/kitchen/provisioner/chef_zero_spec.rb +1001 -1001
- data/spec/kitchen/provisioner/dummy_spec.rb +99 -99
- data/spec/kitchen/provisioner/shell_spec.rb +566 -566
- data/spec/kitchen/provisioner_spec.rb +107 -107
- data/spec/kitchen/shell_out_spec.rb +150 -150
- data/spec/kitchen/ssh_spec.rb +693 -693
- data/spec/kitchen/state_file_spec.rb +129 -129
- data/spec/kitchen/suite_spec.rb +62 -62
- data/spec/kitchen/transport/base_spec.rb +89 -89
- data/spec/kitchen/transport/ssh_spec.rb +1255 -1255
- data/spec/kitchen/transport/winrm_spec.rb +1143 -1143
- data/spec/kitchen/transport_spec.rb +112 -112
- data/spec/kitchen/util_spec.rb +165 -165
- data/spec/kitchen/verifier/base_spec.rb +362 -362
- data/spec/kitchen/verifier/busser_spec.rb +610 -610
- data/spec/kitchen/verifier/dummy_spec.rb +99 -99
- data/spec/kitchen/verifier/shell_spec.rb +160 -160
- data/spec/kitchen/verifier_spec.rb +120 -120
- data/spec/kitchen_spec.rb +114 -114
- data/spec/spec_helper.rb +85 -85
- data/spec/support/powershell_max_size_spec.rb +40 -40
- data/support/busser_install_command.ps1 +14 -14
- data/support/busser_install_command.sh +14 -14
- data/support/chef-client-zero.rb +77 -77
- data/support/chef_base_init_command.ps1 +18 -18
- data/support/chef_base_init_command.sh +2 -2
- data/support/chef_base_install_command.ps1 +85 -85
- data/support/chef_base_install_command.sh +229 -229
- data/support/chef_zero_prepare_command_legacy.ps1 +9 -9
- data/support/chef_zero_prepare_command_legacy.sh +10 -10
- data/support/download_helpers.sh +109 -109
- data/support/dummy-validation.pem +27 -27
- data/templates/driver/CHANGELOG.md.erb +3 -3
- data/templates/driver/Gemfile.erb +3 -3
- data/templates/driver/README.md.erb +64 -64
- data/templates/driver/Rakefile.erb +21 -21
- data/templates/driver/driver.rb.erb +23 -23
- data/templates/driver/gemspec.erb +29 -29
- data/templates/driver/gitignore.erb +17 -17
- data/templates/driver/license_apachev2.erb +15 -15
- data/templates/driver/license_lgplv3.erb +16 -16
- data/templates/driver/license_mit.erb +22 -22
- data/templates/driver/license_reserved.erb +5 -5
- data/templates/driver/tailor.erb +4 -4
- data/templates/driver/travis.yml.erb +11 -11
- data/templates/driver/version.rb.erb +12 -12
- data/templates/init/chefignore.erb +1 -1
- data/templates/init/kitchen.yml.erb +18 -18
- data/test-kitchen.gemspec +62 -62
- data/test/integration/default/default_spec.rb +3 -3
- data/testing_windows.md +37 -37
- metadata +5 -4
data/lib/kitchen/logger.rb
CHANGED
|
@@ -1,423 +1,423 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (C) 2013, Fletcher Nichol
|
|
6
|
-
#
|
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
# you may not use this file except in compliance with the License.
|
|
9
|
-
# You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
# See the License for the specific language governing permissions and
|
|
17
|
-
# limitations under the License.
|
|
18
|
-
|
|
19
|
-
require "fileutils"
|
|
20
|
-
require "logger"
|
|
21
|
-
|
|
22
|
-
module Kitchen
|
|
23
|
-
|
|
24
|
-
# Logging implementation for Kitchen. By default the console/stdout output
|
|
25
|
-
# will be displayed differently than the file log output. Therefor, this
|
|
26
|
-
# class wraps multiple loggers that conform to the stdlib `Logger` class
|
|
27
|
-
# behavior.
|
|
28
|
-
#
|
|
29
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
30
|
-
class Logger
|
|
31
|
-
|
|
32
|
-
include ::Logger::Severity
|
|
33
|
-
|
|
34
|
-
# @return [IO] the log device
|
|
35
|
-
attr_reader :logdev
|
|
36
|
-
|
|
37
|
-
# @return [Boolean] whether logger is configured for
|
|
38
|
-
# overwriting
|
|
39
|
-
attr_reader :log_overwrite
|
|
40
|
-
|
|
41
|
-
# Constructs a new logger.
|
|
42
|
-
#
|
|
43
|
-
# @param options [Hash] configuration for a new logger
|
|
44
|
-
# @option options [Symbol] :color color to use when when outputting
|
|
45
|
-
# messages
|
|
46
|
-
# @option options [Integer] :level the logging severity threshold
|
|
47
|
-
# (default: `Kitchen::DEFAULT_LOG_LEVEL`)
|
|
48
|
-
# @option options [Boolean] whether to overwrite the log
|
|
49
|
-
# when Test Kitchen runs. Only applies if the :logdev is a String.
|
|
50
|
-
# (default: `Kitchen::DEFAULT_LOG_OVERWRITE`)
|
|
51
|
-
# @option options [String,IO] :logdev filepath String or IO object to be
|
|
52
|
-
# used for logging (default: `nil`)
|
|
53
|
-
# @option options [String] :progname program name to include in log
|
|
54
|
-
# messages (default: `"Kitchen"`)
|
|
55
|
-
# @option options [IO] :stdout a standard out IO object to use
|
|
56
|
-
# (default: `$stdout`)
|
|
57
|
-
def initialize(options = {})
|
|
58
|
-
color = options[:color]
|
|
59
|
-
@log_overwrite = if options[:log_overwrite].nil?
|
|
60
|
-
default_log_overwrite
|
|
61
|
-
else
|
|
62
|
-
options[:log_overwrite]
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
@logdev = logdev_logger(options[:logdev], log_overwrite) if options[:logdev]
|
|
66
|
-
|
|
67
|
-
populate_loggers(color, options)
|
|
68
|
-
|
|
69
|
-
# These setters cannot be called until @loggers are populated because
|
|
70
|
-
# they are delegated
|
|
71
|
-
self.progname = options[:progname] || "Kitchen"
|
|
72
|
-
self.level = options[:level] || default_log_level
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Pulled out for Rubocop complexity issues
|
|
76
|
-
#
|
|
77
|
-
# @api private
|
|
78
|
-
def populate_loggers(color, options)
|
|
79
|
-
@loggers = []
|
|
80
|
-
@loggers << logdev unless logdev.nil?
|
|
81
|
-
@loggers << stdout_logger(options[:stdout], color) if options[:stdout]
|
|
82
|
-
@loggers << stdout_logger($stdout, color) if @loggers.empty?
|
|
83
|
-
end
|
|
84
|
-
private :populate_loggers
|
|
85
|
-
|
|
86
|
-
class << self
|
|
87
|
-
|
|
88
|
-
private
|
|
89
|
-
|
|
90
|
-
# @api private
|
|
91
|
-
# @!macro delegate_to_first_logger
|
|
92
|
-
# @method $1()
|
|
93
|
-
def delegate_to_first_logger(meth)
|
|
94
|
-
define_method(meth) { |*args| @loggers.first.public_send(meth, *args) }
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# @api private
|
|
98
|
-
# @!macro delegate_to_all_loggers
|
|
99
|
-
# @method $1()
|
|
100
|
-
def delegate_to_all_loggers(meth)
|
|
101
|
-
define_method(meth) do |*args|
|
|
102
|
-
result = nil
|
|
103
|
-
@loggers.each { |l| result = l.public_send(meth, *args) }
|
|
104
|
-
result
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# @return [Integer] the logging severity threshold
|
|
110
|
-
# @see http://is.gd/Okuy5p
|
|
111
|
-
delegate_to_first_logger :level
|
|
112
|
-
|
|
113
|
-
# Sets the logging severity threshold.
|
|
114
|
-
#
|
|
115
|
-
# @param level [Integer] the logging severity threshold
|
|
116
|
-
# @see http://is.gd/H1VBFH
|
|
117
|
-
delegate_to_all_loggers :level=
|
|
118
|
-
|
|
119
|
-
# @return [String] program name to include in log messages
|
|
120
|
-
# @see http://is.gd/5uHGK0
|
|
121
|
-
delegate_to_first_logger :progname
|
|
122
|
-
|
|
123
|
-
# Sets the program name to include in log messages.
|
|
124
|
-
#
|
|
125
|
-
# @param progname [String] the program name to include in log messages
|
|
126
|
-
# @see http://is.gd/f2U5Xj
|
|
127
|
-
delegate_to_all_loggers :progname=
|
|
128
|
-
|
|
129
|
-
# @return [String] the date format being used
|
|
130
|
-
# @see http://is.gd/btmFWJ
|
|
131
|
-
delegate_to_first_logger :datetime_format
|
|
132
|
-
|
|
133
|
-
# Sets the date format being used.
|
|
134
|
-
#
|
|
135
|
-
# @param format [String] the date format
|
|
136
|
-
# @see http://is.gd/M36ml8
|
|
137
|
-
delegate_to_all_loggers :datetime_format=
|
|
138
|
-
|
|
139
|
-
# Log a message if the given severity is high enough.
|
|
140
|
-
#
|
|
141
|
-
# @see http://is.gd/5opBW0
|
|
142
|
-
delegate_to_all_loggers :add
|
|
143
|
-
|
|
144
|
-
# Dump one or more messages to info.
|
|
145
|
-
#
|
|
146
|
-
# @param message [#to_s] the message to log
|
|
147
|
-
# @see http://is.gd/BCp5KV
|
|
148
|
-
delegate_to_all_loggers :<<
|
|
149
|
-
|
|
150
|
-
# Log a message with severity of banner (high level).
|
|
151
|
-
#
|
|
152
|
-
# @param message_or_progname [#to_s] the message to log. In the block
|
|
153
|
-
# form, this is the progname to use in the log message.
|
|
154
|
-
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
155
|
-
# logger's level is sufficient to log the message. This allows you to
|
|
156
|
-
# create potentially expensive logging messages that are only called when
|
|
157
|
-
# the logger is configured to show them.
|
|
158
|
-
# @return [nil,true] when the given severity is not high enough (for this
|
|
159
|
-
# particular logger), log no message, and return true
|
|
160
|
-
# @see http://is.gd/pYUCYU
|
|
161
|
-
delegate_to_all_loggers :banner
|
|
162
|
-
|
|
163
|
-
# Log a message with severity of debug.
|
|
164
|
-
#
|
|
165
|
-
# @param message_or_progname [#to_s] the message to log. In the block
|
|
166
|
-
# form, this is the progname to use in the log message.
|
|
167
|
-
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
168
|
-
# logger's level is sufficient to log the message. This allows you to
|
|
169
|
-
# create potentially expensive logging messages that are only called when
|
|
170
|
-
# the logger is configured to show them.
|
|
171
|
-
# @return [nil,true] when the given severity is not high enough (for this
|
|
172
|
-
# particular logger), log no message, and return true
|
|
173
|
-
# @see http://is.gd/Re97Zp
|
|
174
|
-
delegate_to_all_loggers :debug
|
|
175
|
-
|
|
176
|
-
# @return [true,false] whether or not the current severity level
|
|
177
|
-
# allows for the printing of debug messages
|
|
178
|
-
# @see http://is.gd/Iq08xB
|
|
179
|
-
delegate_to_first_logger :debug?
|
|
180
|
-
|
|
181
|
-
# Log a message with severity of info.
|
|
182
|
-
#
|
|
183
|
-
# @param message_or_progname [#to_s] the message to log. In the block
|
|
184
|
-
# form, this is the progname to use in the log message.
|
|
185
|
-
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
186
|
-
# logger's level is sufficient to log the message. This allows you to
|
|
187
|
-
# create potentially expensive logging messages that are only called when
|
|
188
|
-
# the logger is configured to show them.
|
|
189
|
-
# @return [nil,true] when the given severity is not high enough (for this
|
|
190
|
-
# particular logger), log no message, and return true
|
|
191
|
-
# @see http://is.gd/pYUCYU
|
|
192
|
-
delegate_to_all_loggers :info
|
|
193
|
-
|
|
194
|
-
# @return [true,false] whether or not the current severity level
|
|
195
|
-
# allows for the printing of info messages
|
|
196
|
-
# @see http://is.gd/lBtJkT
|
|
197
|
-
delegate_to_first_logger :info?
|
|
198
|
-
|
|
199
|
-
# Log a message with severity of error.
|
|
200
|
-
#
|
|
201
|
-
# @param message_or_progname [#to_s] the message to log. In the block
|
|
202
|
-
# form, this is the progname to use in the log message.
|
|
203
|
-
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
204
|
-
# logger's level is sufficient to log the message. This allows you to
|
|
205
|
-
# create potentially expensive logging messages that are only called when
|
|
206
|
-
# the logger is configured to show them.
|
|
207
|
-
# @return [nil,true] when the given severity is not high enough (for this
|
|
208
|
-
# particular logger), log no message, and return true
|
|
209
|
-
# @see http://is.gd/mLwYMl
|
|
210
|
-
delegate_to_all_loggers :error
|
|
211
|
-
|
|
212
|
-
# @return [true,false] whether or not the current severity level
|
|
213
|
-
# allows for the printing of error messages
|
|
214
|
-
# @see http://is.gd/QY19JL
|
|
215
|
-
delegate_to_first_logger :error?
|
|
216
|
-
|
|
217
|
-
# Log a message with severity of warn.
|
|
218
|
-
#
|
|
219
|
-
# @param message_or_progname [#to_s] the message to log. In the block
|
|
220
|
-
# form, this is the progname to use in the log message.
|
|
221
|
-
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
222
|
-
# logger's level is sufficient to log the message. This allows you to
|
|
223
|
-
# create potentially expensive logging messages that are only called when
|
|
224
|
-
# the logger is configured to show them.
|
|
225
|
-
# @return [nil,true] when the given severity is not high enough (for this
|
|
226
|
-
# particular logger), log no message, and return true
|
|
227
|
-
# @see http://is.gd/PX9AIS
|
|
228
|
-
delegate_to_all_loggers :warn
|
|
229
|
-
|
|
230
|
-
# @return [true,false] whether or not the current severity level
|
|
231
|
-
# allows for the printing of warn messages
|
|
232
|
-
# @see http://is.gd/Gdr4lD
|
|
233
|
-
delegate_to_first_logger :warn?
|
|
234
|
-
|
|
235
|
-
# Log a message with severity of fatal.
|
|
236
|
-
#
|
|
237
|
-
# @param message_or_progname [#to_s] the message to log. In the block
|
|
238
|
-
# form, this is the progname to use in the log message.
|
|
239
|
-
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
240
|
-
# logger's level is sufficient to log the message. This allows you to
|
|
241
|
-
# create potentially expensive logging messages that are only called when
|
|
242
|
-
# the logger is configured to show them.
|
|
243
|
-
# @return [nil,true] when the given severity is not high enough (for this
|
|
244
|
-
# particular logger), log no message, and return true
|
|
245
|
-
# @see http://is.gd/5ElFPK
|
|
246
|
-
delegate_to_all_loggers :fatal
|
|
247
|
-
|
|
248
|
-
# @return [true,false] whether or not the current severity level
|
|
249
|
-
# allows for the printing of fatal messages
|
|
250
|
-
# @see http://is.gd/7PgwRl
|
|
251
|
-
delegate_to_first_logger :fatal?
|
|
252
|
-
|
|
253
|
-
# Log a message with severity of unknown.
|
|
254
|
-
#
|
|
255
|
-
# @param message_or_progname [#to_s] the message to log. In the block
|
|
256
|
-
# form, this is the progname to use in the log message.
|
|
257
|
-
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
258
|
-
# logger's level is sufficient to log the message. This allows you to
|
|
259
|
-
# create potentially expensive logging messages that are only called when
|
|
260
|
-
# the logger is configured to show them.
|
|
261
|
-
# @return [nil,true] when the given severity is not high enough (for this
|
|
262
|
-
# particular logger), log no message, and return true
|
|
263
|
-
# @see http://is.gd/Y4hqpf
|
|
264
|
-
delegate_to_all_loggers :unknown
|
|
265
|
-
|
|
266
|
-
# Close the logging devices.
|
|
267
|
-
#
|
|
268
|
-
# @see http://is.gd/b13cVn
|
|
269
|
-
delegate_to_all_loggers :close
|
|
270
|
-
|
|
271
|
-
private
|
|
272
|
-
|
|
273
|
-
# @return [Integer] the default logger level
|
|
274
|
-
# @api private
|
|
275
|
-
def default_log_level
|
|
276
|
-
Util.to_logger_level(Kitchen::DEFAULT_LOG_LEVEL)
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
# @return [Boolean] whether to overwrite logs by default
|
|
280
|
-
# @api private
|
|
281
|
-
def default_log_overwrite
|
|
282
|
-
Kitchen::DEFAULT_LOG_OVERWRITE
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
# Construct a new standard out logger.
|
|
286
|
-
#
|
|
287
|
-
# @param stdout [IO] the IO object that represents stdout (or similar)
|
|
288
|
-
# @param color [Symbol] color to use when outputing messages
|
|
289
|
-
# @return [StdoutLogger] a new logger
|
|
290
|
-
# @api private
|
|
291
|
-
def stdout_logger(stdout, color)
|
|
292
|
-
logger = StdoutLogger.new(stdout)
|
|
293
|
-
if Kitchen.tty?
|
|
294
|
-
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
295
|
-
Color.colorize("#{msg}", color).concat("\n")
|
|
296
|
-
end
|
|
297
|
-
else
|
|
298
|
-
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
299
|
-
msg.concat("\n")
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
logger
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
# Construct a new logdev logger.
|
|
306
|
-
#
|
|
307
|
-
# @param filepath_or_logdev [String,IO] a filepath String or IO object
|
|
308
|
-
# @param log_overwrite [Boolean] apply log overwriting
|
|
309
|
-
# if filepath_or_logdev is a file path
|
|
310
|
-
# @return [LogdevLogger] a new logger
|
|
311
|
-
# @api private
|
|
312
|
-
def logdev_logger(filepath_or_logdev, log_overwrite)
|
|
313
|
-
LogdevLogger.new(resolve_logdev(filepath_or_logdev, log_overwrite))
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
# Return an IO object from a filepath String or the IO object itself.
|
|
317
|
-
#
|
|
318
|
-
# @param filepath_or_logdev [String,IO] a filepath String or IO object
|
|
319
|
-
# @param log_overwrite [Boolean] apply log overwriting
|
|
320
|
-
# if filepath_or_logdev is a file path
|
|
321
|
-
# @return [IO] an IO object
|
|
322
|
-
# @api private
|
|
323
|
-
def resolve_logdev(filepath_or_logdev, log_overwrite)
|
|
324
|
-
if filepath_or_logdev.is_a? String
|
|
325
|
-
mode = log_overwrite ? "wb" : "ab"
|
|
326
|
-
FileUtils.mkdir_p(File.dirname(filepath_or_logdev))
|
|
327
|
-
file = File.open(File.expand_path(filepath_or_logdev), mode)
|
|
328
|
-
file.sync = true
|
|
329
|
-
file
|
|
330
|
-
else
|
|
331
|
-
filepath_or_logdev
|
|
332
|
-
end
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
# Internal class which adds a #banner method call that displays the
|
|
336
|
-
# message with a callout arrow.
|
|
337
|
-
class LogdevLogger < ::Logger
|
|
338
|
-
|
|
339
|
-
alias_method :super_info, :info
|
|
340
|
-
|
|
341
|
-
# Dump one or more messages to info.
|
|
342
|
-
#
|
|
343
|
-
# @param msg [String] a message
|
|
344
|
-
def <<(msg)
|
|
345
|
-
@buffer ||= ""
|
|
346
|
-
@buffer += msg
|
|
347
|
-
while i = @buffer.index("\n")
|
|
348
|
-
format_line(@buffer[0, i].chomp)
|
|
349
|
-
@buffer[0, i + 1] = ""
|
|
350
|
-
end
|
|
351
|
-
end
|
|
352
|
-
|
|
353
|
-
# Log a banner message.
|
|
354
|
-
#
|
|
355
|
-
# @param msg [String] a message
|
|
356
|
-
def banner(msg = nil, &block)
|
|
357
|
-
super_info("-----> #{msg}", &block)
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
private
|
|
361
|
-
|
|
362
|
-
# Reformat a line if it already contains log formatting.
|
|
363
|
-
#
|
|
364
|
-
# @param line [String] a message line
|
|
365
|
-
# @api private
|
|
366
|
-
def format_line(line)
|
|
367
|
-
case line
|
|
368
|
-
when %r{^-----> } then banner(line.gsub(%r{^[ >-]{6} }, ""))
|
|
369
|
-
when %r{^>>>>>> } then error(line.gsub(%r{^[ >-]{6} }, ""))
|
|
370
|
-
when %r{^ } then info(line.gsub(%r{^[ >-]{6} }, ""))
|
|
371
|
-
else info(line)
|
|
372
|
-
end
|
|
373
|
-
end
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
# Internal class which reformats logging methods for display as console
|
|
377
|
-
# output.
|
|
378
|
-
class StdoutLogger < LogdevLogger
|
|
379
|
-
|
|
380
|
-
# Log a debug message
|
|
381
|
-
#
|
|
382
|
-
# @param msg [String] a message
|
|
383
|
-
def debug(msg = nil, &block)
|
|
384
|
-
super("D #{msg}", &block)
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
# Log an info message
|
|
388
|
-
#
|
|
389
|
-
# @param msg [String] a message
|
|
390
|
-
def info(msg = nil, &block)
|
|
391
|
-
super(" #{msg}", &block)
|
|
392
|
-
end
|
|
393
|
-
|
|
394
|
-
# Log a warn message
|
|
395
|
-
#
|
|
396
|
-
# @param msg [String] a message
|
|
397
|
-
def warn(msg = nil, &block)
|
|
398
|
-
super("$$$$$$ #{msg}", &block)
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
# Log an error message
|
|
402
|
-
#
|
|
403
|
-
# @param msg [String] a message
|
|
404
|
-
def error(msg = nil, &block)
|
|
405
|
-
super(">>>>>> #{msg}", &block)
|
|
406
|
-
end
|
|
407
|
-
|
|
408
|
-
# Log a fatal message
|
|
409
|
-
#
|
|
410
|
-
# @param msg [String] a message
|
|
411
|
-
def fatal(msg = nil, &block)
|
|
412
|
-
super("!!!!!! #{msg}", &block)
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
# Log an unknown message
|
|
416
|
-
#
|
|
417
|
-
# @param msg [String] a message
|
|
418
|
-
def unknown(msg = nil, &block)
|
|
419
|
-
super("?????? #{msg}", &block)
|
|
420
|
-
end
|
|
421
|
-
end
|
|
422
|
-
end
|
|
423
|
-
end
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2013, Fletcher Nichol
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
require "fileutils"
|
|
20
|
+
require "logger"
|
|
21
|
+
|
|
22
|
+
module Kitchen
|
|
23
|
+
|
|
24
|
+
# Logging implementation for Kitchen. By default the console/stdout output
|
|
25
|
+
# will be displayed differently than the file log output. Therefor, this
|
|
26
|
+
# class wraps multiple loggers that conform to the stdlib `Logger` class
|
|
27
|
+
# behavior.
|
|
28
|
+
#
|
|
29
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
30
|
+
class Logger
|
|
31
|
+
|
|
32
|
+
include ::Logger::Severity
|
|
33
|
+
|
|
34
|
+
# @return [IO] the log device
|
|
35
|
+
attr_reader :logdev
|
|
36
|
+
|
|
37
|
+
# @return [Boolean] whether logger is configured for
|
|
38
|
+
# overwriting
|
|
39
|
+
attr_reader :log_overwrite
|
|
40
|
+
|
|
41
|
+
# Constructs a new logger.
|
|
42
|
+
#
|
|
43
|
+
# @param options [Hash] configuration for a new logger
|
|
44
|
+
# @option options [Symbol] :color color to use when when outputting
|
|
45
|
+
# messages
|
|
46
|
+
# @option options [Integer] :level the logging severity threshold
|
|
47
|
+
# (default: `Kitchen::DEFAULT_LOG_LEVEL`)
|
|
48
|
+
# @option options [Boolean] whether to overwrite the log
|
|
49
|
+
# when Test Kitchen runs. Only applies if the :logdev is a String.
|
|
50
|
+
# (default: `Kitchen::DEFAULT_LOG_OVERWRITE`)
|
|
51
|
+
# @option options [String,IO] :logdev filepath String or IO object to be
|
|
52
|
+
# used for logging (default: `nil`)
|
|
53
|
+
# @option options [String] :progname program name to include in log
|
|
54
|
+
# messages (default: `"Kitchen"`)
|
|
55
|
+
# @option options [IO] :stdout a standard out IO object to use
|
|
56
|
+
# (default: `$stdout`)
|
|
57
|
+
def initialize(options = {})
|
|
58
|
+
color = options[:color]
|
|
59
|
+
@log_overwrite = if options[:log_overwrite].nil?
|
|
60
|
+
default_log_overwrite
|
|
61
|
+
else
|
|
62
|
+
options[:log_overwrite]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
@logdev = logdev_logger(options[:logdev], log_overwrite) if options[:logdev]
|
|
66
|
+
|
|
67
|
+
populate_loggers(color, options)
|
|
68
|
+
|
|
69
|
+
# These setters cannot be called until @loggers are populated because
|
|
70
|
+
# they are delegated
|
|
71
|
+
self.progname = options[:progname] || "Kitchen"
|
|
72
|
+
self.level = options[:level] || default_log_level
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Pulled out for Rubocop complexity issues
|
|
76
|
+
#
|
|
77
|
+
# @api private
|
|
78
|
+
def populate_loggers(color, options)
|
|
79
|
+
@loggers = []
|
|
80
|
+
@loggers << logdev unless logdev.nil?
|
|
81
|
+
@loggers << stdout_logger(options[:stdout], color) if options[:stdout]
|
|
82
|
+
@loggers << stdout_logger($stdout, color) if @loggers.empty?
|
|
83
|
+
end
|
|
84
|
+
private :populate_loggers
|
|
85
|
+
|
|
86
|
+
class << self
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
# @api private
|
|
91
|
+
# @!macro delegate_to_first_logger
|
|
92
|
+
# @method $1()
|
|
93
|
+
def delegate_to_first_logger(meth)
|
|
94
|
+
define_method(meth) { |*args| @loggers.first.public_send(meth, *args) }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @api private
|
|
98
|
+
# @!macro delegate_to_all_loggers
|
|
99
|
+
# @method $1()
|
|
100
|
+
def delegate_to_all_loggers(meth)
|
|
101
|
+
define_method(meth) do |*args|
|
|
102
|
+
result = nil
|
|
103
|
+
@loggers.each { |l| result = l.public_send(meth, *args) }
|
|
104
|
+
result
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @return [Integer] the logging severity threshold
|
|
110
|
+
# @see http://is.gd/Okuy5p
|
|
111
|
+
delegate_to_first_logger :level
|
|
112
|
+
|
|
113
|
+
# Sets the logging severity threshold.
|
|
114
|
+
#
|
|
115
|
+
# @param level [Integer] the logging severity threshold
|
|
116
|
+
# @see http://is.gd/H1VBFH
|
|
117
|
+
delegate_to_all_loggers :level=
|
|
118
|
+
|
|
119
|
+
# @return [String] program name to include in log messages
|
|
120
|
+
# @see http://is.gd/5uHGK0
|
|
121
|
+
delegate_to_first_logger :progname
|
|
122
|
+
|
|
123
|
+
# Sets the program name to include in log messages.
|
|
124
|
+
#
|
|
125
|
+
# @param progname [String] the program name to include in log messages
|
|
126
|
+
# @see http://is.gd/f2U5Xj
|
|
127
|
+
delegate_to_all_loggers :progname=
|
|
128
|
+
|
|
129
|
+
# @return [String] the date format being used
|
|
130
|
+
# @see http://is.gd/btmFWJ
|
|
131
|
+
delegate_to_first_logger :datetime_format
|
|
132
|
+
|
|
133
|
+
# Sets the date format being used.
|
|
134
|
+
#
|
|
135
|
+
# @param format [String] the date format
|
|
136
|
+
# @see http://is.gd/M36ml8
|
|
137
|
+
delegate_to_all_loggers :datetime_format=
|
|
138
|
+
|
|
139
|
+
# Log a message if the given severity is high enough.
|
|
140
|
+
#
|
|
141
|
+
# @see http://is.gd/5opBW0
|
|
142
|
+
delegate_to_all_loggers :add
|
|
143
|
+
|
|
144
|
+
# Dump one or more messages to info.
|
|
145
|
+
#
|
|
146
|
+
# @param message [#to_s] the message to log
|
|
147
|
+
# @see http://is.gd/BCp5KV
|
|
148
|
+
delegate_to_all_loggers :<<
|
|
149
|
+
|
|
150
|
+
# Log a message with severity of banner (high level).
|
|
151
|
+
#
|
|
152
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
153
|
+
# form, this is the progname to use in the log message.
|
|
154
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
155
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
156
|
+
# create potentially expensive logging messages that are only called when
|
|
157
|
+
# the logger is configured to show them.
|
|
158
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
159
|
+
# particular logger), log no message, and return true
|
|
160
|
+
# @see http://is.gd/pYUCYU
|
|
161
|
+
delegate_to_all_loggers :banner
|
|
162
|
+
|
|
163
|
+
# Log a message with severity of debug.
|
|
164
|
+
#
|
|
165
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
166
|
+
# form, this is the progname to use in the log message.
|
|
167
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
168
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
169
|
+
# create potentially expensive logging messages that are only called when
|
|
170
|
+
# the logger is configured to show them.
|
|
171
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
172
|
+
# particular logger), log no message, and return true
|
|
173
|
+
# @see http://is.gd/Re97Zp
|
|
174
|
+
delegate_to_all_loggers :debug
|
|
175
|
+
|
|
176
|
+
# @return [true,false] whether or not the current severity level
|
|
177
|
+
# allows for the printing of debug messages
|
|
178
|
+
# @see http://is.gd/Iq08xB
|
|
179
|
+
delegate_to_first_logger :debug?
|
|
180
|
+
|
|
181
|
+
# Log a message with severity of info.
|
|
182
|
+
#
|
|
183
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
184
|
+
# form, this is the progname to use in the log message.
|
|
185
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
186
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
187
|
+
# create potentially expensive logging messages that are only called when
|
|
188
|
+
# the logger is configured to show them.
|
|
189
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
190
|
+
# particular logger), log no message, and return true
|
|
191
|
+
# @see http://is.gd/pYUCYU
|
|
192
|
+
delegate_to_all_loggers :info
|
|
193
|
+
|
|
194
|
+
# @return [true,false] whether or not the current severity level
|
|
195
|
+
# allows for the printing of info messages
|
|
196
|
+
# @see http://is.gd/lBtJkT
|
|
197
|
+
delegate_to_first_logger :info?
|
|
198
|
+
|
|
199
|
+
# Log a message with severity of error.
|
|
200
|
+
#
|
|
201
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
202
|
+
# form, this is the progname to use in the log message.
|
|
203
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
204
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
205
|
+
# create potentially expensive logging messages that are only called when
|
|
206
|
+
# the logger is configured to show them.
|
|
207
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
208
|
+
# particular logger), log no message, and return true
|
|
209
|
+
# @see http://is.gd/mLwYMl
|
|
210
|
+
delegate_to_all_loggers :error
|
|
211
|
+
|
|
212
|
+
# @return [true,false] whether or not the current severity level
|
|
213
|
+
# allows for the printing of error messages
|
|
214
|
+
# @see http://is.gd/QY19JL
|
|
215
|
+
delegate_to_first_logger :error?
|
|
216
|
+
|
|
217
|
+
# Log a message with severity of warn.
|
|
218
|
+
#
|
|
219
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
220
|
+
# form, this is the progname to use in the log message.
|
|
221
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
222
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
223
|
+
# create potentially expensive logging messages that are only called when
|
|
224
|
+
# the logger is configured to show them.
|
|
225
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
226
|
+
# particular logger), log no message, and return true
|
|
227
|
+
# @see http://is.gd/PX9AIS
|
|
228
|
+
delegate_to_all_loggers :warn
|
|
229
|
+
|
|
230
|
+
# @return [true,false] whether or not the current severity level
|
|
231
|
+
# allows for the printing of warn messages
|
|
232
|
+
# @see http://is.gd/Gdr4lD
|
|
233
|
+
delegate_to_first_logger :warn?
|
|
234
|
+
|
|
235
|
+
# Log a message with severity of fatal.
|
|
236
|
+
#
|
|
237
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
238
|
+
# form, this is the progname to use in the log message.
|
|
239
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
240
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
241
|
+
# create potentially expensive logging messages that are only called when
|
|
242
|
+
# the logger is configured to show them.
|
|
243
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
244
|
+
# particular logger), log no message, and return true
|
|
245
|
+
# @see http://is.gd/5ElFPK
|
|
246
|
+
delegate_to_all_loggers :fatal
|
|
247
|
+
|
|
248
|
+
# @return [true,false] whether or not the current severity level
|
|
249
|
+
# allows for the printing of fatal messages
|
|
250
|
+
# @see http://is.gd/7PgwRl
|
|
251
|
+
delegate_to_first_logger :fatal?
|
|
252
|
+
|
|
253
|
+
# Log a message with severity of unknown.
|
|
254
|
+
#
|
|
255
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
256
|
+
# form, this is the progname to use in the log message.
|
|
257
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
258
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
259
|
+
# create potentially expensive logging messages that are only called when
|
|
260
|
+
# the logger is configured to show them.
|
|
261
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
262
|
+
# particular logger), log no message, and return true
|
|
263
|
+
# @see http://is.gd/Y4hqpf
|
|
264
|
+
delegate_to_all_loggers :unknown
|
|
265
|
+
|
|
266
|
+
# Close the logging devices.
|
|
267
|
+
#
|
|
268
|
+
# @see http://is.gd/b13cVn
|
|
269
|
+
delegate_to_all_loggers :close
|
|
270
|
+
|
|
271
|
+
private
|
|
272
|
+
|
|
273
|
+
# @return [Integer] the default logger level
|
|
274
|
+
# @api private
|
|
275
|
+
def default_log_level
|
|
276
|
+
Util.to_logger_level(Kitchen::DEFAULT_LOG_LEVEL)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# @return [Boolean] whether to overwrite logs by default
|
|
280
|
+
# @api private
|
|
281
|
+
def default_log_overwrite
|
|
282
|
+
Kitchen::DEFAULT_LOG_OVERWRITE
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# Construct a new standard out logger.
|
|
286
|
+
#
|
|
287
|
+
# @param stdout [IO] the IO object that represents stdout (or similar)
|
|
288
|
+
# @param color [Symbol] color to use when outputing messages
|
|
289
|
+
# @return [StdoutLogger] a new logger
|
|
290
|
+
# @api private
|
|
291
|
+
def stdout_logger(stdout, color)
|
|
292
|
+
logger = StdoutLogger.new(stdout)
|
|
293
|
+
if Kitchen.tty?
|
|
294
|
+
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
295
|
+
Color.colorize("#{msg}", color).concat("\n")
|
|
296
|
+
end
|
|
297
|
+
else
|
|
298
|
+
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
299
|
+
msg.concat("\n")
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
logger
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Construct a new logdev logger.
|
|
306
|
+
#
|
|
307
|
+
# @param filepath_or_logdev [String,IO] a filepath String or IO object
|
|
308
|
+
# @param log_overwrite [Boolean] apply log overwriting
|
|
309
|
+
# if filepath_or_logdev is a file path
|
|
310
|
+
# @return [LogdevLogger] a new logger
|
|
311
|
+
# @api private
|
|
312
|
+
def logdev_logger(filepath_or_logdev, log_overwrite)
|
|
313
|
+
LogdevLogger.new(resolve_logdev(filepath_or_logdev, log_overwrite))
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Return an IO object from a filepath String or the IO object itself.
|
|
317
|
+
#
|
|
318
|
+
# @param filepath_or_logdev [String,IO] a filepath String or IO object
|
|
319
|
+
# @param log_overwrite [Boolean] apply log overwriting
|
|
320
|
+
# if filepath_or_logdev is a file path
|
|
321
|
+
# @return [IO] an IO object
|
|
322
|
+
# @api private
|
|
323
|
+
def resolve_logdev(filepath_or_logdev, log_overwrite)
|
|
324
|
+
if filepath_or_logdev.is_a? String
|
|
325
|
+
mode = log_overwrite ? "wb" : "ab"
|
|
326
|
+
FileUtils.mkdir_p(File.dirname(filepath_or_logdev))
|
|
327
|
+
file = File.open(File.expand_path(filepath_or_logdev), mode)
|
|
328
|
+
file.sync = true
|
|
329
|
+
file
|
|
330
|
+
else
|
|
331
|
+
filepath_or_logdev
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
# Internal class which adds a #banner method call that displays the
|
|
336
|
+
# message with a callout arrow.
|
|
337
|
+
class LogdevLogger < ::Logger
|
|
338
|
+
|
|
339
|
+
alias_method :super_info, :info
|
|
340
|
+
|
|
341
|
+
# Dump one or more messages to info.
|
|
342
|
+
#
|
|
343
|
+
# @param msg [String] a message
|
|
344
|
+
def <<(msg)
|
|
345
|
+
@buffer ||= ""
|
|
346
|
+
@buffer += msg
|
|
347
|
+
while i = @buffer.index("\n")
|
|
348
|
+
format_line(@buffer[0, i].chomp)
|
|
349
|
+
@buffer[0, i + 1] = ""
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# Log a banner message.
|
|
354
|
+
#
|
|
355
|
+
# @param msg [String] a message
|
|
356
|
+
def banner(msg = nil, &block)
|
|
357
|
+
super_info("-----> #{msg}", &block)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
private
|
|
361
|
+
|
|
362
|
+
# Reformat a line if it already contains log formatting.
|
|
363
|
+
#
|
|
364
|
+
# @param line [String] a message line
|
|
365
|
+
# @api private
|
|
366
|
+
def format_line(line)
|
|
367
|
+
case line
|
|
368
|
+
when %r{^-----> } then banner(line.gsub(%r{^[ >-]{6} }, ""))
|
|
369
|
+
when %r{^>>>>>> } then error(line.gsub(%r{^[ >-]{6} }, ""))
|
|
370
|
+
when %r{^ } then info(line.gsub(%r{^[ >-]{6} }, ""))
|
|
371
|
+
else info(line)
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# Internal class which reformats logging methods for display as console
|
|
377
|
+
# output.
|
|
378
|
+
class StdoutLogger < LogdevLogger
|
|
379
|
+
|
|
380
|
+
# Log a debug message
|
|
381
|
+
#
|
|
382
|
+
# @param msg [String] a message
|
|
383
|
+
def debug(msg = nil, &block)
|
|
384
|
+
super("D #{msg}", &block)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# Log an info message
|
|
388
|
+
#
|
|
389
|
+
# @param msg [String] a message
|
|
390
|
+
def info(msg = nil, &block)
|
|
391
|
+
super(" #{msg}", &block)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Log a warn message
|
|
395
|
+
#
|
|
396
|
+
# @param msg [String] a message
|
|
397
|
+
def warn(msg = nil, &block)
|
|
398
|
+
super("$$$$$$ #{msg}", &block)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
# Log an error message
|
|
402
|
+
#
|
|
403
|
+
# @param msg [String] a message
|
|
404
|
+
def error(msg = nil, &block)
|
|
405
|
+
super(">>>>>> #{msg}", &block)
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
# Log a fatal message
|
|
409
|
+
#
|
|
410
|
+
# @param msg [String] a message
|
|
411
|
+
def fatal(msg = nil, &block)
|
|
412
|
+
super("!!!!!! #{msg}", &block)
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# Log an unknown message
|
|
416
|
+
#
|
|
417
|
+
# @param msg [String] a message
|
|
418
|
+
def unknown(msg = nil, &block)
|
|
419
|
+
super("?????? #{msg}", &block)
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
end
|