logger 1.5.0 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|