log4r 1.0.6

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.
Files changed (74) hide show
  1. data/doc/content/contact.html +22 -0
  2. data/doc/content/contribute.html +21 -0
  3. data/doc/content/index.html +90 -0
  4. data/doc/content/license.html +56 -0
  5. data/doc/content/manual.html +449 -0
  6. data/doc/dev/README.developers +55 -0
  7. data/doc/dev/checklist +23 -0
  8. data/doc/dev/things-to-do +5 -0
  9. data/doc/images/log4r-logo.png +0 -0
  10. data/doc/images/logo2.png +0 -0
  11. data/doc/log4r.css +111 -0
  12. data/doc/templates/main.html +147 -0
  13. data/examples/README +19 -0
  14. data/examples/customlevels.rb +34 -0
  15. data/examples/fileroll.rb +40 -0
  16. data/examples/log4r_yaml.yaml +0 -0
  17. data/examples/logclient.rb +25 -0
  18. data/examples/logserver.rb +18 -0
  19. data/examples/moderate.xml +29 -0
  20. data/examples/moderateconfig.rb +66 -0
  21. data/examples/myformatter.rb +23 -0
  22. data/examples/outofthebox.rb +21 -0
  23. data/examples/rrconfig.xml +63 -0
  24. data/examples/rrsetup.rb +42 -0
  25. data/examples/simpleconfig.rb +39 -0
  26. data/examples/xmlconfig.rb +25 -0
  27. data/examples/yaml.rb +30 -0
  28. data/src/log4r.rb +17 -0
  29. data/src/log4r/base.rb +74 -0
  30. data/src/log4r/config.rb +9 -0
  31. data/src/log4r/configurator.rb +224 -0
  32. data/src/log4r/formatter/formatter.rb +105 -0
  33. data/src/log4r/formatter/patternformatter.rb +107 -0
  34. data/src/log4r/lib/drbloader.rb +52 -0
  35. data/src/log4r/lib/xmlloader.rb +24 -0
  36. data/src/log4r/logevent.rb +28 -0
  37. data/src/log4r/logger.rb +194 -0
  38. data/src/log4r/loggerfactory.rb +89 -0
  39. data/src/log4r/logserver.rb +28 -0
  40. data/src/log4r/outputter/consoleoutputters.rb +18 -0
  41. data/src/log4r/outputter/datefileoutputter.rb +110 -0
  42. data/src/log4r/outputter/emailoutputter.rb +116 -0
  43. data/src/log4r/outputter/fileoutputter.rb +49 -0
  44. data/src/log4r/outputter/iooutputter.rb +55 -0
  45. data/src/log4r/outputter/outputter.rb +132 -0
  46. data/src/log4r/outputter/outputterfactory.rb +59 -0
  47. data/src/log4r/outputter/remoteoutputter.rb +40 -0
  48. data/src/log4r/outputter/rollingfileoutputter.rb +126 -0
  49. data/src/log4r/outputter/staticoutputter.rb +30 -0
  50. data/src/log4r/outputter/syslogoutputter.rb +75 -0
  51. data/src/log4r/rdoc/configurator +243 -0
  52. data/src/log4r/rdoc/emailoutputter +103 -0
  53. data/src/log4r/rdoc/formatter +39 -0
  54. data/src/log4r/rdoc/log4r +89 -0
  55. data/src/log4r/rdoc/logger +175 -0
  56. data/src/log4r/rdoc/logserver +85 -0
  57. data/src/log4r/rdoc/outputter +108 -0
  58. data/src/log4r/rdoc/patternformatter +128 -0
  59. data/src/log4r/rdoc/syslogoutputter +29 -0
  60. data/src/log4r/rdoc/yamlconfigurator +20 -0
  61. data/src/log4r/repository.rb +65 -0
  62. data/src/log4r/staticlogger.rb +49 -0
  63. data/src/log4r/yamlconfigurator.rb +0 -0
  64. data/tests/README +10 -0
  65. data/tests/testall.rb +6 -0
  66. data/tests/testbase.rb +49 -0
  67. data/tests/testconf.xml +37 -0
  68. data/tests/testcustom.rb +27 -0
  69. data/tests/testformatter.rb +27 -0
  70. data/tests/testlogger.rb +196 -0
  71. data/tests/testoutputter.rb +111 -0
  72. data/tests/testpatternformatter.rb +21 -0
  73. data/tests/testxmlconf.rb +45 -0
  74. metadata +127 -0
