D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
alt
/
ruby34
/
share
/
ri
/
system
/
Logger
/
Filename :
cdesc-Logger.ri
back
Copy
U:RDoc::NormalClass[iI"Logger:ET@I"Object;To:RDoc::Markup::Document:@parts[o;;[�o:RDoc::Markup::Paragraph;[I"M\Class \Logger provides a simple but sophisticated logging utility that ;TI"'you can use to create one or more ;TI"O{event logs}[https://en.wikipedia.org/wiki/Logging_(software)#Event_logs] ;TI"for your program. ;TI"@Each such log contains a chronological sequence of entries ;TI"8that provides a record of the program's activities.;To:RDoc::Markup::BlankLine S:RDoc::Markup::Heading: leveli: textI"About the Examples;T@o; ;[I"EAll examples on this page assume that \Logger has been required:;T@o:RDoc::Markup::Verbatim;[I"require 'logger' ;T:@format0S;;i; I" Synopsis;T@o; ;[I""Create a log with Logger.new:;T@o;;[ I"# Single log file. ;TI""logger = Logger.new('t.log') ;TI"8# Size-based rotated logging: 3 10-megabyte files. ;TI"/logger = Logger.new('t.log', 3, 10485760) ;TI"P# Period-based rotated logging: daily (also allowed: 'weekly', 'monthly'). ;TI"+logger = Logger.new('t.log', 'daily') ;TI"# Log to an IO stream. ;TI""logger = Logger.new($stdout) ;T;0o; ;[I"2Add entries (level, message) with Logger#add:;T@o;;[I"9logger.add(Logger::DEBUG, 'Maximal debugging info') ;TI"7logger.add(Logger::INFO, 'Non-error information') ;TI"3logger.add(Logger::WARN, 'Non-error warning') ;TI"2logger.add(Logger::ERROR, 'Non-fatal error') ;TI".logger.add(Logger::FATAL, 'Fatal error') ;TI"0logger.add(Logger::UNKNOWN, 'Most severe') ;T;0o; ;[I"%Close the log with Logger#close:;T@o;;[I"logger.close ;T;0S;;i; I"Entries;T@o; ;[I"0You can add entries with method Logger#add:;T@o;;[I"9logger.add(Logger::DEBUG, 'Maximal debugging info') ;TI"7logger.add(Logger::INFO, 'Non-error information') ;TI"3logger.add(Logger::WARN, 'Non-error warning') ;TI"2logger.add(Logger::ERROR, 'Non-fatal error') ;TI".logger.add(Logger::FATAL, 'Fatal error') ;TI"0logger.add(Logger::UNKNOWN, 'Most severe') ;T;0o; ;[I".These shorthand methods also add entries:;T@o;;[I",logger.debug('Maximal debugging info') ;TI"*logger.info('Non-error information') ;TI"&logger.warn('Non-error warning') ;TI"%logger.error('Non-fatal error') ;TI"!logger.fatal('Fatal error') ;TI"#logger.unknown('Most severe') ;T;0o; ;[ I")When you call any of these methods, ;TI"5the entry may or may not be written to the log, ;TI"=depending on the entry's severity and on the log level; ;TI"/see {Log Level}[rdoc-ref:Logger@Log+Level];T@o; ;[I"An entry always has:;T@o:RDoc::Markup::List: @type:BULLET:@items[o:RDoc::Markup::ListItem:@label0;[o; ;[I"0A severity (the required argument to #add).;To;;0;[o; ;[I"(An automatically created timestamp.;T@o; ;[I"And may also have:;T@o;;;;[o;;0;[o; ;[I"A message.;To;;0;[o; ;[I"A program name.;T@o; ;[I" Example:;T@o;;[I""logger = Logger.new($stdout) ;TI"5logger.add(Logger::INFO, 'My message.', 'mung') ;TI"L# => I, [2022-05-07T17:21:46.536234 #20536] INFO -- mung: My message. ;T;0o; ;[I"(The default format for an entry is:;T@o;;[I"$"%s, [%s #%d] %5s -- %s: %s\n" ;T;0o; ;[I"*where the values to be formatted are:;T@o;;;;[o;;0;[o; ;[I"\Severity (one letter).;To;;0;[o; ;[I"Timestamp.;To;;0;[o; ;[I"Process id.;To;;0;[o; ;[I"\Severity (word).;To;;0;[o; ;[I"Program name.;To;;0;[o; ;[I" Message.;T@o; ;[I"-You can use a different entry format by:;T@o;;;;[o;;0;[o; ;[I"?Setting a custom format proc (affects following entries); ;TI"9see {formatter=}[Logger.html#attribute-i-formatter].;To;;0;[o; ;[I"3Calling any of the methods above with a block ;TI"#(affects only the one entry). ;TI"$Doing so can have two benefits:;T@o;;;;[o;;0;[o; ;[I"@Context: the block can evaluate the entire program context ;TI",and create a context-dependent message.;To;;0;[o; ;[I"BPerformance: the block is not evaluated unless the log level ;TI".permits the entry actually to be written:;T@o;;[I"0logger.error { my_slow_message_generator } ;T;0o; ;[I"=Contrast this with the string form, where the string is ;TI"3always evaluated, regardless of the log level:;T@o;;[I"2logger.error("#{my_slow_message_generator}") ;T;0S;;i; I"\Severity;T@o; ;[I"1The severity of a log entry has two effects:;T@o;;;;[o;;0;[o; ;[I"HDetermines whether the entry is selected for inclusion in the log; ;TI"0see {Log Level}[rdoc-ref:Logger@Log+Level].;To;;0;[o; ;[I"AIndicates to any log reader (whether a person or a program) ;TI"*the relative importance of the entry.;T@S;;i; I"Timestamp;T@o; ;[I">The timestamp for a log entry is generated automatically ;TI"when the entry is created.;T@o; ;[I"1The logged timestamp is formatted by method ;TI"-{Time#strftime}[rdoc-ref:Time#strftime] ;TI"using this format string:;T@o;;[I"'%Y-%m-%dT%H:%M:%S.%6N' ;T;0o; ;[I" Example:;T@o;;[I""logger = Logger.new($stdout) ;TI"logger.add(Logger::INFO) ;TI"@# => I, [2022-05-07T17:04:32.318331 #20536] INFO -- : nil ;T;0o; ;[I"CYou can set a different format using method #datetime_format=.;T@S;;i; I"Message;T@o; ;[I"<The message is an optional argument to an entry method:;T@o;;[I""logger = Logger.new($stdout) ;TI",logger.add(Logger::INFO, 'My message') ;TI"G# => I, [2022-05-07T18:15:37.647581 #20536] INFO -- : My message ;T;0o; ;[I"BFor the default entry formatter, <tt>Logger::Formatter</tt>, ;TI"the message object may be:;T@o;;;;[o;;0;[o; ;[I"A string: used as-is.;To;;0;[o; ;[I"4An Exception: <tt>message.message</tt> is used.;To;;0;[o; ;[I"5Anything else: <tt>message.inspect</tt> is used.;T@o; ;[ I";*Note*: Logger::Formatter does not escape or sanitize ;TI"the message passed to it. ;TI"ADevelopers should be aware that malicious data (user input) ;TI"Hmay be in the message, and should explicitly escape untrusted data.;T@o; ;[I"<You can use a custom formatter to escape message data; ;TI"Hsee the example at {formatter=}[Logger.html#attribute-i-formatter].;T@S;;i; I"Program Name;T@o; ;[I"AThe program name is an optional argument to an entry method:;T@o;;[I""logger = Logger.new($stdout) ;TI"4logger.add(Logger::INFO, 'My message', 'mung') ;TI"K# => I, [2022-05-07T18:17:38.084716 #20536] INFO -- mung: My message ;T;0o; ;[I"IThe default program name for a new logger may be set in the call to ;TI"9Logger.new via optional keyword argument +progname+:;T@o;;[I"4logger = Logger.new('t.log', progname: 'mung') ;T;0o; ;[I"@The default program name for an existing logger may be set ;TI"$by a call to method #progname=:;T@o;;[I"logger.progname = 'mung' ;T;0o; ;[I";The current program name may be retrieved with method ;TI"2{progname}[Logger.html#attribute-i-progname]:;T@o;;[I"!logger.progname # => "mung" ;T;0S;;i; I"Log Level;T@o; ;[I"CThe log level setting determines whether an entry is actually ;TI"7written to the log, based on the entry's severity.;T@o; ;[I"DThese are the defined severities (least severe to most severe):;T@o;;[I""logger = Logger.new($stdout) ;TI"9logger.add(Logger::DEBUG, 'Maximal debugging info') ;TI"S# => D, [2022-05-07T17:57:41.776220 #20536] DEBUG -- : Maximal debugging info ;TI"7logger.add(Logger::INFO, 'Non-error information') ;TI"R# => I, [2022-05-07T17:59:14.349167 #20536] INFO -- : Non-error information ;TI"3logger.add(Logger::WARN, 'Non-error warning') ;TI"N# => W, [2022-05-07T18:00:45.337538 #20536] WARN -- : Non-error warning ;TI"2logger.add(Logger::ERROR, 'Non-fatal error') ;TI"L# => E, [2022-05-07T18:02:41.592912 #20536] ERROR -- : Non-fatal error ;TI".logger.add(Logger::FATAL, 'Fatal error') ;TI"H# => F, [2022-05-07T18:05:24.703931 #20536] FATAL -- : Fatal error ;TI"0logger.add(Logger::UNKNOWN, 'Most severe') ;TI"H# => A, [2022-05-07T18:07:54.657491 #20536] ANY -- : Most severe ;T;0o; ;[I"KThe default initial level setting is Logger::DEBUG, the lowest level, ;TI"Lwhich means that all entries are to be written, regardless of severity:;T@o;;[ I""logger = Logger.new($stdout) ;TI"logger.level # => 0 ;TI"!logger.add(0, "My message") ;TI"G# => D, [2022-05-11T15:10:59.773668 #20536] DEBUG -- : My message ;T;0o; ;[I"9You can specify a different setting in a new logger ;TI">using keyword argument +level+ with an appropriate value:;T@o;;[ I"8logger = Logger.new($stdout, level: Logger::ERROR) ;TI"2logger = Logger.new($stdout, level: 'error') ;TI"1logger = Logger.new($stdout, level: :error) ;TI"logger.level # => 3 ;T;0o; ;[I"EWith this level, entries with severity Logger::ERROR and higher ;TI"Dare written, while those with lower severities are not written:;T@o;;[ I"8logger = Logger.new($stdout, level: Logger::ERROR) ;TI"logger.add(3) ;TI"@# => E, [2022-05-11T15:17:20.933362 #20536] ERROR -- : nil ;TI"logger.add(2) # Silent. ;T;0o; ;[I"6You can set the log level for an existing logger ;TI"with method #level=:;T@o;;[I""logger.level = Logger::ERROR ;T;0o; ;[I"0These shorthand methods also set the level:;T@o;;[ I"logger.debug! # => 0 ;TI"logger.info! # => 1 ;TI"logger.warn! # => 2 ;TI"logger.error! # => 3 ;TI"logger.fatal! # => 4 ;T;0o; ;[I"7You can retrieve the log level with method #level.;T@o;;[I""logger.level = Logger::ERROR ;TI"logger.level # => 3 ;T;0o; ;[I"*These methods return whether a given ;TI"level is to be written:;T@o;;[I""logger.level = Logger::ERROR ;TI"logger.debug? # => false ;TI"logger.info? # => false ;TI"logger.warn? # => false ;TI"logger.error? # => true ;TI"logger.fatal? # => true ;T;0S;;i; I"Log File Rotation;T@o; ;[I"EBy default, a log file is a single file that grows indefinitely ;TI":(until explicitly closed); there is no file rotation.;T@o; ;[I"-To keep log files to a manageable size, ;TI"Hyou can use _log_ _file_ _rotation_, which uses multiple log files:;T@o;;;;[o;;0;[o; ;[I"5Each log file has entries for a non-overlapping ;TI"time interval.;To;;0;[o; ;[I"7Only the most recent log file is open and active; ;TI"(the others are closed and inactive.;T@S;;i; I"Size-Based Rotation;T@o; ;[I"<For size-based log file rotation, call Logger.new with:;T@o;;;;[o;;0;[o; ;[I"&Argument +logdev+ as a file path.;To;;0;[o; ;[I"3Argument +shift_age+ with a positive integer: ;TI"3the number of log files to be in the rotation.;To;;0;[o; ;[I"2Argument +shift_size+ as a positive integer: ;TI"3the maximum size (in bytes) of each log file; ;TI"&defaults to 1048576 (1 megabyte).;T@o; ;[I"Examples:;T@o;;[I"Ilogger = Logger.new('t.log', 3) # Three 1-megabyte files. ;TI"Ilogger = Logger.new('t.log', 5, 10485760) # Five 10-megabyte files. ;T;0o; ;[I"!For these examples, suppose:;T@o;;[I"%logger = Logger.new('t.log', 3) ;T;0o; ;[I"2Logging begins in the new log file, +t.log+; ;TI"3the log file is "full" and ready for rotation ;TI"Bwhen a new entry would cause its size to exceed +shift_size+.;T@o; ;[I"$The first time +t.log+ is full:;T@o;;;;[o;;0;[o; ;[I"0+t.log+ is closed and renamed to +t.log.0+.;To;;0;[o; ;[I""A new file +t.log+ is opened.;T@o; ;[I"%The second time +t.log+ is full:;T@o;;;;[o;;0;[o; ;[I"&+t.log.0 is renamed as +t.log.1+.;To;;0;[o; ;[I"0+t.log+ is closed and renamed to +t.log.0+.;To;;0;[o; ;[I""A new file +t.log+ is opened.;T@o; ;[I"0Each subsequent time that +t.log+ is full, ;TI"the log files are rotated:;T@o;;;;[ o;;0;[o; ;[I"+t.log.1+ is removed.;To;;0;[o; ;[I"&+t.log.0 is renamed as +t.log.1+.;To;;0;[o; ;[I"0+t.log+ is closed and renamed to +t.log.0+.;To;;0;[o; ;[I""A new file +t.log+ is opened.;T@S;;i; I"Periodic Rotation;T@o; ;[I"1For periodic rotation, call Logger.new with:;T@o;;;;[o;;0;[o; ;[I"&Argument +logdev+ as a file path.;To;;0;[o; ;[I"7Argument +shift_age+ as a string period indicator.;T@o; ;[I"Examples:;T@o;;[I"Glogger = Logger.new('t.log', 'daily') # Rotate log files daily. ;TI"Hlogger = Logger.new('t.log', 'weekly') # Rotate log files weekly. ;TI"Ilogger = Logger.new('t.log', 'monthly') # Rotate log files monthly. ;T;0o; ;[I" Example:;T@o;;[I"+logger = Logger.new('t.log', 'daily') ;T;0o; ;[I"#When the given period expires:;T@o;;;;[o;;0;[o; ;[I"6The base log file, +t.log+ is closed and renamed ;TI"7with a date-based suffix such as +t.log.20220509+.;To;;0;[o; ;[I"&A new log file +t.log+ is opened.;To;;0;[o; ;[I"Nothing is removed.;T@o; ;[I"=The default format for the suffix is <tt>'%Y%m%d'</tt>, ;TI"7which produces a suffix similar to the one above. ;TI"=You can set a different format using create-time option ;TI"+shift_period_suffix+; ;TI"$see details and suggestions at ;TI"-{Time#strftime}[rdoc-ref:Time#strftime].;T: @fileI"lib/logger.rb;T:0@omit_headings_from_table_of_contents_below0o;;[ ;I"lib/logger/errors.rb;T;0o;;[ ;I"lib/logger/formatter.rb;T;0o;;[ ;I"lib/logger/log_device.rb;T;0o;;[ ;I"lib/logger/period.rb;T;0o;;[ ;I"lib/logger/severity.rb;T;0o;;[ ;I"lib/logger/version.rb;T;0;0;0[[ I"formatter;TI"RW;T:publicFI"lib/logger.rb;T[ I" progname;T@p;F@q[U:RDoc::Constant[i I" ProgName;TI"Logger::ProgName;T;0o;;[ ;@Z;0@Z@cRDoc::NormalClass0U;[i I"SEV_LABEL;TI"Logger::SEV_LABEL;T;0o;;[o; ;[I"/\Severity label for logging (max 5 chars).;T;@Z;0@Z@@{0U;[i I"VERSION;TI"Logger::VERSION;T;0o;;[ ;@l;0@l@@{0[[I" Severity;To;;[ ;@Z;0@q[[I" class;T[[;[[I"new;T@q[:protected[ [:private[ [I" instance;T[[;[![I"<<;T@q[I"add;T@q[I" close;T@q[I"datetime_format;T@q[I"datetime_format=;T@q[I" debug;T@q[I"debug!;T@q[I"debug?;T@q[I" error;T@q[I"error!;T@q[I"error?;T@q[I" fatal;T@q[I"fatal!;T@q[I"fatal?;T@q[I" info;T@q[I" info!;T@q[I" info?;T@q[I" level;T@q[I"level=;T@q[I"log;T@q[I"reopen;T@q[I"sev_threshold;T@q[I"sev_threshold=;T@q[I"unknown;T@q[I" warn;T@q[I" warn!;T@q[I" warn?;T@q[I"with_level;T@q[;[ [;[ [I"format_message;T@q[I"format_severity;T@q[I"level_key;T@q[I"level_override;T@q[ [U:RDoc::Context::Section[i 0o;;[ ;0;0[@Z@]@`@c@f@i@l@lcRDoc::TopLevel