path-log4r 1.1.10

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 (104) hide show
  1. data/INSTALL +11 -0
  2. data/LICENSE +90 -0
  3. data/LICENSE.LGPLv3 +165 -0
  4. data/README +95 -0
  5. data/Rakefile +74 -0
  6. data/TODO +2 -0
  7. data/doc/content/contact.html +22 -0
  8. data/doc/content/contribute.html +21 -0
  9. data/doc/content/index.html +90 -0
  10. data/doc/content/license.html +56 -0
  11. data/doc/content/manual.html +449 -0
  12. data/doc/dev/README.developers +55 -0
  13. data/doc/dev/checklist +23 -0
  14. data/doc/dev/things-to-do +5 -0
  15. data/doc/images/log4r-logo.png +0 -0
  16. data/doc/images/logo2.png +0 -0
  17. data/doc/log4r.css +111 -0
  18. data/doc/rdoc-log4r.css +696 -0
  19. data/doc/templates/main.html +147 -0
  20. data/examples/README +19 -0
  21. data/examples/ancestors.rb +53 -0
  22. data/examples/chainsaw_settings.xml +7 -0
  23. data/examples/customlevels.rb +34 -0
  24. data/examples/filelog.rb +25 -0
  25. data/examples/fileroll.rb +40 -0
  26. data/examples/gmail.rb +30 -0
  27. data/examples/gmail.yaml +95 -0
  28. data/examples/log4r_yaml.yaml +0 -0
  29. data/examples/logclient.rb +25 -0
  30. data/examples/logserver.rb +18 -0
  31. data/examples/moderate.xml +29 -0
  32. data/examples/moderateconfig.rb +66 -0
  33. data/examples/myformatter.rb +23 -0
  34. data/examples/outofthebox.rb +21 -0
  35. data/examples/rdoc-gen +2 -0
  36. data/examples/rrconfig.xml +63 -0
  37. data/examples/rrsetup.rb +42 -0
  38. data/examples/simpleconfig.rb +39 -0
  39. data/examples/syslogcustom.rb +52 -0
  40. data/examples/xmlconfig.rb +25 -0
  41. data/examples/yaml.rb +30 -0
  42. data/lib/log4r.rb +20 -0
  43. data/lib/log4r/GDC.rb +41 -0
  44. data/lib/log4r/MDC.rb +59 -0
  45. data/lib/log4r/NDC.rb +86 -0
  46. data/lib/log4r/base.rb +74 -0
  47. data/lib/log4r/config.rb +9 -0
  48. data/lib/log4r/configurator.rb +224 -0
  49. data/lib/log4r/formatter/formatter.rb +105 -0
  50. data/lib/log4r/formatter/log4jxmlformatter.rb +61 -0
  51. data/lib/log4r/formatter/patternformatter.rb +145 -0
  52. data/lib/log4r/lib/drbloader.rb +52 -0
  53. data/lib/log4r/lib/xmlloader.rb +24 -0
  54. data/lib/log4r/logevent.rb +28 -0
  55. data/lib/log4r/logger.rb +199 -0
  56. data/lib/log4r/loggerfactory.rb +89 -0
  57. data/lib/log4r/logserver.rb +28 -0
  58. data/lib/log4r/outputter/consoleoutputters.rb +18 -0
  59. data/lib/log4r/outputter/datefileoutputter.rb +117 -0
  60. data/lib/log4r/outputter/emailoutputter.rb +143 -0
  61. data/lib/log4r/outputter/fileoutputter.rb +56 -0
  62. data/lib/log4r/outputter/iooutputter.rb +55 -0
  63. data/lib/log4r/outputter/outputter.rb +134 -0
  64. data/lib/log4r/outputter/outputterfactory.rb +61 -0
  65. data/lib/log4r/outputter/remoteoutputter.rb +40 -0
  66. data/lib/log4r/outputter/rollingfileoutputter.rb +234 -0
  67. data/lib/log4r/outputter/scribeoutputter.rb +37 -0
  68. data/lib/log4r/outputter/staticoutputter.rb +30 -0
  69. data/lib/log4r/outputter/syslogoutputter.rb +130 -0
  70. data/lib/log4r/outputter/udpoutputter.rb +53 -0
  71. data/lib/log4r/rdoc/GDC +14 -0
  72. data/lib/log4r/rdoc/MDC +16 -0
  73. data/lib/log4r/rdoc/NDC +41 -0
  74. data/lib/log4r/rdoc/configurator +243 -0
  75. data/lib/log4r/rdoc/emailoutputter +103 -0
  76. data/lib/log4r/rdoc/formatter +39 -0
  77. data/lib/log4r/rdoc/log4r +89 -0
  78. data/lib/log4r/rdoc/logger +175 -0
  79. data/lib/log4r/rdoc/logserver +85 -0
  80. data/lib/log4r/rdoc/outputter +108 -0
  81. data/lib/log4r/rdoc/patternformatter +128 -0
  82. data/lib/log4r/rdoc/scribeoutputter +16 -0
  83. data/lib/log4r/rdoc/syslogoutputter +29 -0
  84. data/lib/log4r/rdoc/win32eventoutputter +7 -0
  85. data/lib/log4r/rdoc/yamlconfigurator +20 -0
  86. data/lib/log4r/repository.rb +88 -0
  87. data/lib/log4r/staticlogger.rb +49 -0
  88. data/lib/log4r/yamlconfigurator.rb +196 -0
  89. data/tests/README +10 -0
  90. data/tests/testGDC.rb +26 -0
  91. data/tests/testMDC.rb +42 -0
  92. data/tests/testNDC.rb +27 -0
  93. data/tests/testall.rb +6 -0
  94. data/tests/testbase.rb +49 -0
  95. data/tests/testchainsaw.rb +48 -0
  96. data/tests/testconf.xml +37 -0
  97. data/tests/testcustom.rb +27 -0
  98. data/tests/testformatter.rb +27 -0
  99. data/tests/testlogger.rb +196 -0
  100. data/tests/testoutputter.rb +132 -0
  101. data/tests/testpatternformatter.rb +78 -0
  102. data/tests/testthreads.rb +35 -0
  103. data/tests/testxmlconf.rb +45 -0
  104. metadata +184 -0
