logger 1.5.0 → 1.5.2
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/lib/logger/errors.rb +1 -1
- data/lib/logger/formatter.rb +1 -1
- data/lib/logger/log_device.rb +1 -1
- data/lib/logger/version.rb +1 -1
- data/lib/logger.rb +465 -308
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b70d947261ec2e9d94145b13c4831a54fa6c49864aa208e63d4151fd494de443
|
4
|
+
data.tar.gz: cda09e37794e00a0c56e66e7ade628f2acdf10312af790d0e2fd1d5c32bf30f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b26008735ad28617a11e8db99db0c5aa5abd5253f3950182da45d342d2bf360d6ef48da6cf1a87c11282ff242f59ee4b731093cb6e738b0464f2a78ceb4df7d1
|
7
|
+
data.tar.gz: 5aba8135b1e8322f1038b5bdff1d5ff7472edc3aa71a88f8798e944ea0fb1fad4884c2e6281c9e0691ded78fc9cf0ae75cf6a1d56b3fa23c33fc5e90b30aaa4e
|
data/lib/logger/errors.rb
CHANGED
data/lib/logger/formatter.rb
CHANGED
@@ -13,7 +13,7 @@ class Logger
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def call(severity, time, progname, msg)
|
16
|
-
Format % [severity[0
|
16
|
+
Format % [severity[0, 1], format_datetime(time), Process.pid, severity, progname,
|
17
17
|
msg2str(msg)]
|
18
18
|
end
|
19
19
|
|
data/lib/logger/log_device.rb
CHANGED
data/lib/logger/version.rb
CHANGED
data/lib/logger.rb
CHANGED
@@ -11,6 +11,7 @@
|
|
11
11
|
# A simple system for logging messages. See Logger for more documentation.
|
12
12
|
|
13
13
|
require 'monitor'
|
14
|
+
require 'rbconfig'
|
14
15
|
|
15
16
|
require_relative 'logger/version'
|
16
17
|
require_relative 'logger/formatter'
|
@@ -18,216 +19,353 @@ require_relative 'logger/log_device'
|
|
18
19
|
require_relative 'logger/severity'
|
19
20
|
require_relative 'logger/errors'
|
20
21
|
|
21
|
-
#
|
22
|
+
# \Class \Logger provides a simple but sophisticated logging utility that
|
23
|
+
# you can use to create one or more
|
24
|
+
# {event logs}[https://en.wikipedia.org/wiki/Logging_(software)#Event_logs]
|
25
|
+
# for your program.
|
26
|
+
# Each such log contains a chronological sequence of entries
|
27
|
+
# that provides a record of the program's activities.
|
22
28
|
#
|
23
|
-
#
|
24
|
-
# you can use to output messages.
|
29
|
+
# == About the Examples
|
25
30
|
#
|
26
|
-
#
|
27
|
-
# their importance. You can then give the Logger a level, and only messages
|
28
|
-
# at that level or higher will be printed.
|
31
|
+
# All examples on this page assume that \Logger has been required:
|
29
32
|
#
|
30
|
-
#
|
33
|
+
# require 'logger'
|
31
34
|
#
|
32
|
-
#
|
33
|
-
# +FATAL+:: An unhandleable error that results in a program crash.
|
34
|
-
# +ERROR+:: A handleable error condition.
|
35
|
-
# +WARN+:: A warning.
|
36
|
-
# +INFO+:: Generic (useful) information about system operation.
|
37
|
-
# +DEBUG+:: Low-level information for developers.
|
35
|
+
# == Synopsis
|
38
36
|
#
|
39
|
-
#
|
40
|
-
# +INFO+ or even +WARN+.
|
41
|
-
# When you are developing the system, however, you probably
|
42
|
-
# want to know about the program's internal state, and would set the Logger to
|
43
|
-
# +DEBUG+.
|
37
|
+
# Create a log with Logger.new:
|
44
38
|
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
39
|
+
# # Single log file.
|
40
|
+
# logger = Logger.new('t.log')
|
41
|
+
# # Size-based rotated logging: 3 10-megabyte files.
|
42
|
+
# logger = Logger.new('t.log', 3, 10485760)
|
43
|
+
# # Period-based rotated logging: daily (also allowed: 'weekly', 'monthly').
|
44
|
+
# logger = Logger.new('t.log', 'daily')
|
45
|
+
# # Log to an IO stream.
|
46
|
+
# logger = Logger.new($stdout)
|
48
47
|
#
|
49
|
-
#
|
50
|
-
# logger.info("User-input: %p" % input)
|
48
|
+
# Add entries (level, message) with Logger#add:
|
51
49
|
#
|
52
|
-
#
|
50
|
+
# logger.add(Logger::DEBUG, 'Maximal debugging info')
|
51
|
+
# logger.add(Logger::INFO, 'Non-error information')
|
52
|
+
# logger.add(Logger::WARN, 'Non-error warning')
|
53
|
+
# logger.add(Logger::ERROR, 'Non-fatal error')
|
54
|
+
# logger.add(Logger::FATAL, 'Fatal error')
|
55
|
+
# logger.add(Logger::UNKNOWN, 'Most severe')
|
53
56
|
#
|
54
|
-
#
|
55
|
-
# logger.formatter = proc { |severity, datetime, progname, msg|
|
56
|
-
# original_formatter.call(severity, datetime, progname, msg.dump)
|
57
|
-
# }
|
58
|
-
# logger.info(input)
|
57
|
+
# Close the log with Logger#close:
|
59
58
|
#
|
60
|
-
#
|
59
|
+
# logger.close
|
61
60
|
#
|
62
|
-
#
|
63
|
-
# level of +WARN+:
|
61
|
+
# == Entries
|
64
62
|
#
|
65
|
-
#
|
63
|
+
# You can add entries with method Logger#add:
|
64
|
+
#
|
65
|
+
# logger.add(Logger::DEBUG, 'Maximal debugging info')
|
66
|
+
# logger.add(Logger::INFO, 'Non-error information')
|
67
|
+
# logger.add(Logger::WARN, 'Non-error warning')
|
68
|
+
# logger.add(Logger::ERROR, 'Non-fatal error')
|
69
|
+
# logger.add(Logger::FATAL, 'Fatal error')
|
70
|
+
# logger.add(Logger::UNKNOWN, 'Most severe')
|
71
|
+
#
|
72
|
+
# These shorthand methods also add entries:
|
73
|
+
#
|
74
|
+
# logger.debug('Maximal debugging info')
|
75
|
+
# logger.info('Non-error information')
|
76
|
+
# logger.warn('Non-error warning')
|
77
|
+
# logger.error('Non-fatal error')
|
78
|
+
# logger.fatal('Fatal error')
|
79
|
+
# logger.unknown('Most severe')
|
80
|
+
#
|
81
|
+
# When you call any of these methods,
|
82
|
+
# the entry may or may not be written to the log,
|
83
|
+
# depending on the entry's severity and on the log level;
|
84
|
+
# see {Log Level}[rdoc-ref:Logger@Log+Level]
|
85
|
+
#
|
86
|
+
# An entry always has:
|
87
|
+
#
|
88
|
+
# - A severity (the required argument to #add).
|
89
|
+
# - An automatically created timestamp.
|
90
|
+
#
|
91
|
+
# And may also have:
|
92
|
+
#
|
93
|
+
# - A message.
|
94
|
+
# - A program name.
|
95
|
+
#
|
96
|
+
# Example:
|
97
|
+
#
|
98
|
+
# logger = Logger.new($stdout)
|
99
|
+
# logger.add(Logger::INFO, 'My message.', 'mung')
|
100
|
+
# # => I, [2022-05-07T17:21:46.536234 #20536] INFO -- mung: My message.
|
101
|
+
#
|
102
|
+
# The default format for an entry is:
|
103
|
+
#
|
104
|
+
# "%s, [%s #%d] %5s -- %s: %s\n"
|
105
|
+
#
|
106
|
+
# where the values to be formatted are:
|
107
|
+
#
|
108
|
+
# - \Severity (one letter).
|
109
|
+
# - Timestamp.
|
110
|
+
# - Process id.
|
111
|
+
# - \Severity (word).
|
112
|
+
# - Program name.
|
113
|
+
# - Message.
|
114
|
+
#
|
115
|
+
# You can use a different entry format by:
|
116
|
+
#
|
117
|
+
# - Setting a custom format proc (affects following entries);
|
118
|
+
# see {formatter=}[Logger.html#attribute-i-formatter].
|
119
|
+
# - Calling any of the methods above with a block
|
120
|
+
# (affects only the one entry).
|
121
|
+
# Doing so can have two benefits:
|
122
|
+
#
|
123
|
+
# - Context: the block can evaluate the entire program context
|
124
|
+
# and create a context-dependent message.
|
125
|
+
# - Performance: the block is not evaluated unless the log level
|
126
|
+
# permits the entry actually to be written:
|
127
|
+
#
|
128
|
+
# logger.error { my_slow_message_generator }
|
129
|
+
#
|
130
|
+
# Contrast this with the string form, where the string is
|
131
|
+
# always evaluated, regardless of the log level:
|
132
|
+
#
|
133
|
+
# logger.error("#{my_slow_message_generator}")
|
134
|
+
#
|
135
|
+
# === \Severity
|
136
|
+
#
|
137
|
+
# The severity of a log entry has two effects:
|
138
|
+
#
|
139
|
+
# - Determines whether the entry is selected for inclusion in the log;
|
140
|
+
# see {Log Level}[rdoc-ref:Logger@Log+Level].
|
141
|
+
# - Indicates to any log reader (whether a person or a program)
|
142
|
+
# the relative importance of the entry.
|
143
|
+
#
|
144
|
+
# === Timestamp
|
66
145
|
#
|
67
|
-
#
|
68
|
-
#
|
146
|
+
# The timestamp for a log entry is generated automatically
|
147
|
+
# when the entry is created.
|
69
148
|
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
149
|
+
# The logged timestamp is formatted by method
|
150
|
+
# {Time#strftime}[https://docs.ruby-lang.org/en/master/Time.html#method-i-strftime]
|
151
|
+
# using this format string:
|
73
152
|
#
|
74
|
-
#
|
153
|
+
# '%Y-%m-%dT%H:%M:%S.%6N'
|
75
154
|
#
|
76
|
-
#
|
77
|
-
# File.foreach(path) do |line|
|
78
|
-
# unless line =~ /^(\w+) = (.*)$/
|
79
|
-
# logger.error("Line in wrong format: #{line.chomp}")
|
80
|
-
# end
|
81
|
-
# end
|
82
|
-
# rescue => err
|
83
|
-
# logger.fatal("Caught exception; exiting")
|
84
|
-
# logger.fatal(err)
|
85
|
-
# end
|
155
|
+
# Example:
|
86
156
|
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
157
|
+
# logger = Logger.new($stdout)
|
158
|
+
# logger.add(Logger::INFO)
|
159
|
+
# # => I, [2022-05-07T17:04:32.318331 #20536] INFO -- : nil
|
90
160
|
#
|
91
|
-
#
|
161
|
+
# You can set a different format using method #datetime_format=.
|
92
162
|
#
|
93
|
-
#
|
94
|
-
# auto-rolling of log files, setting the format of log messages, and
|
95
|
-
# specifying a program name in conjunction with the message. The next section
|
96
|
-
# shows you how to achieve these things.
|
163
|
+
# === Message
|
97
164
|
#
|
165
|
+
# The message is an optional argument to an entry method:
|
98
166
|
#
|
99
|
-
#
|
167
|
+
# logger = Logger.new($stdout)
|
168
|
+
# logger.add(Logger::INFO, 'My message')
|
169
|
+
# # => I, [2022-05-07T18:15:37.647581 #20536] INFO -- : My message
|
100
170
|
#
|
101
|
-
#
|
171
|
+
# For the default entry formatter, <tt>Logger::Formatter</tt>,
|
172
|
+
# the message object may be:
|
102
173
|
#
|
103
|
-
#
|
104
|
-
#
|
174
|
+
# - A string: used as-is.
|
175
|
+
# - An Exception: <tt>message.message</tt> is used.
|
176
|
+
# - Anything else: <tt>message.inspect</tt> is used.
|
105
177
|
#
|
106
|
-
#
|
178
|
+
# *Note*: Logger::Formatter does not escape or sanitize
|
179
|
+
# the message passed to it.
|
180
|
+
# Developers should be aware that malicious data (user input)
|
181
|
+
# may be in the message, and should explicitly escape untrusted data.
|
107
182
|
#
|
108
|
-
#
|
109
|
-
#
|
183
|
+
# You can use a custom formatter to escape message data;
|
184
|
+
# see the example at {formatter=}[Logger.html#attribute-i-formatter].
|
110
185
|
#
|
111
|
-
#
|
186
|
+
# === Program Name
|
112
187
|
#
|
113
|
-
#
|
188
|
+
# The program name is an optional argument to an entry method:
|
114
189
|
#
|
115
|
-
#
|
190
|
+
# logger = Logger.new($stdout)
|
191
|
+
# logger.add(Logger::INFO, 'My message', 'mung')
|
192
|
+
# # => I, [2022-05-07T18:17:38.084716 #20536] INFO -- mung: My message
|
116
193
|
#
|
117
|
-
#
|
118
|
-
#
|
119
|
-
# # file = File.open('foo.log', File::WRONLY | File::APPEND | File::CREAT)
|
120
|
-
# logger = Logger.new(file)
|
194
|
+
# The default program name for a new logger may be set in the call to
|
195
|
+
# Logger.new via optional keyword argument +progname+:
|
121
196
|
#
|
122
|
-
#
|
123
|
-
# Leave 10 "old" log files where each file is about 1,024,000 bytes.
|
197
|
+
# logger = Logger.new('t.log', progname: 'mung')
|
124
198
|
#
|
125
|
-
#
|
199
|
+
# The default program name for an existing logger may be set
|
200
|
+
# by a call to method #progname=:
|
126
201
|
#
|
127
|
-
#
|
202
|
+
# logger.progname = 'mung'
|
128
203
|
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
# logger = Logger.new('foo.log', 'monthly')
|
204
|
+
# The current program name may be retrieved with method
|
205
|
+
# {progname}[Logger.html#attribute-i-progname]:
|
132
206
|
#
|
133
|
-
#
|
207
|
+
# logger.progname # => "mung"
|
134
208
|
#
|
135
|
-
#
|
136
|
-
# messages of various levels? Other methods in this family are +warn+ and
|
137
|
-
# +debug+. +add+ is used below to log a message of an arbitrary (perhaps
|
138
|
-
# dynamic) level.
|
209
|
+
# == Log Level
|
139
210
|
#
|
140
|
-
#
|
211
|
+
# The log level setting determines whether an entry is actually
|
212
|
+
# written to the log, based on the entry's severity.
|
141
213
|
#
|
142
|
-
#
|
214
|
+
# These are the defined severities (least severe to most severe):
|
143
215
|
#
|
144
|
-
#
|
216
|
+
# logger = Logger.new($stdout)
|
217
|
+
# logger.add(Logger::DEBUG, 'Maximal debugging info')
|
218
|
+
# # => D, [2022-05-07T17:57:41.776220 #20536] DEBUG -- : Maximal debugging info
|
219
|
+
# logger.add(Logger::INFO, 'Non-error information')
|
220
|
+
# # => I, [2022-05-07T17:59:14.349167 #20536] INFO -- : Non-error information
|
221
|
+
# logger.add(Logger::WARN, 'Non-error warning')
|
222
|
+
# # => W, [2022-05-07T18:00:45.337538 #20536] WARN -- : Non-error warning
|
223
|
+
# logger.add(Logger::ERROR, 'Non-fatal error')
|
224
|
+
# # => E, [2022-05-07T18:02:41.592912 #20536] ERROR -- : Non-fatal error
|
225
|
+
# logger.add(Logger::FATAL, 'Fatal error')
|
226
|
+
# # => F, [2022-05-07T18:05:24.703931 #20536] FATAL -- : Fatal error
|
227
|
+
# logger.add(Logger::UNKNOWN, 'Most severe')
|
228
|
+
# # => A, [2022-05-07T18:07:54.657491 #20536] ANY -- : Most severe
|
145
229
|
#
|
146
|
-
#
|
230
|
+
# The default initial level setting is Logger::DEBUG, the lowest level,
|
231
|
+
# which means that all entries are to be written, regardless of severity:
|
147
232
|
#
|
148
|
-
#
|
233
|
+
# logger = Logger.new($stdout)
|
234
|
+
# logger.level # => 0
|
235
|
+
# logger.add(0, "My message")
|
236
|
+
# # => D, [2022-05-11T15:10:59.773668 #20536] DEBUG -- : My message
|
149
237
|
#
|
150
|
-
#
|
238
|
+
# You can specify a different setting in a new logger
|
239
|
+
# using keyword argument +level+ with an appropriate value:
|
151
240
|
#
|
152
|
-
#
|
241
|
+
# logger = Logger.new($stdout, level: Logger::ERROR)
|
242
|
+
# logger = Logger.new($stdout, level: 'error')
|
243
|
+
# logger = Logger.new($stdout, level: :error)
|
244
|
+
# logger.level # => 3
|
153
245
|
#
|
154
|
-
#
|
246
|
+
# With this level, entries with severity Logger::ERROR and higher
|
247
|
+
# are written, while those with lower severities are not written:
|
155
248
|
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
#
|
249
|
+
# logger = Logger.new($stdout, level: Logger::ERROR)
|
250
|
+
# logger.add(3)
|
251
|
+
# # => E, [2022-05-11T15:17:20.933362 #20536] ERROR -- : nil
|
252
|
+
# logger.add(2) # Silent.
|
159
253
|
#
|
160
|
-
#
|
254
|
+
# You can set the log level for an existing logger
|
255
|
+
# with method #level=:
|
161
256
|
#
|
162
|
-
#
|
163
|
-
# and the entire block will not even be evaluated. Compare to this:
|
257
|
+
# logger.level = Logger::ERROR
|
164
258
|
#
|
165
|
-
#
|
259
|
+
# These shorthand methods also set the level:
|
166
260
|
#
|
167
|
-
#
|
168
|
-
#
|
261
|
+
# logger.debug! # => 0
|
262
|
+
# logger.info! # => 1
|
263
|
+
# logger.warn! # => 2
|
264
|
+
# logger.error! # => 3
|
265
|
+
# logger.fatal! # => 4
|
169
266
|
#
|
170
|
-
#
|
267
|
+
# You can retrieve the log level with method
|
268
|
+
# {level}[Logger.html#attribute-i-level]:
|
171
269
|
#
|
172
|
-
#
|
270
|
+
# logger.level = Logger::ERROR
|
271
|
+
# logger.level # => 3
|
173
272
|
#
|
174
|
-
#
|
273
|
+
# These methods return whether a given
|
274
|
+
# level is to be written:
|
175
275
|
#
|
176
|
-
#
|
276
|
+
# logger.level = Logger::ERROR
|
277
|
+
# logger.debug? # => false
|
278
|
+
# logger.info? # => false
|
279
|
+
# logger.warn? # => false
|
280
|
+
# logger.error? # => true
|
281
|
+
# logger.fatal? # => true
|
177
282
|
#
|
178
|
-
#
|
283
|
+
# == Log File Rotation
|
179
284
|
#
|
180
|
-
#
|
285
|
+
# By default, a log file is a single file that grows indefinitely
|
286
|
+
# (until explicitly closed); there is no file rotation.
|
181
287
|
#
|
182
|
-
#
|
288
|
+
# To keep log files to a manageable size,
|
289
|
+
# you can use _log_ _file_ _rotation_, which uses multiple log files:
|
183
290
|
#
|
184
|
-
#
|
291
|
+
# - Each log file has entries for a non-overlapping
|
292
|
+
# time interval.
|
293
|
+
# - Only the most recent log file is open and active;
|
294
|
+
# the others are closed and inactive.
|
185
295
|
#
|
186
|
-
#
|
296
|
+
# === Size-Based Rotation
|
187
297
|
#
|
188
|
-
#
|
189
|
-
# logger.level = 'INFO'
|
298
|
+
# For size-based log file rotation, call Logger.new with:
|
190
299
|
#
|
191
|
-
#
|
300
|
+
# - Argument +logdev+ as a file path.
|
301
|
+
# - Argument +shift_age+ with a positive integer:
|
302
|
+
# the number of log files to be in the rotation.
|
303
|
+
# - Argument +shift_size+ as a positive integer:
|
304
|
+
# the maximum size (in bytes) of each log file;
|
305
|
+
# defaults to 1048576 (1 megabyte).
|
192
306
|
#
|
193
|
-
#
|
307
|
+
# Examples:
|
194
308
|
#
|
195
|
-
#
|
196
|
-
#
|
197
|
-
# Logger.new(logdev, level: 'INFO')
|
309
|
+
# logger = Logger.new('t.log', 3) # Three 1-megabyte files.
|
310
|
+
# logger = Logger.new('t.log', 5, 10485760) # Five 10-megabyte files.
|
198
311
|
#
|
199
|
-
#
|
312
|
+
# For these examples, suppose:
|
200
313
|
#
|
201
|
-
#
|
202
|
-
# default. The default format and a sample are shown below:
|
314
|
+
# logger = Logger.new('t.log', 3)
|
203
315
|
#
|
204
|
-
#
|
205
|
-
#
|
316
|
+
# Logging begins in the new log file, +t.log+;
|
317
|
+
# the log file is "full" and ready for rotation
|
318
|
+
# when a new entry would cause its size to exceed +shift_size+.
|
206
319
|
#
|
207
|
-
#
|
208
|
-
# I, [1999-03-03T02:34:24.895701 #19074] INFO -- Main: info.
|
320
|
+
# The first time +t.log+ is full:
|
209
321
|
#
|
210
|
-
#
|
322
|
+
# - +t.log+ is closed and renamed to +t.log.0+.
|
323
|
+
# - A new file +t.log+ is opened.
|
211
324
|
#
|
212
|
-
#
|
213
|
-
# # e.g. "2004-01-03 00:54:26"
|
325
|
+
# The second time +t.log+ is full:
|
214
326
|
#
|
215
|
-
#
|
327
|
+
# - +t.log.0 is renamed as +t.log.1+.
|
328
|
+
# - +t.log+ is closed and renamed to +t.log.0+.
|
329
|
+
# - A new file +t.log+ is opened.
|
216
330
|
#
|
217
|
-
#
|
331
|
+
# Each subsequent time that +t.log+ is full,
|
332
|
+
# the log files are rotated:
|
218
333
|
#
|
219
|
-
#
|
334
|
+
# - +t.log.1+ is removed.
|
335
|
+
# - +t.log.0 is renamed as +t.log.1+.
|
336
|
+
# - +t.log+ is closed and renamed to +t.log.0+.
|
337
|
+
# - A new file +t.log+ is opened.
|
220
338
|
#
|
221
|
-
#
|
222
|
-
# "#{datetime}: #{msg}\n"
|
223
|
-
# end
|
224
|
-
# # e.g. "2005-09-22 08:51:08 +0900: hello world"
|
339
|
+
# === Periodic Rotation
|
225
340
|
#
|
226
|
-
#
|
341
|
+
# For periodic rotation, call Logger.new with:
|
227
342
|
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
343
|
+
# - Argument +logdev+ as a file path.
|
344
|
+
# - Argument +shift_age+ as a string period indicator.
|
345
|
+
#
|
346
|
+
# Examples:
|
347
|
+
#
|
348
|
+
# logger = Logger.new('t.log', 'daily') # Rotate log files daily.
|
349
|
+
# logger = Logger.new('t.log', 'weekly') # Rotate log files weekly.
|
350
|
+
# logger = Logger.new('t.log', 'monthly') # Rotate log files monthly.
|
351
|
+
#
|
352
|
+
# Example:
|
353
|
+
#
|
354
|
+
# logger = Logger.new('t.log', 'daily')
|
355
|
+
#
|
356
|
+
# When the given period expires:
|
357
|
+
#
|
358
|
+
# - The base log file, +t.log+ is closed and renamed
|
359
|
+
# with a date-based suffix such as +t.log.20220509+.
|
360
|
+
# - A new log file +t.log+ is opened.
|
361
|
+
# - Nothing is removed.
|
362
|
+
#
|
363
|
+
# The default format for the suffix is <tt>'%Y%m%d'</tt>,
|
364
|
+
# which produces a suffix similar to the one above.
|
365
|
+
# You can set a different format using create-time option
|
366
|
+
# +shift_period_suffix+;
|
367
|
+
# see details and suggestions at
|
368
|
+
# {Time#strftime}[https://docs.ruby-lang.org/en/master/Time.html#method-i-strftime].
|
231
369
|
#
|
232
370
|
class Logger
|
233
371
|
_, name, rev = %w$Id$
|
@@ -244,9 +382,18 @@ class Logger
|
|
244
382
|
# Logging severity threshold (e.g. <tt>Logger::INFO</tt>).
|
245
383
|
attr_reader :level
|
246
384
|
|
247
|
-
#
|
385
|
+
# Sets the log level; returns +severity+.
|
386
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
387
|
+
#
|
388
|
+
# Argument +severity+ may be an integer, a string, or a symbol:
|
389
|
+
#
|
390
|
+
# logger.level = Logger::ERROR # => 3
|
391
|
+
# logger.level = 3 # => 3
|
392
|
+
# logger.level = 'error' # => "error"
|
393
|
+
# logger.level = :error # => :error
|
394
|
+
#
|
395
|
+
# Logger#sev_threshold= is an alias for Logger#level=.
|
248
396
|
#
|
249
|
-
# +severity+:: The Severity of the log message.
|
250
397
|
def level=(severity)
|
251
398
|
if severity.is_a?(Integer)
|
252
399
|
@level = severity
|
@@ -273,109 +420,159 @@ class Logger
|
|
273
420
|
# Program name to include in log messages.
|
274
421
|
attr_accessor :progname
|
275
422
|
|
276
|
-
#
|
423
|
+
# Sets the date-time format.
|
424
|
+
#
|
425
|
+
# Argument +datetime_format+ should be either of these:
|
426
|
+
#
|
427
|
+
# - A string suitable for use as a format for method
|
428
|
+
# {Time#strftime}[https://docs.ruby-lang.org/en/master/Time.html#method-i-strftime].
|
429
|
+
# - +nil+: the logger uses <tt>'%Y-%m-%dT%H:%M:%S.%6N'</tt>.
|
277
430
|
#
|
278
|
-
# +datetime_format+:: A string suitable for passing to +strftime+.
|
279
431
|
def datetime_format=(datetime_format)
|
280
432
|
@default_formatter.datetime_format = datetime_format
|
281
433
|
end
|
282
434
|
|
283
|
-
# Returns the date format
|
435
|
+
# Returns the date-time format; see #datetime_format=.
|
436
|
+
#
|
284
437
|
def datetime_format
|
285
438
|
@default_formatter.datetime_format
|
286
439
|
end
|
287
440
|
|
288
|
-
#
|
289
|
-
# return the formatted message. The arguments are:
|
441
|
+
# Sets or retrieves the logger entry formatter proc.
|
290
442
|
#
|
291
|
-
# +
|
292
|
-
#
|
293
|
-
# +
|
294
|
-
#
|
295
|
-
#
|
443
|
+
# When +formatter+ is +nil+, the logger uses Logger::Formatter.
|
444
|
+
#
|
445
|
+
# When +formatter+ is a proc, a new entry is formatted by the proc,
|
446
|
+
# which is called with four arguments:
|
447
|
+
#
|
448
|
+
# - +severity+: The severity of the entry.
|
449
|
+
# - +time+: A Time object representing the entry's timestamp.
|
450
|
+
# - +progname+: The program name for the entry.
|
451
|
+
# - +msg+: The message for the entry (string or string-convertible object).
|
452
|
+
#
|
453
|
+
# The proc should return a string containing the formatted entry.
|
454
|
+
#
|
455
|
+
# This custom formatter uses
|
456
|
+
# {String#dump}[https://docs.ruby-lang.org/en/master/String.html#method-i-dump]
|
457
|
+
# to escape the message string:
|
458
|
+
#
|
459
|
+
# logger = Logger.new($stdout, progname: 'mung')
|
460
|
+
# original_formatter = logger.formatter || Logger::Formatter.new
|
461
|
+
# logger.formatter = proc { |severity, time, progname, msg|
|
462
|
+
# original_formatter.call(severity, time, progname, msg.dump)
|
463
|
+
# }
|
464
|
+
# logger.add(Logger::INFO, "hello \n ''")
|
465
|
+
# logger.add(Logger::INFO, "\f\x00\xff\\\"")
|
466
|
+
#
|
467
|
+
# Output:
|
468
|
+
#
|
469
|
+
# I, [2022-05-13T13:16:29.637488 #8492] INFO -- mung: "hello \n ''"
|
470
|
+
# I, [2022-05-13T13:16:29.637610 #8492] INFO -- mung: "\f\x00\xFF\\\""
|
296
471
|
#
|
297
|
-
# The block should return an Object that can be written to the logging
|
298
|
-
# device via +write+. The default formatter is used when no formatter is
|
299
|
-
# set.
|
300
472
|
attr_accessor :formatter
|
301
473
|
|
302
474
|
alias sev_threshold level
|
303
475
|
alias sev_threshold= level=
|
304
476
|
|
305
|
-
# Returns +true+ if
|
306
|
-
#
|
477
|
+
# Returns +true+ if the log level allows entries with severity
|
478
|
+
# Logger::DEBUG to be written, +false+ otherwise.
|
479
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
480
|
+
#
|
307
481
|
def debug?; level <= DEBUG; end
|
308
482
|
|
309
|
-
# Sets the
|
483
|
+
# Sets the log level to Logger::DEBUG.
|
484
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
485
|
+
#
|
310
486
|
def debug!; self.level = DEBUG; end
|
311
487
|
|
312
|
-
# Returns +true+ if
|
313
|
-
#
|
488
|
+
# Returns +true+ if the log level allows entries with severity
|
489
|
+
# Logger::INFO to be written, +false+ otherwise.
|
490
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
491
|
+
#
|
314
492
|
def info?; level <= INFO; end
|
315
493
|
|
316
|
-
# Sets the
|
494
|
+
# Sets the log level to Logger::INFO.
|
495
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
496
|
+
#
|
317
497
|
def info!; self.level = INFO; end
|
318
498
|
|
319
|
-
# Returns +true+ if
|
320
|
-
#
|
499
|
+
# Returns +true+ if the log level allows entries with severity
|
500
|
+
# Logger::WARN to be written, +false+ otherwise.
|
501
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
502
|
+
#
|
321
503
|
def warn?; level <= WARN; end
|
322
504
|
|
323
|
-
# Sets the
|
505
|
+
# Sets the log level to Logger::WARN.
|
506
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
507
|
+
#
|
324
508
|
def warn!; self.level = WARN; end
|
325
509
|
|
326
|
-
# Returns +true+ if
|
327
|
-
#
|
510
|
+
# Returns +true+ if the log level allows entries with severity
|
511
|
+
# Logger::ERROR to be written, +false+ otherwise.
|
512
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
513
|
+
#
|
328
514
|
def error?; level <= ERROR; end
|
329
515
|
|
330
|
-
# Sets the
|
516
|
+
# Sets the log level to Logger::ERROR.
|
517
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
518
|
+
#
|
331
519
|
def error!; self.level = ERROR; end
|
332
520
|
|
333
|
-
# Returns +true+ if
|
334
|
-
#
|
521
|
+
# Returns +true+ if the log level allows entries with severity
|
522
|
+
# Logger::FATAL to be written, +false+ otherwise.
|
523
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
524
|
+
#
|
335
525
|
def fatal?; level <= FATAL; end
|
336
526
|
|
337
|
-
# Sets the
|
527
|
+
# Sets the log level to Logger::FATAL.
|
528
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level].
|
529
|
+
#
|
338
530
|
def fatal!; self.level = FATAL; end
|
339
531
|
|
340
|
-
#
|
341
532
|
# :call-seq:
|
342
|
-
#
|
343
|
-
#
|
344
|
-
#
|
345
|
-
#
|
346
|
-
#
|
347
|
-
# Logger.new(
|
348
|
-
#
|
349
|
-
#
|
350
|
-
#
|
351
|
-
#
|
352
|
-
#
|
353
|
-
#
|
354
|
-
#
|
355
|
-
#
|
356
|
-
#
|
357
|
-
#
|
358
|
-
#
|
359
|
-
#
|
360
|
-
#
|
361
|
-
#
|
362
|
-
#
|
363
|
-
#
|
364
|
-
#
|
365
|
-
#
|
366
|
-
# +
|
367
|
-
#
|
368
|
-
#
|
369
|
-
#
|
370
|
-
# +
|
371
|
-
#
|
372
|
-
#
|
373
|
-
#
|
374
|
-
#
|
375
|
-
#
|
376
|
-
#
|
377
|
-
#
|
378
|
-
#
|
533
|
+
# Logger.new(logdev, shift_age = 0, shift_size = 1048576, **options)
|
534
|
+
#
|
535
|
+
# With the single argument +logdev+,
|
536
|
+
# returns a new logger with all default options:
|
537
|
+
#
|
538
|
+
# Logger.new('t.log') # => #<Logger:0x000001e685dc6ac8>
|
539
|
+
#
|
540
|
+
# Argument +logdev+ must be one of:
|
541
|
+
#
|
542
|
+
# - A string filepath: entries are to be written
|
543
|
+
# to the file at that path; if the file at that path exists,
|
544
|
+
# new entries are appended.
|
545
|
+
# - An IO stream (typically +$stdout+, +$stderr+. or an open file):
|
546
|
+
# entries are to be written to the given stream.
|
547
|
+
# - +nil+ or +File::NULL+: no entries are to be written.
|
548
|
+
#
|
549
|
+
# Examples:
|
550
|
+
#
|
551
|
+
# Logger.new('t.log')
|
552
|
+
# Logger.new($stdout)
|
553
|
+
#
|
554
|
+
# The keyword options are:
|
555
|
+
#
|
556
|
+
# - +level+: sets the log level; default value is Logger::DEBUG.
|
557
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level]:
|
558
|
+
#
|
559
|
+
# Logger.new('t.log', level: Logger::ERROR)
|
560
|
+
#
|
561
|
+
# - +progname+: sets the default program name; default is +nil+.
|
562
|
+
# See {Program Name}[rdoc-ref:Logger@Program+Name]:
|
563
|
+
#
|
564
|
+
# Logger.new('t.log', progname: 'mung')
|
565
|
+
#
|
566
|
+
# - +formatter+: sets the entry formatter; default is +nil+.
|
567
|
+
# See {formatter=}[Logger.html#attribute-i-formatter].
|
568
|
+
# - +datetime_format+: sets the format for entry timestamp;
|
569
|
+
# default is +nil+.
|
570
|
+
# See #datetime_format=.
|
571
|
+
# - +binmode+: sets whether the logger writes in binary mode;
|
572
|
+
# default is +false+.
|
573
|
+
# - +shift_period_suffix+: sets the format for the filename suffix
|
574
|
+
# for periodic log file rotation; default is <tt>'%Y%m%d'</tt>.
|
575
|
+
# See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation].
|
379
576
|
#
|
380
577
|
def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG,
|
381
578
|
progname: nil, formatter: nil, datetime_format: nil,
|
@@ -394,67 +591,60 @@ class Logger
|
|
394
591
|
end
|
395
592
|
end
|
396
593
|
|
397
|
-
#
|
398
|
-
#
|
399
|
-
#
|
400
|
-
#
|
401
|
-
#
|
402
|
-
#
|
403
|
-
#
|
404
|
-
#
|
405
|
-
#
|
406
|
-
#
|
407
|
-
#
|
408
|
-
#
|
409
|
-
#
|
410
|
-
#
|
411
|
-
#
|
594
|
+
# Sets the logger's output stream:
|
595
|
+
#
|
596
|
+
# - If +logdev+ is +nil+, reopens the current output stream.
|
597
|
+
# - If +logdev+ is a filepath, opens the indicated file for append.
|
598
|
+
# - If +logdev+ is an IO stream
|
599
|
+
# (usually <tt>$stdout</tt>, <tt>$stderr</tt>, or an open File object),
|
600
|
+
# opens the stream for append.
|
601
|
+
#
|
602
|
+
# Example:
|
603
|
+
#
|
604
|
+
# logger = Logger.new('t.log')
|
605
|
+
# logger.add(Logger::ERROR, 'one')
|
606
|
+
# logger.close
|
607
|
+
# logger.add(Logger::ERROR, 'two') # Prints 'log writing failed. closed stream'
|
608
|
+
# logger.reopen
|
609
|
+
# logger.add(Logger::ERROR, 'three')
|
610
|
+
# logger.close
|
611
|
+
# File.readlines('t.log')
|
612
|
+
# # =>
|
613
|
+
# # ["# Logfile created on 2022-05-12 14:21:19 -0500 by logger.rb/v1.5.0\n",
|
614
|
+
# # "E, [2022-05-12T14:21:27.596726 #22428] ERROR -- : one\n",
|
615
|
+
# # "E, [2022-05-12T14:23:05.847241 #22428] ERROR -- : three\n"]
|
412
616
|
#
|
413
617
|
def reopen(logdev = nil)
|
414
618
|
@logdev&.reopen(logdev)
|
415
619
|
self
|
416
620
|
end
|
417
621
|
|
622
|
+
# Creates a log entry, which may or may not be written to the log,
|
623
|
+
# depending on the entry's severity and on the log level.
|
624
|
+
# See {Log Level}[rdoc-ref:Logger@Log+Level]
|
625
|
+
# and {Entries}[rdoc-ref:Logger@Entries] for details.
|
418
626
|
#
|
419
|
-
# :
|
420
|
-
# Logger#add(severity, message = nil, progname = nil) { ... }
|
421
|
-
#
|
422
|
-
# === Args
|
423
|
-
#
|
424
|
-
# +severity+::
|
425
|
-
# Severity. Constants are defined in Logger namespace: +DEBUG+, +INFO+,
|
426
|
-
# +WARN+, +ERROR+, +FATAL+, or +UNKNOWN+.
|
427
|
-
# +message+::
|
428
|
-
# The log message. A String or Exception.
|
429
|
-
# +progname+::
|
430
|
-
# Program name string. Can be omitted. Treated as a message if no
|
431
|
-
# +message+ and +block+ are given.
|
432
|
-
# +block+::
|
433
|
-
# Can be omitted. Called to get a message string if +message+ is nil.
|
434
|
-
#
|
435
|
-
# === Return
|
436
|
-
#
|
437
|
-
# When the given severity is not high enough (for this particular logger),
|
438
|
-
# log no message, and return +true+.
|
627
|
+
# Examples:
|
439
628
|
#
|
440
|
-
#
|
629
|
+
# logger = Logger.new($stdout, progname: 'mung')
|
630
|
+
# logger.add(Logger::INFO)
|
631
|
+
# logger.add(Logger::ERROR, 'No good')
|
632
|
+
# logger.add(Logger::ERROR, 'No good', 'gnum')
|
441
633
|
#
|
442
|
-
#
|
443
|
-
# logging method. Users will be more inclined to use #debug, #info, #warn,
|
444
|
-
# #error, and #fatal.
|
634
|
+
# Output:
|
445
635
|
#
|
446
|
-
#
|
447
|
-
#
|
448
|
-
#
|
449
|
-
# A special case is an +Exception+ object, which will be printed in detail,
|
450
|
-
# including message, class, and backtrace. See #msg2str for the
|
451
|
-
# implementation if required.
|
636
|
+
# I, [2022-05-12T16:25:31.469726 #36328] INFO -- mung: mung
|
637
|
+
# E, [2022-05-12T16:25:55.349414 #36328] ERROR -- mung: No good
|
638
|
+
# E, [2022-05-12T16:26:35.841134 #36328] ERROR -- gnum: No good
|
452
639
|
#
|
453
|
-
#
|
640
|
+
# These convenience methods have implicit severity:
|
454
641
|
#
|
455
|
-
#
|
456
|
-
#
|
457
|
-
#
|
642
|
+
# - #debug.
|
643
|
+
# - #info.
|
644
|
+
# - #warn.
|
645
|
+
# - #error.
|
646
|
+
# - #fatal.
|
647
|
+
# - #unknown.
|
458
648
|
#
|
459
649
|
def add(severity, message = nil, progname = nil)
|
460
650
|
severity ||= UNKNOWN
|
@@ -478,104 +668,71 @@ class Logger
|
|
478
668
|
end
|
479
669
|
alias log add
|
480
670
|
|
671
|
+
# Writes the given +msg+ to the log with no formatting;
|
672
|
+
# returns the number of characters written,
|
673
|
+
# or +nil+ if no log device exists:
|
481
674
|
#
|
482
|
-
#
|
483
|
-
#
|
675
|
+
# logger = Logger.new($stdout)
|
676
|
+
# logger << 'My message.' # => 10
|
677
|
+
#
|
678
|
+
# Output:
|
679
|
+
#
|
680
|
+
# My message.
|
484
681
|
#
|
485
682
|
def <<(msg)
|
486
683
|
@logdev&.write(msg)
|
487
684
|
end
|
488
685
|
|
489
|
-
#
|
490
|
-
# Log a +DEBUG+ message.
|
491
|
-
#
|
492
|
-
# See #info for more information.
|
686
|
+
# Equivalent to calling #add with severity <tt>Logger::DEBUG</tt>.
|
493
687
|
#
|
494
688
|
def debug(progname = nil, &block)
|
495
689
|
add(DEBUG, nil, progname, &block)
|
496
690
|
end
|
497
691
|
|
498
|
-
#
|
499
|
-
# :call-seq:
|
500
|
-
# info(message)
|
501
|
-
# info(progname, &block)
|
502
|
-
#
|
503
|
-
# Log an +INFO+ message.
|
504
|
-
#
|
505
|
-
# +message+:: The message to log; does not need to be a String.
|
506
|
-
# +progname+:: In the block form, this is the #progname to use in the
|
507
|
-
# log message. The default can be set with #progname=.
|
508
|
-
# +block+:: Evaluates to the message to log. This is not evaluated unless
|
509
|
-
# the logger's level is sufficient to log the message. This
|
510
|
-
# allows you to create potentially expensive logging messages that
|
511
|
-
# are only called when the logger is configured to show them.
|
512
|
-
#
|
513
|
-
# === Examples
|
514
|
-
#
|
515
|
-
# logger.info("MainApp") { "Received connection from #{ip}" }
|
516
|
-
# # ...
|
517
|
-
# logger.info "Waiting for input from user"
|
518
|
-
# # ...
|
519
|
-
# logger.info { "User typed #{input}" }
|
520
|
-
#
|
521
|
-
# You'll probably stick to the second form above, unless you want to provide a
|
522
|
-
# program name (which you can do with #progname= as well).
|
523
|
-
#
|
524
|
-
# === Return
|
525
|
-
#
|
526
|
-
# See #add.
|
692
|
+
# Equivalent to calling #add with severity <tt>Logger::INFO</tt>.
|
527
693
|
#
|
528
694
|
def info(progname = nil, &block)
|
529
695
|
add(INFO, nil, progname, &block)
|
530
696
|
end
|
531
697
|
|
532
|
-
#
|
533
|
-
# Log a +WARN+ message.
|
534
|
-
#
|
535
|
-
# See #info for more information.
|
698
|
+
# Equivalent to calling #add with severity <tt>Logger::WARN</tt>.
|
536
699
|
#
|
537
700
|
def warn(progname = nil, &block)
|
538
701
|
add(WARN, nil, progname, &block)
|
539
702
|
end
|
540
703
|
|
541
|
-
#
|
542
|
-
# Log an +ERROR+ message.
|
543
|
-
#
|
544
|
-
# See #info for more information.
|
704
|
+
# Equivalent to calling #add with severity <tt>Logger::ERROR</tt>.
|
545
705
|
#
|
546
706
|
def error(progname = nil, &block)
|
547
707
|
add(ERROR, nil, progname, &block)
|
548
708
|
end
|
549
709
|
|
550
|
-
#
|
551
|
-
# Log a +FATAL+ message.
|
552
|
-
#
|
553
|
-
# See #info for more information.
|
710
|
+
# Equivalent to calling #add with severity <tt>Logger::FATAL</tt>.
|
554
711
|
#
|
555
712
|
def fatal(progname = nil, &block)
|
556
713
|
add(FATAL, nil, progname, &block)
|
557
714
|
end
|
558
715
|
|
559
|
-
#
|
560
|
-
# Log an +UNKNOWN+ message. This will be printed no matter what the logger's
|
561
|
-
# level is.
|
562
|
-
#
|
563
|
-
# See #info for more information.
|
716
|
+
# Equivalent to calling #add with severity <tt>Logger::UNKNOWN</tt>.
|
564
717
|
#
|
565
718
|
def unknown(progname = nil, &block)
|
566
719
|
add(UNKNOWN, nil, progname, &block)
|
567
720
|
end
|
568
721
|
|
722
|
+
# Closes the logger; returns +nil+:
|
569
723
|
#
|
570
|
-
#
|
724
|
+
# logger = Logger.new('t.log')
|
725
|
+
# logger.close # => nil
|
726
|
+
# logger.info('foo') # Prints "log writing failed. closed stream"
|
571
727
|
#
|
728
|
+
# Related: Logger#reopen.
|
572
729
|
def close
|
573
730
|
@logdev&.close
|
574
731
|
end
|
575
732
|
|
576
733
|
private
|
577
734
|
|
578
|
-
# Severity label for logging (max 5 chars).
|
735
|
+
# \Severity label for logging (max 5 chars).
|
579
736
|
SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY).freeze
|
580
737
|
|
581
738
|
def format_severity(severity)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Naotoshi Seo
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-12-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '0'
|
105
105
|
requirements: []
|
106
|
-
rubygems_version: 3.
|
106
|
+
rubygems_version: 3.4.0.dev
|
107
107
|
signing_key:
|
108
108
|
specification_version: 4
|
109
109
|
summary: Provides a simple logging utility for outputting messages.
|