@@ -0,0 +1,108 @@
1
+ = Outputters
2
+
3
+ An Outputter is a logging destination with a particular way to format
4
+ data. It has a level threshold and a flexible level mask.
5
+
6
+ Outputters must have names.
7
+
8
+ == Level Threshold
9
+
10
+ Outputters have their own level thresholds that default to <tt>root</tt>
11
+ level. They will not write any log events with a rank less than their
12
+ threshold.
13
+
14
+ == Level Mask
15
+
16
+ Alternatively, an Outputter can be told to log specific levels only:
17
+
18
+ o = StdoutOutputter.new 'console'
19
+ o.only_at DEBUG, FATAL # only DEBUG and FATAL get written
20
+
21
+ == Outputter Repository
22
+
23
+ When outputters are created, they store themselves in an Outputter
24
+ repository similar to the Logger repository.
25
+
26
+ StdoutOutputter.new 'console' => Create 'console' outputter
27
+ Outputter['console'] => Get it back from the stash.
28
+
29
+ == Formatter
30
+
31
+ An outputter has a format defined by its Formatter. If no Formatter
32
+ is specified, DefaultFormatter will be used.
33
+
34
+ == Outputter is Abstract
35
+
36
+ The basic Outputter class is both abstract and a null object.
37
+
38
+ == Interesting Outputters
39
+
40
+ * log4r/outputter/syslogoutputter.rb - Logs to syslog
41
+ * log4r/outputter/emailoutputter.rb - Email logs
42
+ * log4r/logserver.rb - For remote logging
43
+
44
+ == Subclasses
45
+
46
+ * Log4r::IOOutputter - for any IO object
47
+ * Log4r::StdoutOutputter - $stdout
48
+ * Log4r::StderrOutputter - $stderr
49
+ * Log4r::FileOutputter - log to a file
50
+ * Log4r::RollingFileOutputter - log to a file and split it as it grows
51
+ * Log4r::SyslogOutputter - logs to syslog
52
+ * Log4r::EmailOutputter - email logs
53
+ * Log4r::RemoteOutputter - for remote logging
54
+
55
+ == Default Outputters
56
+
57
+ Two outputters named 'stdout' and 'stderr' are created automatically at
58
+ the root level. They are nice shortcuts.
59
+
60
+ Outputter['stdout'] => 'stdout'
61
+ Outputter['stderr'] => 'stderr'
62
+ Outputter.stdout => 'stdout'
63
+ Outputter.stderr => 'stderr'
64
+
65
+ == Configuring
66
+
67
+ Outputters must have names and receive hash arguments. The parameter name
68
+ for the hash args can be either a symbol or a string. All defined outputters
69
+ accept <tt>:level</tt> and <tt>:formatter</tt> arguments. For arguments
70
+ specific to a convenience Outputter, please look at the class description.
71
+
72
+ The level threshold, the levels to log at (only_at) and formatter can be
73
+ changed dynamically using the <tt>=</tt> methods.
74
+
75
+ As a collective example of all this, here are various ways to set up an
76
+ IOOutputter:
77
+
78
+ IOOutputter.new ExoticIO.new 'exotic', 'level' => WARN,
79
+ :formatter => MyFormatter.new
80
+ # an equivalent way:
81
+ o = IOOutputter.new ExoticIO.new 'exotic'
82
+ o.level = WARN
83
+ o.formatter = MyFormatter # we can specify just the class
84
+ o.only_at = THIS, THAT
85
+
86
+ == XML Configuration
87
+
88
+ Specify outputters as children of <tt><log4r_config></tt>:
89
+
90
+ <log4r_config>
91
+ <outputter name="myout" type="Log4r::StdoutOutputter">
92
+ <only_at>DEBUG, INFO</only_at>
93
+ </outputter>
94
+ <outputter name="file" level="WARN">
95
+ <type>FileOutputter</type>
96
+ <filename>#{logpath}/file.log</filename>
97
+ <trunc>false</trunc>
98
+ </outputter>
99
+ ...
100
+
101
+ As explained in log4r/configurator.rb, the hash arguments you would normally
102
+ pass to <tt>new</tt> are specified as <i>XML parameters</i>.
103
+ It is given an IO object to write
104
+ to, a Formatter to call, and, optionally, levels to write at.
105
+
106
+ Outputters invoke print then flush on the wrapped IO object.
107
+ If the IO chokes, the Outputter will close the IO and set its
108
+ level to <tt>OFF</tt>.
@@ -0,0 +1,128 @@
1
+ = PatternFormatter
2
+
3
+ PatternFormatter offers complete control over the appearance of
4
+ Log4r log events without having to write custom Formatter classes.
5
+ In order to take advantage of PatternFormatter, some familarity with
6
+ Kernel#sprintf or the C printf function is recommended. For time formatting,
7
+ please look at Time.strftime.
8
+
9
+ PatternFormatter accepts three hash arguments:
10
+
11
+ <tt>pattern</tt>:: Log event format string.
12
+ <tt>date_pattern</tt>:: Date format string.
13
+ <tt>date_method</tt>:: <tt>Time</tt> method to call (instead of using date_pattern).
14
+
15
+
16
+ The <tt>pattern</tt> format string is something like "%l [%d] %80M",
17
+ which resembles a pattern one would normally pass to Kernel#sprintf. However,
18
+ the directives are specific to Log4r. Before we go on, let's cover some
19
+ terminology.
20
+
21
+ == Terminology
22
+
23
+ [<b>%</b>] The directive identifier. Everything after this up to and
24
+ including one of the <em>directive letters</em> defines a
25
+ <em>directive</em>.
26
+ [<b>directive letter</b>]
27
+ Letters in the set <tt>[cCdtmMl%]</tt>. These
28
+ identify what kind of data we're interested in.
29
+ They are detailed below.
30
+ [<b>format directive</b>]
31
+ The numbers and assorted symbols that appears
32
+ between <b>%</b> and a <em>directive letter</em>
33
+ is a format directive. It is comprised of an
34
+ integer specifying the field width followed
35
+ optionally by a period and an integer specifying
36
+ the precision. The field width is the minimum
37
+ number of characters to copy from the data string
38
+ while the precision is the maximum number to copy.
39
+ If the field width is preceded by a - sign, the
40
+ data will be left-justified. Otherwise, it is
41
+ right-justified.
42
+ [<b>directive</b>]
43
+ A statement that says, "I want this data to appear with
44
+ this (optional) particular format." A directive starts
45
+ with a <b>%</b> and is followed by a format directive and
46
+ terminates in a directive letter.
47
+
48
+ == What the Directive Letters mean
49
+
50
+ [<b>c</b>] Produces a logger's name. Fast.
51
+ [<b>C</b>] Produces a logger's full name. Fast.
52
+ [<b>d</b>] Produces the time in a format specified by <b>date_pattern</b> or
53
+ by <b>date_method</b>. If neither is specified, the default will
54
+ be used (ISO8601). Slow.
55
+ [<b>t</b>] Produces the file and line number of the log event. The
56
+ appearance varies by Ruby version, but it is the same output
57
+ returned by Kernel#caller[0]. Slow.
58
+ [<b>m</b>] The non-inspected log message. That is, to_s called on the object
59
+ passed into a log method. Fast.
60
+ [<b>M</b>] The message formatted by the <tt>format_object</tt> method in
61
+ BasicFormatter. It will pretty-print Exceptions, print Strings
62
+ and inspect everything else. Slow.
63
+ [<b>l</b>] The name of the level. That's l as in Lambda. Fast.
64
+ [<b>%</b>] %% just prints a %. Any formatting is <em>probably</em> ignored.
65
+ Fast.
66
+
67
+ == Examples of directives:
68
+
69
+
70
+ [<b>%d</b>] Prints out the date according to our date_pattern or
71
+ date_method. By default, it looks like this: 2001-01-12 13:15:50
72
+ [<b>%.120m</b>] Prints out at most 120 characters of the log message.
73
+ [<b>%15t</b>] Prints the execution trace and pads it on the left with
74
+ enough whitespace to make the whole thing 15 chars.
75
+
76
+ == Pattern String
77
+
78
+ A pattern string is simply a bunch of directives combined with the desired
79
+ format. For instance, to show the level in brackets followed by the date
80
+ and then the log message trimmed to 15 characters, we use the following
81
+ pattern:
82
+
83
+ "[%l] %d :: %.15m" #=> [DEBUG] 2001-01-12 13:15:50 :: This is a messa
84
+
85
+ To create a PatternFormatter with this format:
86
+
87
+ p = PatternFormatter.new(:pattern => "[%l] %d :: %.15m")
88
+
89
+ == Formatting time
90
+
91
+ To format time, do one of the following:
92
+
93
+ * Specify a date_pattern
94
+ * Specify what class method of Ruby's <tt>Time</tt> class to call.
95
+ * Use the default format
96
+
97
+ If neither date_pattern nor date_method is specified, the default date
98
+ format will be used. Currently, that would be ISO8601,
99
+
100
+ The date_pattern is exactly what one would pass to <tt>Time.strftime</tt>.
101
+ To specify a date_pattern, pass
102
+ <tt>:date_pattern=>"pattern"</tt> to PatternFormat.new.
103
+
104
+ Alternatively, date_method can be specified to produce the output of
105
+ a specific <tt>Time</tt> method, such as <tt>usec</tt> or <tt>to_s</tt>
106
+ or any other zero argument <tt>Time</tt> method that produces a time. More
107
+ precisely, the method to call will be invoked on <tt>Time.now</tt>.
108
+ To specify a date_method, pass <tt>:date_method=>'methodname'</tt> (or a
109
+ Symbol equivalent) to <tt>PatternFormatter.new</tt>.
110
+
111
+ = XML Configuration
112
+
113
+ As explained in log4r/configurator.rb, the hash arguments to PatternFormatter
114
+ are <i>XML parameters</i>. Here's an example:
115
+
116
+ <formatter type="PatternFormatter" pattern="[%l] %d :: %.15m">
117
+ <date_method>usec</date_method>
118
+ </formatter>
119
+
120
+ = Performace considerations
121
+
122
+ The performance impact of using a particular directive letter is noted in
123
+ the <b>What the Directives Letters mean</b> section.
124
+
125
+ The performance impact of time formatting merits special attention. If you
126
+ aren't aware yet, the Time class is kind of a kludge. Time.now.usec happens
127
+ to be faster than Time.now. If you're concerned about performance, please
128
+ profile the various time methods and patterns.
@@ -0,0 +1,29 @@
1
+ = SyslogOutputter
2
+
3
+ A SyslogOutputter transforms a Log4r::LogEvent into a call to syslog().
4
+ Since syslog has its own formatting system, log4r formatters are ignored.
5
+
6
+ == Usage
7
+
8
+ To use,
9
+
10
+ <tt>require 'log4r/outputter/syslogoutputter'</tt>
11
+
12
+ An example,
13
+
14
+ require 'log4r'
15
+ require 'log4r/outputter/syslogoutputter'
16
+
17
+ syslog = Log4r::SyslogOutputter.new("name", 'logopt'=>#, 'facility'=>#)
18
+ syslog.err("this is an ERR message")
19
+
20
+ The output in <tt>/var/logs/syslog</tt> (Debian) is,
21
+
22
+ Sep 3 11:43:06 tiphares sys[1603]: this is an ERR message
23
+
24
+ The hash arguments +logoptions+ and +facility+ are passed to
25
+ <tt>Syslog.open</tt>. The
26
+ defaults are <tt>LOG_PID | LOG_CONS</tt> and <tt>LOG_USER</tt> respectively.
27
+
28
+ This is a first try implementation. It works well. Please report
29
+ any bugs and fixes.
@@ -0,0 +1,20 @@
1
+ = Configuring Log4r with Log4r::YamlConfigurator
2
+
3
+ The YamlConfigurator class allows one to set up Log4r via YAML.
4
+ It is used almost exactly as Log4r::Configurator and has the same features,
5
+
6
+ ycfg = YamlConfigurator # handy shorthand
7
+ ycfg['foo'] = bar # replaces instances of #{foo} in the YAML with bar
8
+ ycfg.load_yaml_file('foo.yaml')
9
+
10
+ Ruby 1.7 and 1.8 comes with a YAML parser. Hence, YAML can be used
11
+ to configure Log4r out of the box.
12
+
13
+ A comprehensive example of a Log4r YAML configuration is provided in the
14
+ examples directory.
15
+
16
+ To use this class:
17
+
18
+ require 'log4r/yamlconfigurator'
19
+
20
+ Thanks to Andreas Hund for making this possible.
@@ -0,0 +1,65 @@
1
+ # :nodoc:
2
+ # Version:: $Id: repository.rb,v 1.1.1.1 2004/03/19 03:31:07 fando Exp $
3
+
4
+ require "singleton"
5
+
6
+ module Log4r
7
+ class Logger
8
+
9
+ # The repository stores a Hash of loggers keyed to their fullnames and
10
+ # provides a few functions to reduce the code bloat in log4r/logger.rb.
11
+ # This class is supposed to be transparent to end users, hence it is
12
+ # a class within Logger. If anyone knows how to make this private,
13
+ # let me know.
14
+
15
+ class Repository # :nodoc:
16
+ include Singleton
17
+ attr_reader :loggers
18
+
19
+ def initialize
20
+ @loggers = Hash.new
21
+ end
22
+
23
+ def self.[](fullname)
24
+ instance.loggers[fullname]
25
+ end
26
+
27
+ def self.[]=(fullname, logger)
28
+ instance.loggers[fullname] = logger
29
+ end
30
+
31
+ # Retrieves all children of a parent
32
+ def self.all_children(parent)
33
+ # children have the parent name + delimiter in their fullname
34
+ daddy = parent.name + Private::Config::LoggerPathDelimiter
35
+ for fullname, logger in instance.loggers
36
+ yield logger if parent.is_root? || fullname =~ /#{daddy}/
37
+ end
38
+ end
39
+
40
+ # when new loggers are introduced, they may get inserted into
41
+ # an existing inheritance tree. this method
42
+ # updates the children of a logger to link their new parent
43
+ def self.reassign_any_children(parent)
44
+ for fullname, logger in instance.loggers
45
+ next if logger.is_root?
46
+ logger.parent = parent if logger.path =~ /^#{parent.fullname}$/
47
+ end
48
+ end
49
+
50
+ # looks for the first defined logger in a child's path
51
+ # or nil if none found (which will then be rootlogger)
52
+ def self.find_ancestor(path)
53
+ arr = path.split Log4rConfig::LoggerPathDelimiter
54
+ logger = nil
55
+ while arr.size > 0 do
56
+ logger = Repository[arr.join(Log4rConfig::LoggerPathDelimiter)]
57
+ break unless logger.nil?
58
+ arr.pop
59
+ end
60
+ logger
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,49 @@
1
+ # :nodoc:
2
+ module Log4r
3
+ class Logger
4
+ # Returns the root logger. Identical to Logger.global
5
+ def self.root; return RootLogger.instance end
6
+ # Returns the root logger. Identical to Logger.root
7
+ def self.global; return root end
8
+
9
+ # Get a logger with a fullname from the repository or nil if logger
10
+ # wasn't found.
11
+
12
+ def self.[](_fullname)
13
+ # forces creation of RootLogger if it doesn't exist yet.
14
+ return RootLogger.instance if _fullname=='root' or _fullname=='global'
15
+ Repository[_fullname]
16
+ end
17
+
18
+ # Like Logger[] except that it raises NameError if Logger wasn't found.
19
+
20
+ def self.get(_fullname)
21
+ logger = self[_fullname]
22
+ if logger.nil?
23
+ raise NameError, "Logger '#{_fullname}' not found.", caller
24
+ end
25
+ logger
26
+ end
27
+
28
+ # Yields fullname and logger for every logger in the system.
29
+ def self.each
30
+ for fullname, logger in Repository.instance.loggers
31
+ yield fullname, logger
32
+ end
33
+ end
34
+
35
+ def self.each_logger
36
+ Repository.instance.loggers.each_value {|logger| yield logger}
37
+ end
38
+
39
+ # Internal logging for Log4r components. Accepts only blocks.
40
+ # To see such log events, create a logger named 'log4r' and give
41
+ # it an outputter.
42
+
43
+ def self.log_internal(level=1)
44
+ internal = Logger['log4r']
45
+ return if internal.nil?
46
+ internal.send(LNAMES[level].downcase, yield)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,10 @@
1
+ The unit tests are currently out of date. The examples actually provide
2
+ a decent test suite for log4r. But the unit tests are still very important
3
+ because of bounds-checking and a quicker turnaround for bug discovery.
4
+ The unit files need to be converted to the new 'test/unit' paradigm.
5
+
6
+ Because Log4r dynamically defines constants according to user preferences,
7
+ the unit testing can't all be done in one instance of ruby. It is planned
8
+ to use popen to run each test that needs a clean ruby instance.
9
+
10
+ The logs/ directory is where these tests dump generated log files.
@@ -0,0 +1,6 @@
1
+ $: << File.join("..", "src")
2
+
3
+ # because constants are dynamically defined, some tests need to
4
+ # be opened in a fresh instance of Ruby, hence the popens
5
+
6
+ IO.popen("date") { |f| puts f.gets }
@@ -0,0 +1,49 @@
1
+ $: << File.join("..","src")
2
+ require "test/unit"
3
+ require "log4r"
4
+ include Log4r
5
+
6
+ class TestBase < Test::Unit::TestCase
7
+ # check that LNAMES loads properly (it uses an eval to load)
8
+ def test_default_levels
9
+ Logger.root # doing this loads the default levels
10
+ assert_equal(ALL,0)
11
+ assert_equal(DEBUG,1)
12
+ assert_equal(INFO,2)
13
+ assert_equal(WARN,3)
14
+ assert_equal(ERROR,4)
15
+ assert_equal(FATAL,5)
16
+ assert_equal(OFF,6)
17
+ assert_equal(LEVELS, 7)
18
+ assert_equal(LNAMES.size, 7)
19
+ end
20
+ # check bad input and bounds for validate_level
21
+ def test_validate_level
22
+ 7.times{|i| assert_nothing_raised {Log4rTools.validate_level(i)} }
23
+ assert_raises(ArgumentError) {Log4rTools.validate_level(-1)}
24
+ assert_raises(ArgumentError) {Log4rTools.validate_level(LEVELS)}
25
+ assert_raises(ArgumentError) {Log4rTools.validate_level(String)}
26
+ assert_raises(ArgumentError) {Log4rTools.validate_level("bogus")}
27
+ end
28
+ # decode_bool turns a string 'true' into true and so on
29
+ def test_decode_bool
30
+ # when the key is a symbol :data
31
+ assert(Log4rTools.decode_bool({:data=> 'true'} ,:data,false) == true)
32
+ assert(Log4rTools.decode_bool({:data=> true} ,:data,false) == true)
33
+ assert(Log4rTools.decode_bool({:data=> 'false'} ,:data,true) == false)
34
+ assert(Log4rTools.decode_bool({:data=> false} ,:data,true) == false)
35
+ assert(Log4rTools.decode_bool({:data=> nil} ,:data,true) == true)
36
+ assert(Log4rTools.decode_bool({:data=> nil} ,:data,false) == false)
37
+ assert(Log4rTools.decode_bool({:data=> String} ,:data,true) == true)
38
+ assert(Log4rTools.decode_bool({:data=> String} ,:data,false) == false)
39
+ # now the key is a string 'data'
40
+ assert(Log4rTools.decode_bool({'data'=> 'true'} ,:data,false) == true)
41
+ assert(Log4rTools.decode_bool({'data'=> true} ,:data,false) == true)
42
+ assert(Log4rTools.decode_bool({'data'=> 'false'} ,:data,true) == false)
43
+ assert(Log4rTools.decode_bool({'data'=> false} ,:data,true) == false)
44
+ assert(Log4rTools.decode_bool({'data'=> nil} ,:data,true) == true)
45
+ assert(Log4rTools.decode_bool({'data'=> nil} ,:data,false) == false)
46
+ assert(Log4rTools.decode_bool({'data'=> String} ,:data,true) == true)
47
+ assert(Log4rTools.decode_bool({'data'=> String} ,:data,false) == false)
48
+ end
49
+ end