log4r 1.0.6

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