sml-log4r 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/content/contact.html +22 -0
- data/doc/content/contribute.html +21 -0
- data/doc/content/index.html +90 -0
- data/doc/content/license.html +56 -0
- data/doc/content/manual.html +449 -0
- data/doc/dev/README.developers +40 -0
- data/doc/dev/checklist +14 -0
- data/doc/dev/things-to-do +2 -0
- data/doc/images/crush/logo2.png +0 -0
- data/doc/images/log4r-logo.png +0 -0
- data/doc/images/logo2.png +0 -0
- data/doc/log4r.css +111 -0
- data/doc/old/manual.html +348 -0
- data/doc/templates/main.html +147 -0
- data/examples/README +19 -0
- data/examples/customlevels.rb +34 -0
- data/examples/fileroll.rb +40 -0
- data/examples/log4r_yaml.yaml +0 -0
- data/examples/logclient.rb +25 -0
- data/examples/logserver.rb +18 -0
- data/examples/moderate.xml +29 -0
- data/examples/moderateconfig.rb +66 -0
- data/examples/myformatter.rb +23 -0
- data/examples/outofthebox.rb +21 -0
- data/examples/rrconfig.xml +63 -0
- data/examples/rrsetup.rb +42 -0
- data/examples/simpleconfig.rb +39 -0
- data/examples/xmlconfig.rb +25 -0
- data/examples/yaml.rb +30 -0
- data/src/log4r.rb +17 -0
- data/src/log4r/base.rb +74 -0
- data/src/log4r/config.rb +9 -0
- data/src/log4r/configurator.rb +224 -0
- data/src/log4r/formatter/formatter.rb +105 -0
- data/src/log4r/formatter/patternformatter.rb +108 -0
- data/src/log4r/lib/drbloader.rb +52 -0
- data/src/log4r/lib/xmlloader.rb +24 -0
- data/src/log4r/logevent.rb +28 -0
- data/src/log4r/logger.rb +194 -0
- data/src/log4r/loggerfactory.rb +89 -0
- data/src/log4r/logserver.rb +28 -0
- data/src/log4r/outputter/consoleoutputters.rb +18 -0
- data/src/log4r/outputter/datefileoutputter.rb +110 -0
- data/src/log4r/outputter/emailoutputter.rb +115 -0
- data/src/log4r/outputter/fileoutputter.rb +49 -0
- data/src/log4r/outputter/iooutputter.rb +55 -0
- data/src/log4r/outputter/outputter.rb +132 -0
- data/src/log4r/outputter/outputterfactory.rb +59 -0
- data/src/log4r/outputter/remoteoutputter.rb +40 -0
- data/src/log4r/outputter/rollingfileoutputter.rb +126 -0
- data/src/log4r/outputter/staticoutputter.rb +30 -0
- data/src/log4r/outputter/syslogoutputter.rb +75 -0
- data/src/log4r/rdoc/configurator +243 -0
- data/src/log4r/rdoc/emailoutputter +103 -0
- data/src/log4r/rdoc/formatter +39 -0
- data/src/log4r/rdoc/log4r +89 -0
- data/src/log4r/rdoc/logger +175 -0
- data/src/log4r/rdoc/logserver +85 -0
- data/src/log4r/rdoc/outputter +108 -0
- data/src/log4r/rdoc/patternformatter +128 -0
- data/src/log4r/rdoc/syslogoutputter +29 -0
- data/src/log4r/rdoc/yamlconfigurator +20 -0
- data/src/log4r/repository.rb +65 -0
- data/src/log4r/staticlogger.rb +49 -0
- data/src/log4r/yamlconfigurator.rb +0 -0
- data/tests/include.rb +7 -0
- data/tests/runtest.rb +6 -0
- data/tests/testbase.rb +45 -0
- data/tests/testcustom.rb +33 -0
- data/tests/testdefault.rb +25 -0
- data/tests/testformatter.rb +29 -0
- data/tests/testlogger.rb +198 -0
- data/tests/testoutputter.rb +112 -0
- data/tests/testpatternformatter.rb +26 -0
- data/tests/testxmlconf.rb +51 -0
- data/tests/xml/testconf.xml +37 -0
- metadata +140 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
This document introduces interested developers to log4r development.
|
2
|
+
|
3
|
+
|
4
|
+
HTML manual and site
|
5
|
+
--------------------
|
6
|
+
|
7
|
+
This is pieced together with a homebrewed content-template system.
|
8
|
+
doc/content has the actual contents, which are just three lines of metadata
|
9
|
+
and a bunch of <tr>s that are incorporated into a template. The only template
|
10
|
+
is doc/templates/main.html which is universal. To test the changes, run
|
11
|
+
bin/makedoc.rb directly and check the results in doc/index.html.
|
12
|
+
|
13
|
+
|
14
|
+
Testing RDoc
|
15
|
+
------------
|
16
|
+
Either run bin/makerdoc.rb directly or,
|
17
|
+
|
18
|
+
cd src/
|
19
|
+
rdoc --op /tmp/rdoc --template kilmer --main log4r.rb
|
20
|
+
|
21
|
+
|
22
|
+
Automated Builds
|
23
|
+
----------------
|
24
|
+
|
25
|
+
The build system is automated and relies on CVS and ruby. There are three main
|
26
|
+
things that go on during build:
|
27
|
+
|
28
|
+
1) bin/makedist.rb checks out a build to prepare for distribution and calls
|
29
|
+
other build scripts, then assembles the distribution into tgz and zip balls
|
30
|
+
|
31
|
+
2) HTML manual is constructed by bin/makehtml.rb, called from makedist.rb
|
32
|
+
|
33
|
+
3) RDoc is constructed by bin/makerdoc.rb, called from makedist.rb
|
34
|
+
|
35
|
+
All system variables and configurable options are in bin/devconfig.rb.
|
36
|
+
|
37
|
+
Essentially, the only thing that needs to be done to build packages for
|
38
|
+
distribution is,
|
39
|
+
|
40
|
+
ruby makedist.rb <version-number>
|
data/doc/dev/checklist
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Distribution checklist:
|
2
|
+
|
3
|
+
* DON'T FORGET: change install.rb when new src/ files are added
|
4
|
+
* DON'T FORGET: change the log4r.gemspec file for same
|
5
|
+
* Update the changelog
|
6
|
+
* Update the README
|
7
|
+
* Change any INSTALL instructions
|
8
|
+
* Update the manuals and HTML
|
9
|
+
* Modify what should not appear in the release (bin/prune.rb)
|
10
|
+
* Run makedist.rb and check the integrity of the resulting tarballs
|
11
|
+
- Test installs
|
12
|
+
- Run the unit tests (cd tests; ruby runtest.rb)
|
13
|
+
- Run all the examples
|
14
|
+
- Browse the docs
|
Binary file
|
Binary file
|
Binary file
|
data/doc/log4r.css
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
body {
|
2
|
+
background-color: #FFFFFF;
|
3
|
+
font-family:sans-serif;
|
4
|
+
}
|
5
|
+
|
6
|
+
a:link { color:#014DA3 }
|
7
|
+
a:active { color:#AA0000 }
|
8
|
+
a:visited { color:#014DA3 }
|
9
|
+
a:hoover { color:#AA0000 }
|
10
|
+
|
11
|
+
.example {
|
12
|
+
font-family: monospace;
|
13
|
+
border:1px solid #007;
|
14
|
+
background:#FFFFFF;
|
15
|
+
margin:1em;
|
16
|
+
}
|
17
|
+
|
18
|
+
pre.box {
|
19
|
+
margin:0px 1em 1em 1em;
|
20
|
+
color:#AA0000;
|
21
|
+
}
|
22
|
+
|
23
|
+
.menu {
|
24
|
+
font-family:sans-serif;
|
25
|
+
font-size:10px;
|
26
|
+
border-left: 1px solid #AA0000;
|
27
|
+
border-right: 1px solid #AA0000;
|
28
|
+
border-bottom: 1px solid #AA0000;
|
29
|
+
background:#EEEEEE;
|
30
|
+
color:#AA0000;
|
31
|
+
}
|
32
|
+
|
33
|
+
.menutitle {
|
34
|
+
font-family:sans-serif;
|
35
|
+
font-size:medium;
|
36
|
+
color:#FFFFFF;
|
37
|
+
font-weight:bold;
|
38
|
+
background:#AA0000;
|
39
|
+
border-right: 1px solid #AA0000;
|
40
|
+
border-left: 1px solid #AA0000;
|
41
|
+
border-top: 1px solid #AA0000;
|
42
|
+
border-bottom: 1px solid #AA0000;
|
43
|
+
}
|
44
|
+
|
45
|
+
.menubuff {
|
46
|
+
font-family:sans-serif;
|
47
|
+
font-size:1px;
|
48
|
+
color:#000000;
|
49
|
+
border-left: 1px solid #AA0000;
|
50
|
+
border-right: 1px solid #AA0000;
|
51
|
+
font-weight:bold;
|
52
|
+
background-color: #99CCFF;
|
53
|
+
height:5;
|
54
|
+
padding-bottom: 0;
|
55
|
+
}
|
56
|
+
|
57
|
+
.contentbuff {
|
58
|
+
font-family:sans-serif;
|
59
|
+
font-size:10px;
|
60
|
+
border-left: 1px solid #AA0000;
|
61
|
+
border-right: 1px solid #AA0000;
|
62
|
+
font-weight:bold;
|
63
|
+
background-color: #99CCFF;
|
64
|
+
height:5;
|
65
|
+
padding-bottom: 0;
|
66
|
+
}
|
67
|
+
|
68
|
+
.header {
|
69
|
+
font-family:sans-serif;
|
70
|
+
color:#AA0000;
|
71
|
+
}
|
72
|
+
|
73
|
+
.content {
|
74
|
+
font-family:sans-serif;
|
75
|
+
font-size:medium;
|
76
|
+
color:#000000;
|
77
|
+
background:#EEEEEE;
|
78
|
+
border-right: 2px solid #AA0000;
|
79
|
+
border-left: 2px solid #AA0000;
|
80
|
+
border-bottom: 2px solid #AA0000;
|
81
|
+
padding-bottom: 5;
|
82
|
+
padding-right: 5;
|
83
|
+
padding-left: 5;
|
84
|
+
padding-top: 0;
|
85
|
+
}
|
86
|
+
.contenttitle {
|
87
|
+
font-family:sans-serif;
|
88
|
+
font-size:medium;
|
89
|
+
color:#FFFFFF;
|
90
|
+
font-weight:bold;
|
91
|
+
background-color:#AA0000;
|
92
|
+
border-left: 2px solid #AA0000;
|
93
|
+
border-top: 1px solid #AA0000;
|
94
|
+
border-right: 2px solid #AA0000;
|
95
|
+
padding: 2;
|
96
|
+
}
|
97
|
+
|
98
|
+
.contentbuff {
|
99
|
+
font-family:sans-serif;
|
100
|
+
font-size:10px;
|
101
|
+
color:#014DA3;
|
102
|
+
border-left: 2px solid #AA0000;
|
103
|
+
border-right: 2px solid #AA0000;
|
104
|
+
font-weight:bold;
|
105
|
+
background-color:#99CCFF;
|
106
|
+
height:13;
|
107
|
+
padding-bottom: 0;
|
108
|
+
}
|
109
|
+
|
110
|
+
br { padding-bottom: 200 }
|
111
|
+
|
data/doc/old/manual.html
ADDED
@@ -0,0 +1,348 @@
|
|
1
|
+
<html>
|
2
|
+
<head><title>Log4r - A Powerful Logger for Ruby</title></head>
|
3
|
+
<body bgcolor="#FFFFFF">
|
4
|
+
<h1><font color="#AA0000">Log4r - A Powerful Logger for Ruby</font></h1>
|
5
|
+
Inspired by the
|
6
|
+
<a href="http://jakarta.apache.org/log4j/docs/index.html">Apache Log4j</a>
|
7
|
+
project
|
8
|
+
<hr/>
|
9
|
+
|
10
|
+
<h4>At a Glance</h4>
|
11
|
+
|
12
|
+
<blockquote>
|
13
|
+
Log4r features an extremely flexible logging library for Ruby.
|
14
|
+
Killer features include a heiarchial logging system of any number of
|
15
|
+
levels, logger inheritance, multiple output destinations, tracing, custom
|
16
|
+
formatting and more.
|
17
|
+
<p>
|
18
|
+
Log4r was inspired by the very excellent
|
19
|
+
<a href="http://jakarta.apache.org/log4j/docs/index.html">
|
20
|
+
Apache Log4j Project</a>
|
21
|
+
. Log4r provides the defining features of Log4j and some of its own
|
22
|
+
features that just might make Log4j users envious. <code>;-)</code>
|
23
|
+
<p/>
|
24
|
+
The project is hosted on SourceForge:
|
25
|
+
<a href="http://sourceforge.net/projects/log4r/">
|
26
|
+
http://sourceforge.net/projects/log4r/</a>
|
27
|
+
</blockquote>
|
28
|
+
|
29
|
+
<h4>Download</h4>
|
30
|
+
|
31
|
+
<blockquote>
|
32
|
+
Latest version is
|
33
|
+
<a href="http://sourceforge.net/project/showfiles.php?group_id=43396">
|
34
|
+
Log4r 0.9.8</a>. All versions are stable. Newer ones have more features.
|
35
|
+
<p/>
|
36
|
+
The
|
37
|
+
<a href="rdoc/index.html">API is available</a>
|
38
|
+
in a Javadoc-like format (thanks go to the
|
39
|
+
<a href="http://rdoc.sourceforge.net/">RDoc project</a>).
|
40
|
+
</blockquote>
|
41
|
+
|
42
|
+
|
43
|
+
<h4>But why?</h4>
|
44
|
+
|
45
|
+
<blockquote>
|
46
|
+
Please read the
|
47
|
+
<a href="http://jakarta.apache.org/log4j/docs/index.html">Introduction</a>
|
48
|
+
to Apache Log4j for answers. Personally, I find
|
49
|
+
that a logging system such as Log4r is essential when writing distributed
|
50
|
+
applications, like for a game that has a client/server design. Also, the
|
51
|
+
ability to leave logging statements in the code without commenting them out
|
52
|
+
is quite handy.
|
53
|
+
</blockquote>
|
54
|
+
|
55
|
+
<h4>Features</h4>
|
56
|
+
<blockquote>
|
57
|
+
<dl>
|
58
|
+
<dt><b><font color="#AA0000">Easy to use</font></b></dt>
|
59
|
+
<dd><p/>
|
60
|
+
Thanks to Ruby, Log4r is an extremely simple tool to use. It should become
|
61
|
+
evident as you read further. <code>;)</code>
|
62
|
+
<p/></dd>
|
63
|
+
<dt><b><font color="#AA0000">Multiple loggers</font></b></dt>
|
64
|
+
<dd>
|
65
|
+
<p/>
|
66
|
+
You can have as many loggers as desired. Upon creation, they get stored
|
67
|
+
in a Singleton repository from which they can be retrieved at any point.
|
68
|
+
<pre>
|
69
|
+
Log4r::Logger.new('mylogger') # create a logger 'mylogger'
|
70
|
+
Log4r::Logger['mylogger'] # get 'mylogger' back
|
71
|
+
</pre>
|
72
|
+
<p/>
|
73
|
+
</dd>
|
74
|
+
<dt><b><font color="#AA0000">Heiarchial logging</font></b></dt>
|
75
|
+
<dd>
|
76
|
+
<p/>
|
77
|
+
Log4r provides five levels of logging:
|
78
|
+
<code>DEBUG, INFO, WARN, ERROR, FATAL</code>.
|
79
|
+
A logger with a certain level will not perform logging for all levels
|
80
|
+
below it (less important, if you will). Hence, if a logger is set to
|
81
|
+
<code>WARN</code>, it won't log <code>DEBUG</code>, and
|
82
|
+
<code>INFO</code> log events.
|
83
|
+
<code>ALL</code> and <code>OFF</code> are special
|
84
|
+
boundary levels. Setting a logger to <code>ALL</code> will let it see evey log event
|
85
|
+
while setting it to <code>OFF</code> will disable all log events. It's not possible
|
86
|
+
to log at <code>ALL</code> and <code>OFF</code>.
|
87
|
+
<pre>
|
88
|
+
include Log4r # include for brevity
|
89
|
+
|
90
|
+
log = Logger['mylogger']
|
91
|
+
log.level = WARN # set log level to Log4r::WARN
|
92
|
+
|
93
|
+
log.debug "DEBUG log event" # won't show up
|
94
|
+
log.info "INFO log event" # ditto
|
95
|
+
log.warn "WARN log event" # will show up, and all that follow
|
96
|
+
log.error "ERROR log event"
|
97
|
+
log.fatal "FATAL log event"
|
98
|
+
</pre>
|
99
|
+
<br/>
|
100
|
+
You can dynamically reassign a logger's level if you want.
|
101
|
+
<p/>
|
102
|
+
</dd>
|
103
|
+
<dt><b><font color="#AA0000">Custom levels</font></b></dt>
|
104
|
+
<dd>
|
105
|
+
<p/>
|
106
|
+
And now, something that will really make Log4j users envious: You can
|
107
|
+
change the number and names of the heiarchial logging levels easily.
|
108
|
+
Suppose we don't like having 5 levels named <code>DEBUG</code>, <code>INFO</code>, etc.
|
109
|
+
Instead, we want <code>Foo</code>, <code>Bar</code>, and <code>Baz</code>.
|
110
|
+
Here's how we do it:
|
111
|
+
<pre>
|
112
|
+
Log4r::Logger.custom_levels 'Foo', 'Bar', 'Baz'
|
113
|
+
</pre>
|
114
|
+
<br/>
|
115
|
+
Thereafter, the logging methods will be named after your custom levels:
|
116
|
+
<p/>
|
117
|
+
<pre>
|
118
|
+
log.level = Log4r::Bar
|
119
|
+
log.foo? => false
|
120
|
+
log.bar? => true
|
121
|
+
log.bar "this is bar" => <Bar> this is bar
|
122
|
+
log.baz "this is baz" => <Baz> this is baz
|
123
|
+
</pre>
|
124
|
+
<p/>
|
125
|
+
</dd>
|
126
|
+
<dt><b><font color="#AA0000">Multiple output destinations</font></b></dt>
|
127
|
+
<dd>
|
128
|
+
<p/>
|
129
|
+
The second block of code won't do anything because <code>mylogger</code> does
|
130
|
+
not have anything to write to. In order to log somewhere, we have to
|
131
|
+
create an <b>Outputter</b> and assign it to our logger. We can give our
|
132
|
+
logger as many <code>Outputters</code> as we want:
|
133
|
+
<pre>
|
134
|
+
# continuing from second block
|
135
|
+
|
136
|
+
f = FileOutputter.new(:filename => './tmp.log')
|
137
|
+
so = StdoutOutputter.new
|
138
|
+
se = StderrOutputter.new
|
139
|
+
ex = Outputter.new(ExoticIO.new) # outputter with an IO of our own make
|
140
|
+
log.add(f, so, se, ex)
|
141
|
+
log.error "A test error" # writes to all 4 IOs
|
142
|
+
</pre>
|
143
|
+
<br/>
|
144
|
+
If an <code>IO</code> somehow chokes, the Outputter will set itself to
|
145
|
+
<code>OFF</code> and close the <code>IO</code>.
|
146
|
+
<p/>
|
147
|
+
</dd>
|
148
|
+
<dt><b><font color="#AA0000">Root logger, global threshold and Logger inheritance</font></b></dt>
|
149
|
+
<dd>
|
150
|
+
<p/>
|
151
|
+
A logger can inherit another logger. It turns out that every logger
|
152
|
+
that you create normally is a child of the <b>root</b> logger.
|
153
|
+
The <b>root</b> logger does two things: Provide the global logging level
|
154
|
+
and the default level for its immediate children.
|
155
|
+
<pre>
|
156
|
+
Logger.root.level = ERROR # set global level to ERROR
|
157
|
+
Logger.new("alog") # alog inherits ERROR
|
158
|
+
</pre>
|
159
|
+
<br/>
|
160
|
+
From this point on, the only log events (by <b>alog</b> and <b>mylogger</b>)
|
161
|
+
that can show up are <code>ERROR</code> and <code>FATAL</code>.
|
162
|
+
<p/>
|
163
|
+
To have one logger inherit another, specify the name of the parent
|
164
|
+
in the argument to <code>Logger.new</code> as follows:
|
165
|
+
<code>"parent::child"</code>. Specifying 'root' is optional. Because
|
166
|
+
of namespace collision concerns, you need to specify the full path
|
167
|
+
to the logger as in <code>foo::bar::baz</code>. The same thing must be done for
|
168
|
+
retrieving loggers from the repository:
|
169
|
+
<pre>
|
170
|
+
Logger.new('mylogger::mychild') # mychild is a child of mylogger
|
171
|
+
Logger['mylogger::mychild'] # get mychild back
|
172
|
+
</pre>
|
173
|
+
<br/>
|
174
|
+
A child logger that does not define its level during creation will inherit
|
175
|
+
the level of its parent.
|
176
|
+
<p/>
|
177
|
+
</dd>
|
178
|
+
<dt><b><font color="#AA0000">Outputter inheritance</font></b></dt>
|
179
|
+
<dd>
|
180
|
+
<p/>
|
181
|
+
In addition to level, a logger inherits the <code>Outputter</code>s of its
|
182
|
+
parent. That is, when <code>mychild</code> performs a logging event, it also
|
183
|
+
calls the appropriate logging event for <code>mylogger</code>. This behavior
|
184
|
+
is entirely optional and can be turned off by setting a logger's
|
185
|
+
<code>additive</code> to false:
|
186
|
+
<pre>
|
187
|
+
Logger['mylogger::mychild'].additive = false
|
188
|
+
</pre>
|
189
|
+
<br/>
|
190
|
+
Hencenforth, any logging events to mychild will not be sent to mylogger.
|
191
|
+
The buck stops here.
|
192
|
+
<p/>
|
193
|
+
</dd>
|
194
|
+
<dt><b><font color="#AA0000">Custom formatting</font></b></dt>
|
195
|
+
<dd>
|
196
|
+
<p/>
|
197
|
+
By default, Log4r is capable of formatting any object passed to it
|
198
|
+
by calling its <code>inspect</code> method. It also pre-formats
|
199
|
+
<code>Exceptions</code>.
|
200
|
+
Changing the way the data is formatted is just a matter of rolling up
|
201
|
+
your own <code>Formatter</code> class that defines the method <code>format</code>:
|
202
|
+
<pre>
|
203
|
+
class MyFormatter < Formatter
|
204
|
+
def format(level, logger, tracer, data)
|
205
|
+
# level is the integer level of the log event
|
206
|
+
# logger is the logger that called it
|
207
|
+
# tracer is the execution stack returned by caller at the log event
|
208
|
+
# data is what was passed into a logging method
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
afile = FileOutputter.new(:file=>'./prettyformat')
|
213
|
+
afile.formatter = MyFormatter.new
|
214
|
+
# add it to 'mychild' dynamically
|
215
|
+
Logger['mylogger::mychild'].add afile
|
216
|
+
</pre>
|
217
|
+
<br/>
|
218
|
+
Formatters are not inherited, they are assigned to specific outputters.
|
219
|
+
<p/>
|
220
|
+
</dd>
|
221
|
+
<dt><b><font color="#AA0000">Tracing</font></b></dt>
|
222
|
+
<dd>
|
223
|
+
<p/>
|
224
|
+
By default, loggers don't record the execution stack. You can turn on
|
225
|
+
tracing by setting a logger's <code>trace</code> to <code>true</code>. It's up to the
|
226
|
+
<code>Formatter</code> to handle this information. <code>BasicFormatter</code> displays
|
227
|
+
the line number and file of the log event.
|
228
|
+
<p/>
|
229
|
+
</dd>
|
230
|
+
<dt><b><font color="#AA0000">Ways around parameter evaluation</font></b></dt>
|
231
|
+
<dd>
|
232
|
+
<p/>
|
233
|
+
Avoiding parameter evaluation at the log method invocation can be
|
234
|
+
critical at times. One way to do this is to pass the object in
|
235
|
+
and let the formatter inspect it. The formatter won't be called for
|
236
|
+
non-loggable levels. If parameter evaluation is unavoidable, you can
|
237
|
+
querry the logger to see if it's logging at a
|
238
|
+
particular level. The following querry methods are provided:
|
239
|
+
<pre>
|
240
|
+
Logger.root.level => ERROR
|
241
|
+
log = Logger['mylogger']
|
242
|
+
log.level => WARN
|
243
|
+
log.debug? => false
|
244
|
+
log.warn? => false
|
245
|
+
log.info? => false
|
246
|
+
log.error? => true
|
247
|
+
log.fatal? => true
|
248
|
+
log.off? => false # true only if OFF is set
|
249
|
+
log.all? => false # true only if ALL is set
|
250
|
+
</pre>
|
251
|
+
<p/>
|
252
|
+
</dd>
|
253
|
+
<dt><b><font color="#AA0000">Even more flexibility: Outputter thresholds</font></b></dt>
|
254
|
+
<dd>
|
255
|
+
<p/>
|
256
|
+
Sometimes it's prudent to fix a certain outputter's level in stone, or
|
257
|
+
keep it at some independent level with respect to any loggers. (Yes, you
|
258
|
+
can share an outputter among loggers.) This can be done fairly easily by
|
259
|
+
setting the level of the outputter:
|
260
|
+
<pre>
|
261
|
+
# console log for mychild that filters out anything less important than ERROR
|
262
|
+
|
263
|
+
screen = StdoutOutputter.new(:level=>ERROR)
|
264
|
+
Logger['mychild'].add(screen)
|
265
|
+
</pre>
|
266
|
+
<br/>
|
267
|
+
And that's not all, we can also tell an Outputter to log only specific
|
268
|
+
levels. Here's how:
|
269
|
+
<p/>
|
270
|
+
<pre>
|
271
|
+
# only DEBUG and FATAL on screen
|
272
|
+
screen.only_at DEBUG, FATAL
|
273
|
+
</pre>
|
274
|
+
<p/>
|
275
|
+
</dd>
|
276
|
+
<dt><b><font color="#AA0000">Thread safe</font></b></dt>
|
277
|
+
<dd>
|
278
|
+
<p/>
|
279
|
+
Logging is thread safe. The formatting and writing to an output are
|
280
|
+
synchronized by a simple mutex in each outputter.
|
281
|
+
<p/>
|
282
|
+
</dd>
|
283
|
+
<dt><b><font color="#AA0000">Fast enough!</font></b></dt>
|
284
|
+
<dd>
|
285
|
+
<p/>
|
286
|
+
Profiling has revealed that log4r is typically an order of magnitude or two
|
287
|
+
slower than log4j. However, this is still damn fast! In particular,
|
288
|
+
if a logger is set to <code>OFF</code>, the overhead of checking to
|
289
|
+
see if
|
290
|
+
a log event should be logged nearly vanishes. This was accomplished by
|
291
|
+
dynamically redefining the unloggable logging methods to do nothing.
|
292
|
+
<p/>
|
293
|
+
I'd like to point out that if one needs to use something like log4r
|
294
|
+
in a performance-critical application, one should recondsider why Ruby
|
295
|
+
is being used at all. As far as anyone should be concerned,
|
296
|
+
log4r is Fast Enough (TM) for casual and moderate use <code>:)</code>
|
297
|
+
<p/>
|
298
|
+
Of course, this doesn't mean that we shouldn't improve the performance
|
299
|
+
of
|
300
|
+
log4r! When the time comes, it will be written as a C extension to Ruby.
|
301
|
+
<p/>
|
302
|
+
</dd>
|
303
|
+
</dl>
|
304
|
+
|
305
|
+
</blockquote>
|
306
|
+
|
307
|
+
<h4>Gotchas</h4>
|
308
|
+
|
309
|
+
If you are using Log4r, there are a few gotchas that you should be aware of:
|
310
|
+
<ul>
|
311
|
+
<li>Logger levels, tracing and additivity can be dynamically
|
312
|
+
redefined, but the changes won't be noticed by any children. That is, if
|
313
|
+
you set <code>root.level=OFF</code> after defining some loggers,
|
314
|
+
none of the loggers will change their level to <code>OFF</code>,
|
315
|
+
</li>
|
316
|
+
<li>However, if a parent changes its Outputters, its children will
|
317
|
+
recognize the change.
|
318
|
+
</li>
|
319
|
+
<li>Dynamically redefining levels, tracing and additivity is a costly
|
320
|
+
operation. It's best to set up all your loggers in a config script and
|
321
|
+
leave well enough alone. The dynamism is useful for debugging as you can
|
322
|
+
toggel tracing and level from within the file you're working on.
|
323
|
+
</li>
|
324
|
+
<li>When an <code>Outputter</code>'s <code>IO</code> is closed, the
|
325
|
+
<code>Outputter</code> changes its level to <code>OFF</code>
|
326
|
+
</li>
|
327
|
+
</ul>
|
328
|
+
|
329
|
+
<h4>The Future</h4>
|
330
|
+
<blockquote>
|
331
|
+
Log4r is mostly done. It was written in about 3 days and does enough to be
|
332
|
+
useful for most cases. There is still room for improvement performance-wise
|
333
|
+
and maybe the C extension is nigh.
|
334
|
+
</blockquote>
|
335
|
+
|
336
|
+
<h4>Obligatory SourceForge Link</h4>
|
337
|
+
<blockquote>
|
338
|
+
<A href="http://sourceforge.net"> <IMG
|
339
|
+
src="http://sourceforge.net/sflogo.php?group_id=43396" width="88" height="31"
|
340
|
+
border="0" alt="SourceForge Logo"></A>
|
341
|
+
</blockquote>
|
342
|
+
<p/>
|
343
|
+
<hr/>
|
344
|
+
<i><a href="mailto:leon@to.ugcs.caltech.edu">leon@ugcs.caltech.edu</a></i>
|
345
|
+
$Id: manual.html,v 1.1 2002/01/16 12:27:05 cepheus Exp $
|
346
|
+
|
347
|
+
</body>
|
348
|
+
</html>
|