Permalink
Browse files

Improve and expand Logger's rdoc

This patch has some cleanups and rewording of Logger's fairly excellent RDoc.
Mostly just making all method doc consistent and complete and adding a few things for clarity.

Patch is made by Dave Copeland <davetron5000@gmail.com>
Signed off by Hiroshi Nakamura <nahi@ruby-lang.org>

http://redmine.ruby-lang.org/issues/4706
  • Loading branch information...
1 parent 6cea910 commit 1ee2e673fafbf6fe742b5e76e5eb55fb01ca4d41 @nahi committed May 16, 2011
Showing with 78 additions and 43 deletions.
  1. +78 −43 lib/logger.rb
View
@@ -7,7 +7,7 @@
# license; either the dual license version in 2003, or any later version.
# Revision:: $Id$
#
-# See Logger for documentation.
+# A simple system for logging messages. See Logger for more documentation.
require 'monitor'
@@ -16,38 +16,35 @@
# == Description
#
# The Logger class provides a simple but sophisticated logging utility that
-# anyone can use because it's included in the Ruby 1.8.x standard library.
+# you can use to output messages.
#
-# The HOWTOs below give a code-based overview of Logger's usage, but the basic
-# concept is as follows. You create a Logger object (output to a file or
-# elsewhere), and use it to log messages. The messages will have varying
-# levels (+info+, +error+, etc), reflecting their varying importance. The
-# levels, and their meanings, are:
+# The messages have associated
+# levels, such as +INFO+ or +ERROR+ that indicate their importance.
+# You can then give the Logger a level, and only messages at that
+# level of higher will be printed.
+#
+# The levels are:
#
# +FATAL+:: an unhandleable error that results in a program crash
# +ERROR+:: a handleable error condition
# +WARN+:: a warning
# +INFO+:: generic (useful) information about system operation
# +DEBUG+:: low-level information for developers
#
-# So each message has a level, and the Logger itself has a level, which acts
-# as a filter, so you can control the amount of information emitted from the
-# logger without having to remove actual messages.
-#
-# For instance, in a production system, you may have your logger(s) set to
-# +INFO+ (or +WARN+ if you don't want the log files growing large with
-# repetitive information). When you are developing it, though, you probably
-# want to know about the program's internal state, and would set them to
+# For instance, in a production system, you may have your Logger set to
+# +INFO+ or even +WARN+
+# When you are developing the system, however, you probably
+# want to know about the program's internal state, and would set the Logger to
# +DEBUG+.
#
-# **Note**: Logger does not escape or sanitize any messages passed to it.
+# *Note*: Logger does not escape or sanitize any messages passed to it.
# Developers should be aware of when potentially malicious data (user-input)
# is passed to Logger, and manually escape the untrusted data:
#
# logger.info("User-input: #{input.dump}")
# logger.info("User-input: %p" % input)
#
-# You can use Logger#formatter= for escaping all data.
+# You can use #formatter= for escaping all data.
#
# original_formatter = Logger::Formatter.new
# logger.formatter = proc { |severity, datetime, progname, msg|
@@ -57,7 +54,7 @@
#
# === Example
#
-# A simple example demonstrates the above explanation:
+# This creates a logger to the standard output stream, with a level of +WARN+
#
# log = Logger.new(STDOUT)
# log.level = Logger::WARN
@@ -126,7 +123,7 @@
# === How to log a message
#
# Notice the different methods (+fatal+, +error+, +info+) being used to log
-# messages of various levels. Other methods in this family are +warn+ and
+# messages of various levels? Other methods in this family are +warn+ and
# +debug+. +add+ is used below to log a message of an arbitrary (perhaps
# dynamic) level.
#
@@ -145,6 +142,20 @@
# 4. With severity.
#
# logger.add(Logger::FATAL) { 'Fatal error!' }
+#
+# The block form allows you to create potentially complex log messages,
+# but to delay their evaluation until and unless the message is
+# logged. For example, if we have the following:
+#
+# logger.debug { "This is a " + potentially + " expensive operation" }
+#
+# If the logger's level is +INFO+ or higher, no debug messages will be logged,
+# and the entire block will not even be evaluated. Compare to this:
+#
+# logger.debug("This is a " + potentially + " expensive operation")
+#
+# Here, the string concatenation is done every time, even if the log
+# level is not set to show the debug message.
#
# === How to close a logger
#
@@ -174,60 +185,73 @@
# Log sample:
# I, [Wed Mar 03 02:34:24 JST 1999 895701 #19074] INFO -- Main: info.
#
-# You may change the date and time format in this manner:
+# You may change the date and time format via #datetime_format=
#
# logger.datetime_format = "%Y-%m-%d %H:%M:%S"
# # e.g. "2004-01-03 00:54:26"
#
-# You may change the overall format with Logger#formatter= method.
+# Or, you may change the overall format with #formatter= method.
#
-# logger.formatter = proc { |severity, datetime, progname, msg|
+# logger.formatter = proc do |severity, datetime, progname, msg|
# "#{datetime}: #{msg}\n"
-# }
-# # e.g. "Thu Sep 22 08:51:08 GMT+9:00 2005: hello world"
+# end
+# # e.g. "Thu Sep 22 08:51:08 GMT+9:00 2005: hello world"
#
-
-
class Logger
VERSION = "1.2.8"
ProgName = "#{File.basename(__FILE__)}/#{VERSION}"
- class Error < RuntimeError; end
- class ShiftingError < Error; end # not used after 1.2.7. just for compat.
+ class Error < RuntimeError # :nodoc:
+ end
+ # not used after 1.2.7. just for compat.
+ class ShiftingError < Error # :nodoc:
+ end
# Logging severity.
module Severity
+ # Low-level information, mostly for developers
DEBUG = 0
+ # generic, useful information about system operation
INFO = 1
+ # a warning
WARN = 2
+ # a handleable error condition
ERROR = 3
+ # an unhandleable error that results in a program crash
FATAL = 4
+ # an unknown message that should always be logged
UNKNOWN = 5
end
include Severity
# Logging severity threshold (e.g. <tt>Logger::INFO</tt>).
attr_accessor :level
- # Logging program name.
+ # program name to include in log messages.
attr_accessor :progname
- # Logging date-time format (string passed to +strftime+).
+ # Set date-time format.
+ #
+ # +datetime_format+:: A string suitable for passing to +strftime+.
def datetime_format=(datetime_format)
@default_formatter.datetime_format = datetime_format
end
- # Returns the date format (string passed to +strftime+) being used (it's set
- # using datetime_format=)
+ # Returns the date format being used. See #datetime_format=
def datetime_format
@default_formatter.datetime_format
end
- # Logging formatter. formatter#call is invoked with 4 arguments; severity,
- # time, progname and msg for each log. Bear in mind that time is a Time and
- # msg is an Object that user passed and it could not be a String. It is
- # expected to return a logdev#write-able Object. Default formatter is used
- # when no formatter is set.
+ # Logging formatter, as a +Proc+ that will take four arguments and
+ # return the formatted message. The arguments are:
+ #
+ # +severity+:: The Severity of the log message
+ # +time+:: A Time instance representing when the message was logged
+ # +progname+:: The #progname configured, or passed to the logger method
+ # +msg+:: The _Object_ the user passed to the log message; not necessarily a String.
+ #
+ # The block should return an Object that can be written to the logging device via +write+. The
+ # default formatter is used when no formatter is set.
attr_accessor :formatter
alias sev_threshold level
@@ -328,7 +352,7 @@ def initialize(logdev, shift_age = 0, shift_size = 1048576)
#
# * Logfile is not locked.
# * Append open does not need to lock file.
- # * But on the OS which supports multi I/O, records possibly be mixed.
+ # * If the OS which supports multi I/O, records possibly be mixed.
#
def add(severity, message = nil, progname = nil, &block)
severity ||= UNKNOWN
@@ -370,11 +394,20 @@ def debug(progname = nil, &block)
end
#
+ # :call-seq:
+ # info(message)
+ # info(progname,&block)
+ #
# Log an +INFO+ message.
#
- # The message can come either from the +progname+ argument or the +block+. If
- # both are provided, then the +block+ is used as the message, and +progname+
- # is used as the program name.
+ # +message+:: the message to log; does not need to be a String
+ # +progname+:: in the block form, this is the #progname to use in the
+ # the log message. The default can be set with #progname=
+ # <tt>&block</tt>:: evaluates to the message to log. This is not evaluated
+ # unless the logger's level is sufficient
+ # to log the message. This allows you to create
+ # potentially expensive logging messages that are
+ # only called when the logger is configured to show them.
#
# === Examples
#
@@ -385,7 +418,7 @@ def debug(progname = nil, &block)
# logger.info { "User typed #{input}" }
#
# You'll probably stick to the second form above, unless you want to provide a
- # program name (which you can do with <tt>Logger#progname=</tt> as well).
+ # program name (which you can do with #progname= as well).
#
# === Return
#
@@ -423,7 +456,7 @@ def fatal(progname = nil, &block)
end
#
- # Log an +UNKNOWN+ message. This will be printed no matter what the logger
+ # Log an +UNKNOWN+ message. This will be printed no matter what the logger's
# level.
#
# See #info for more information.
@@ -453,6 +486,7 @@ def format_message(severity, datetime, progname, msg)
end
+ # Default formatter for log messages
class Formatter
Format = "%s, [%s#%d] %5s -- %s: %s\n"
@@ -491,6 +525,7 @@ def msg2str(msg)
end
+ # Device used for logging messages.
class LogDevice
attr_reader :dev
attr_reader :filename

0 comments on commit 1ee2e67

Please sign in to comment.