Binary file
@@ -0,0 +1,25 @@
1
+ # How to use RemoteOutputter. See logserver.rb first.
2
+
3
+ $: << File.join('..','lib')
4
+ require 'log4r'
5
+ require 'log4r/outputter/remoteoutputter'
6
+ include Log4r
7
+
8
+ Logger.new('log4r').add 'stdout' # to see what's going on inside
9
+ RemoteOutputter.new 'remote', # make a RemoteOutputter
10
+ :uri=>'tcpromp://localhost:9999', # where our LogServer is
11
+ :buffsize=>10 # buffer 10 before sending to LogServer
12
+ Logger.new('client').add('remote') # give 'remote' to a 'client' Logger
13
+
14
+ # we're done with setup, now let's log
15
+ def log(l)
16
+ l.debug "debugging"
17
+ l.info "a piece of info"
18
+ l.warn "Danger, Will Robinson, danger!"
19
+ l.error "I dropped by Wookie! :("
20
+ l.fatal "kaboom!"
21
+ end
22
+
23
+ 5.times { log(Logger['client']) } # do a bunch of logging
24
+ Logger['client'].info "Bye Bye from client!"
25
+ Outputter['remote'].flush # flush the RemoteOutputter
@@ -0,0 +1,18 @@
1
+ # How to use LogServer
2
+
3
+ $: << File.join('..','lib')
4
+ require 'log4r'
5
+ require 'log4r/configurator'
6
+
7
+ # XML configuration is simple enough to embed here
8
+ xml = %(
9
+ <log4r_config>
10
+ <logserver name="server" uri="tcpromp://localhost:9999">
11
+ <outputter>stdout</outputter>
12
+ </logserver>
13
+ </log4r_config>
14
+ )
15
+ Log4r::Logger.new('log4r').add 'stdout' # to see what's going on inside
16
+ Log4r::Configurator.load_xml_string xml # load it up
17
+ sleep
18
+ # now run logclient.rb on another terminal
@@ -0,0 +1,29 @@
1
+ <!-- the config file used by xmlconfig.rb -->
2
+ <log4r_config>
3
+ <pre_config>
4
+ <global level="DEBUG"/>
5
+ <!-- we'll set serverlog in XML and logpath at runtime for illustration -->
6
+ <parameter name="serverlog" value="./logs/server.log"/>
7
+ </pre_config>
8
+
9
+ <!-- outputters, illustrating XML config flexibility -->
10
+ <outputter type="FileOutputter" name="server">
11
+ <filename>#{serverlog}</filename>
12
+ <trunc>false</trunc>
13
+ </outputter>
14
+ <outputter type="FileOutputter" name="client"
15
+ filename="#{logpath}/client.log"/>
16
+ <outputter type="FileOutputter" name="gui"
17
+ filename="#{logpath}/guidebug.log"/>
18
+ <outputter type="StderrOutputter" name="console" level="ERROR"/>
19
+
20
+ <!-- loggers -->
21
+
22
+ <logger name="server" level="ERROR" outputters="server, console"/>
23
+ <logger name="client" level="INFO" outputters="client, console"/>
24
+ <logger name="client::gui" trace="true">
25
+ <level>DEBUG</level>
26
+ <outputter>gui</outputter>
27
+ </logger>
28
+
29
+ </log4r_config>
@@ -0,0 +1,66 @@
1
+ # Now, for something more complicted
2
+ # Let's pretend this is the global config file for our app
3
+
4
+ $: << File.join('..','lib')
5
+ require "log4r"
6
+
7
+ include Log4r # include Log4r to make things simple
8
+
9
+ Logger.root.level = DEBUG # global level DEBUG
10
+
11
+ # suppose we want to have loggers for a Server and a Client class
12
+ # furthermore, we want the client gui to have its own logger. (You'll want
13
+ # one logger per class or so.)
14
+ # When the loggers are created, they are stored in a repository for further
15
+ # retreival at any point using a hash method call: Logger['name']
16
+
17
+ # server is stable, so only log ERROR and FATAL
18
+ Logger.new("server", ERROR)
19
+ # let's say we don't need the DEBUG junk for client logs
20
+ Logger.new("client", INFO)
21
+ # but we're still debugging the gui
22
+ debugger = Logger.new("client::gui", DEBUG)
23
+ debugger.trace = true # we want to see where the log method was called
24
+
25
+ # Guilog is a child of client. In this case, any log events to the gui
26
+ # logger will also be logged to the client outputters. We can change
27
+ # that behavior by setting guilogger's 'additive' to false, but not yet.
28
+
29
+ # let's create the outputters
30
+ FileOutputter.new('server', :filename=>'logs/server.log', :trunc => false)
31
+ FileOutputter.new('client', :filename=>'logs/client.log')
32
+ FileOutputter.new('gui', :filename=>'logs/guidebug.log')
33
+ # additionally, we want ERROR and FATAL messages to go to stderr
34
+ StderrOutputter.new('console', :level=>ERROR)
35
+
36
+ # add the outputters
37
+ Logger['server'].add 'server', 'console'
38
+ Logger['client'].add 'client', 'console'
39
+ Logger['client::gui'].add 'gui' # gui will also write to client's outputters
40
+
41
+ # That's it for config. Now let's use the loggers:
42
+
43
+ def do_logging(log)
44
+ log.debug "debugging"
45
+ log.info "a piece of info"
46
+ log.warn "Danger, Will Robinson, danger!"
47
+ log.error "I dropped my Wookie! :("
48
+ log.fatal "kaboom!"
49
+ end
50
+
51
+ Logger.each_logger{|logger| do_logging(logger) }
52
+
53
+ # You can dynamically change levels and turn off tracing:
54
+ Logger['client'].level = OFF
55
+ Logger['client::gui'].trace = false
56
+
57
+ puts 'Only server should show Dynamic Change onscreen:'
58
+ Logger.each_logger{|logger| logger.fatal "Dynamic change." }
59
+ # logs/client.log file should not show "Dynamic change."
60
+ # logs/guidebug.log should not show the trace at "Dynamic change."
61
+
62
+ # we can also set our outputter to log only specified levels:
63
+
64
+ Outputter['console'].only_at ERROR
65
+ puts "Should only see ERROR next:"
66
+ do_logging Logger['server']
@@ -0,0 +1,23 @@
1
+ # try out a custom formatter
2
+
3
+ $: << '../lib'
4
+
5
+ require "log4r"
6
+
7
+ class MyFormatter < Log4r::Formatter
8
+ def format(event)
9
+ buff = "The level is #{event.level} and has "
10
+ buff += "name '#{Log4r::LNAMES[event.level]}'\n"
11
+ buff += "The logger is '#{event.name}' "
12
+ buff += "and the data type is #{event.data.class}\n"
13
+ buff += "Let's inspect the data:\n"
14
+ buff += event.data.inspect + "\n"
15
+ buff += "We were called at #{event.tracer[0]}\n\n"
16
+ end
17
+ end
18
+
19
+ log = Log4r::Logger.new('custom formatter')
20
+ log.trace = true
21
+ log.add Log4r::StdoutOutputter.new('stdout', :formatter=>MyFormatter)
22
+ log.info [1, 2, 3, 4]
23
+ log.error "A log statement"
@@ -0,0 +1,21 @@
1
+ # Here's how to start using log4r right away
2
+ $: << File.join('..','lib') # path if log4r not installed
3
+ require "log4r"
4
+
5
+ Log = Log4r::Logger.new("outofthebox") # create a logger
6
+ Log.add Log4r::Outputter.stderr # which logs to stdout
7
+
8
+ # do some logging
9
+ def do_logging
10
+ Log.debug "debugging"
11
+ Log.info "a piece of info"
12
+ Log.warn "Danger, Will Robinson, danger!"
13
+ Log.error "I dropped my Wookie! :("
14
+ Log.fatal "kaboom!"
15
+ end
16
+ do_logging
17
+
18
+ # now let's filter anything below WARN level (DEBUG and INFO)
19
+ puts "-= Changing level to WARN =-"
20
+ Log.level = Log4r::WARN
21
+ do_logging
@@ -0,0 +1,2 @@
1
+ rdoc --exclude *CVS* --exclude .*patch --exclude diff
2
+
@@ -0,0 +1,63 @@
1
+ <!-- This is a real config file used by a game that I'm working on
2
+ The Ruby file that loads this is rrsetup.rb -->
3
+ <log4r_config>
4
+ <pre_config>
5
+ <!-- I like having a ton of levels. There are three extra for component
6
+ data, comp1..3 and one level for object dumps (DATA) -->
7
+ <custom_levels>
8
+ COMP3, COMP2, COMP1, DATA, DEBUG, INFO, WARN, ERROR, FATAL
9
+ </custom_levels>
10
+ <!-- change to ERROR when the game goes to production -->
11
+ <global level="ALL"/>
12
+ </pre_config>
13
+
14
+ <!-- Outputters -->
15
+
16
+ <!-- game.log records DEBUG and higher, so no game component data -->
17
+ <outputter name="gameout" type="FileOutputter" level="DEBUG">
18
+ <!-- I set the logpath from within the game. -->
19
+ <filename>#{logpath}/game.log</filename>
20
+ </outputter>
21
+ <!-- DATA level goes to its own special file. These log events are
22
+ too noisy for game.log and are not game components. Useful
23
+ for dumping lots of objects during development. -->
24
+ <outputter name="gamedata" type="FileOutputter" only_at="DATA">
25
+ <filename>#{logpath}/data.log</filename>
26
+ <!-- low-noise custom formatter for objects -->
27
+ <formatter type="CompFormatter"/>
28
+ </outputter>
29
+ <!-- Spit any errors to the console. They merit special attention -->
30
+ <outputter name="console" type="StderrOutputter" level="ERROR"/>
31
+ <!-- A separate log file for tracking game components,
32
+ used for development. It logs ALL-->
33
+ <outputter name="componentout" type="FileOutputter">
34
+ <filename>#{logpath}/component.log</filename>
35
+ <formatter type="CompFormatter"/>
36
+ </outputter>
37
+
38
+ <!-- Loggers -->
39
+
40
+ <!-- 'game' is the main logger for the client-server framework -->
41
+ <logger name="game" level="DATA" additive="false" trace="true">
42
+ <outputters>gameout, gamedata, console</outputters>
43
+ </logger>
44
+ <!-- Notice how we have fine control over how each element logs.
45
+ The gui and controller are stable while the rest are being debugged. -->
46
+ <logger name="game::gui" level="ERROR" additive="true" trace="true"/>
47
+ <logger name="game::boardgui" level="DEBUG" additive="true" trace="false"/>
48
+ <logger name="game::server" level="DEBUG" additive="true" trace="true"/>
49
+ <logger name="game::client" level="DEBUG" additive="true" trace="true"/>
50
+ <logger name="game::controller" level="ERROR" additive="true" trace="false"/>
51
+
52
+ <!-- 'component' is the main logger for game objects. It's used in
53
+ development to track how the objects change with time. -->
54
+ <logger name="component" level="ALL" additive="false" trace="false">
55
+ <outputter>componentout</outputter>
56
+ <outputter>console</outputter>
57
+ </logger>
58
+ <logger name="component::board"/>
59
+ <logger name="component::tile"/>
60
+ <logger name="component::player"/>
61
+ <logger name="component::player::robot"/>
62
+
63
+ </log4r_config>
@@ -0,0 +1,42 @@
1
+ # This is a real config file used by a game that I'm working on
2
+ # The XML config file is called rrconfig.xml
3
+
4
+ $: << File.join('..','lib')
5
+ require 'log4r'
6
+ require 'log4r/configurator'
7
+ include Log4r
8
+
9
+ # How to format component data - low noise
10
+ class CompFormatter < Formatter
11
+ def format(event)
12
+ buff = event.name + "> "
13
+ if event.data.kind_of?(String) then buff += event.data
14
+ else buff += event.data.inspect end
15
+ return buff + "\n"
16
+ end
17
+ end
18
+
19
+ # Set the logpath. Eventually, this will be determined from the environment.
20
+ Configurator['logpath'] = './logs'
21
+ Configurator.load_xml_file('rrconfig.xml')
22
+
23
+ # the rest is an example
24
+
25
+ Robot = {"name"=>"twonky", "row"=>"3", "col"=>"4"}
26
+
27
+ def do_logging(log)
28
+ log.comp3 Robot
29
+ log.comp2 Robot
30
+ log.comp1 Robot
31
+ log.data "this is a piece of data".split
32
+ log.debug "debugging"
33
+ log.info "a piece of info"
34
+ log.warn "Danger, Will Robinson, danger!"
35
+ log.error "I dropped my Wookie! :("
36
+ log.fatal "kaboom!"
37
+ end
38
+
39
+ Logger.each_logger {|logger| do_logging(logger)}
40
+
41
+ # you can see the results onscreen and in logs/game.log
42
+ # logs/data.log and logs/component.log
@@ -0,0 +1,39 @@
1
+ # Simple configuration example.
2
+ # Where we configure just one logger and make it log to a file and stdout.
3
+
4
+ # add the path to log4r if it isn't installed in a ruby path
5
+ $: << File.join('..','lib')
6
+ require "log4r"
7
+
8
+ # First things first, get the root logger and set its level to WARN.
9
+ # This makes the global level WARN. Later on, we can turn off all logging
10
+ # by setting it to OFF right here (or dynamically if you prefer)
11
+ Log4r::Logger.root.level = Log4r::WARN
12
+
13
+ # Remember: By specifying a level, we are saying "Include this level and
14
+ # anything worse." So in this case, we're logging WARN, ERROR and FATAL
15
+
16
+ # create a logger
17
+ log = Log4r::Logger.new("simpleconf")
18
+
19
+ # We want to log to $stderr and a file ./tmp.log
20
+
21
+ # Create an outputter for $stderr. It defaults to the root level WARN
22
+ Log4r::StderrOutputter.new 'console'
23
+ # for the file, we want to log only FATAL and ERROR and don't trunc
24
+ Log4r::FileOutputter.new('logfile',
25
+ :filename=>'logs/simple.log',
26
+ :trunc=>false,
27
+ :level=>Log4r::FATAL)
28
+
29
+ # add the outputters (this method accepts outputter names or references)
30
+ log.add('console','logfile')
31
+
32
+ # Now let's try it out:
33
+ log.debug "debugging"
34
+ log.info "a piece of info"
35
+ log.warn "Danger, Will Robinson, danger!"
36
+ log.error "I dropped my Wookie! :("
37
+ log.fatal "kaboom!"
38
+
39
+ # now run this and compare output to ./tmp.log
@@ -0,0 +1,52 @@
1
+ # Suppose we don't like having 5 levels named DEBUG, INFO, etc.
2
+ # Suppose we'd rather use 3 levels named Foo, Bar, and Baz.
3
+ # Suppose we'd like to use these with syslog
4
+ # Log4r allows you to rename the levels and their corresponding methods
5
+ # in a painless way and then map those to corrisponding syslog levels
6
+ # or have them all default to LOG_INFO
7
+ # This file provides an example
8
+
9
+ $: << '../lib'
10
+
11
+ require 'log4r'
12
+ require 'log4r/configurator'
13
+ require 'log4r/formatter/patternformatter'
14
+ require 'log4r/outputter/syslogoutputter'
15
+ require 'syslog'
16
+ include Log4r
17
+ include Syslog::Constants
18
+
19
+ # This is how we specify our levels
20
+ Configurator.custom_levels "Foo", "Bar", "Baz"
21
+
22
+ l = Logger.new('custom levels')
23
+ slp = PatternFormatter.new( :pattern => '{%p} {%h} {%d} {%l} {%C} {%m}', :date_method => 'usec' )
24
+ sl = SyslogOutputter.new( 'sysloggertest',
25
+ { :logopt => LOG_CONS | LOG_PID | LOG_PERROR,
26
+ :facility => LOG_LOCAL7,
27
+ :formatter => slp } )
28
+ sl.map_levels_by_name_to_syslog( { "Foo" => "DEBUG", "Bar" => "INFO", "Baz" => "ALERT" } )
29
+ l.add sl
30
+
31
+ l.level = Foo
32
+ puts l.foo?
33
+ l.foo "This is foo"
34
+ puts l.bar?
35
+ l.bar "this is bar"
36
+ puts l.baz?
37
+ l.baz "this is baz"
38
+
39
+ puts "Now change to Baz"
40
+
41
+ l.level = Baz
42
+ puts l.foo?
43
+ l.foo {"This is foo"}
44
+ puts l.bar?
45
+ l.bar {"this is bar"}
46
+ puts l.baz?
47
+ l.baz {"this is baz"}
48
+
49
+ l4r = Logger.new('log4r')
50
+ l4r.add Log4r::Outputter.stderr
51
+
52
+ Log4r::SyslogOutputter.new 'test'
@@ -0,0 +1,25 @@
1
+ # This is like moderateconfig.rb, but using an XML config
2
+ # please look at moderate.xml
3
+
4
+ $: << '../lib'
5
+
6
+ require 'log4r'
7
+ require 'log4r/configurator'
8
+ include Log4r
9
+
10
+ # set any runtime XML variables
11
+ Configurator['logpath'] = './logs'
12
+ # Load up the config file
13
+ Configurator.load_xml_file('./moderate.xml')
14
+
15
+ # now repeat what moderateconfig.rb does
16
+ def do_logging(log)
17
+ log.debug "debugging"
18
+ log.info "a piece of info"
19
+ log.warn "Danger, Will Robinson, danger!"
20
+ log.error "I dropped my Wookie! :("
21
+ log.fatal "kaboom!"
22
+ end
23
+
24
+ Logger.each_logger{|logger| do_logging(logger) }
25
+ # stop here
@@ -0,0 +1,30 @@
1
+ # Log4r can be configured using YAML. This example uses log4r_yaml.yaml
2
+
3
+ $: << File.join('..','lib') # path if log4r is not installed
4
+ require 'log4r'
5
+ require 'log4r/yamlconfigurator'
6
+ # we use various outputters, so require them, otherwise config chokes
7
+ require 'log4r/outputter/datefileoutputter'
8
+ require 'log4r/outputter/emailoutputter'
9
+ require 'log4r/outputter/scribeoutputter'
10
+
11
+ cfg = Log4r::YamlConfigurator # shorthand
12
+ cfg['HOME'] = '.' # the only parameter in the YAML, our HOME directory
13
+
14
+ # load the YAML file with this
15
+ cfg.load_yaml_file('log4r_yaml.yaml')
16
+
17
+ # Method to log each of the custom levels
18
+ def do_logging(log)
19
+ log.deb "This is DEB"
20
+ log.inf "This is INF"
21
+ log.prt "This is PRT"
22
+ log.wrn "This is WRN"
23
+ log.err "This is ERR"
24
+ log.fat "This is FAT"
25
+ end
26
+
27
+ # turn off the email outputter
28
+ Log4r::Outputter['email'].level = Log4r::OFF
29
+ # the other two outputters log to stderr and a timestamped file in ./logs
30
+ do_logging( Log4r::Logger['mylogger'])