Author: seb
Date: Mon Nov 6 17:43:33 2006
New Revision: 875
Added:
logback/trunk/logback-examples/src/main/java/chapter4/socket/
logback/trunk/logback-examples/src/main/java/chapter4/socket/SocketClient1.java
logback/trunk/logback-examples/src/main/java/chapter4/socket/SocketClient2.java
logback/trunk/logback-examples/src/main/java/chapter4/socket/client1.xml
logback/trunk/logback-examples/src/main/java/chapter4/socket/server1.xml
logback/trunk/logback-examples/src/main/java/chapter4/socket/server2.xml
Modified:
logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java
logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml
logback/trunk/logback-site/src/site/xdocTemplates/manual/index.xml
Log:
on going work on chapter 4
Modified: logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java
(original)
+++ logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java Mon Nov
6 17:43:33 2006
@@ -14,6 +14,7 @@
import java.io.OutputStreamWriter;
import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.WriterAppender;
@@ -22,7 +23,7 @@
public class ExitWoes {
public static void main(String[] args) throws Exception {
- LoggerContext lc = new LoggerContext();
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
WriterAppender writerAppender = new WriterAppender();
writerAppender.setContext(lc);
writerAppender.setLayout(new EchoLayout());
@@ -36,4 +37,4 @@
logger.debug("Hello world.");
}
-}
+}
\ No newline at end of file
Added:
logback/trunk/logback-examples/src/main/java/chapter4/socket/SocketClient1.java
==============================================================================
--- (empty file)
+++
logback/trunk/logback-examples/src/main/java/chapter4/socket/SocketClient1.java
Mon Nov 6 17:43:33 2006
@@ -0,0 +1,76 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ *
+ * Copyright (C) 1999-2006, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it
under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package chapter4.socket;
+
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.net.SocketAppender;
+
+
+/**
+ * This application uses a SocketAppender that log messages to a
+ * server on a host and port specified by the user. It waits for the
+ * user to type a message which will be sent to the server.
+ * */
+public class SocketClient1 {
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SocketClient1.class.getName() +
+ " hostname port\n" + " hostname the name of the remote log server\n" +
+ " port (integer) the port number of the server\n");
+ System.exit(1);
+ }
+
+ static public void main(String[] args) throws Exception {
+ if (args.length != 2) {
+ usage("Wrong number of arguments.");
+ }
+
+ String hostName = args[0];
+ int port = Integer.parseInt(args[1]);
+
+ // Create a SocketAppender connected to hostname:port with a
+ // reconnection delay of 10000 seconds.
+ SocketAppender socketAppender = new SocketAppender();
+ socketAppender.setRemoteHost(hostName);
+ socketAppender.setPort(port);
+ socketAppender.setReconnectionDelay(10000);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ socketAppender.setContext(lc);
+
+ // SocketAppender options become active only after the execution
+ // of the next statement.
+ socketAppender.start();
+
+ Logger logger = LoggerFactory.getLogger(SocketClient1.class);
+ //logger.addAppender(socketAppender);
+
+ BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
+
+ while (true) {
+ System.out.println("Type a message to send to log server at " + hostName
+
+ ":" + port + ". Type 'q' to quit.");
+
+ String s = reader.readLine();
+
+ if (s.equals("q")) {
+ break;
+ } else {
+ logger.debug(s);
+ }
+ }
+ }
+}
Added:
logback/trunk/logback-examples/src/main/java/chapter4/socket/SocketClient2.java
==============================================================================
--- (empty file)
+++
logback/trunk/logback-examples/src/main/java/chapter4/socket/SocketClient2.java
Mon Nov 6 17:43:33 2006
@@ -0,0 +1,70 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ *
+ * Copyright (C) 1999-2006, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it
under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package chapter4.socket;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+
+
+/**
+ * This application uses a SocketAppender that log messages to a
+ * server on a host and port specified by the user. It waits for the
+ * user to type a message which will be sent to the server.
+ * */
+public class SocketClient2 {
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SocketClient1.class.getName() +
+ " configFile\n" +
+ " configFile a logback configuration file" +
+ " in XML format.");
+ System.exit(1);
+ }
+
+ static public void main(String[] args) throws Exception {
+ if (args.length != 1) {
+ usage("Wrong number of arguments.");
+ }
+
+ String configFile = args[0];
+
+ if (configFile.endsWith(".xml")) {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator configurator = new JoranConfigurator();
+ lc.reset();
+ configurator.setContext(lc);
+ configurator.doConfigure(configFile);
+ }
+
+ Logger logger = LoggerFactory.getLogger(SocketClient2.class);
+
+ BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
+
+ while (true) {
+ System.out.println(
+ "Type a message to send to log server. Type 'q' to quit.");
+
+ String s = reader.readLine();
+
+ if (s.equals("q")) {
+ break;
+ } else {
+ logger.debug(s);
+ }
+ }
+ }
+}
Added: logback/trunk/logback-examples/src/main/java/chapter4/socket/client1.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-examples/src/main/java/chapter4/socket/client1.xml
Mon Nov 6 17:43:33 2006
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SocketAppender configuration. -->
+<!-- ==================================================================== -->
+
+<configuration>
+
+ <appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
+ <RemoteHost>${host}</RemoteHost>
+ <Port>${port}</Port>
+ <ReconnectionDelay>10000</ReconnectionDelay>
+ <IncludeCallerData>${includeCallerData}</IncludeCallerData>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="SOCKET" />
+ </root>
+
+</configuration>
+
+
+
Added: logback/trunk/logback-examples/src/main/java/chapter4/socket/server1.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-examples/src/main/java/chapter4/socket/server1.xml
Mon Nov 6 17:43:33 2006
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- This config file is intended to be used by a SocketServer that logs -->
+<!-- events received from various clients on the console and to a file -->
+<!-- that is rolled over when appropriate. The interesting point to note -->
+<!-- is that it is a configuration file like any other. -->
+<!-- ==================================================================== -->
+
+<configuration>
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%d %-5p [%t] %c - %m%n</Pattern>
+ </layout>
+
+ </appender>
+
+ <appender name="ROLLING"
class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <File>rolling.log</File>
+
+ <rollingPolicy
class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <FileNamePattern>rolling.%i.log</FileNamePattern>
+ <MinIndex>1</MinIndex>
+ <MaxIndex>3</MaxIndex>
+ </rollingPolicy>
+
+ <triggeringPolicy
+
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <MaxFileSize>8KB</MaxFileSize>
+ </triggeringPolicy>
+
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%r %-5p %c - %m%n</Pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="CONSOLE" />
+ <appender-ref ref="ROLLING" />
+ </root>
+</configuration>
+
+
+
Added: logback/trunk/logback-examples/src/main/java/chapter4/socket/server2.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-examples/src/main/java/chapter4/socket/server2.xml
Mon Nov 6 17:43:33 2006
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- This config file is intended to be used by a SocketServer that logs -->
+<!-- events received from various clients on the console. The interesting -->
+<!-- point to note is that it is a configuration file like any other. -->
+<!-- ==================================================================== -->
+
+<configuration>
+
+ <!-- Notice the %file and %line patterns in the Pattern. -->
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date %-5level [%thread] [%file:%line] %logger -
%msg%n</Pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="CONSOLE" />
+ </root>
+</configuration>
+
+
+
Modified: logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml
==============================================================================
--- logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml
(original)
+++ logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml
Mon Nov 6 17:43:33 2006
@@ -47,7 +47,8 @@
<p>
Logback delegates the task of writing a logging event
to appenders.
- Appenders must imple-ment the
<code>ch.qos.logback.core.Appender</code> interface.
+ Appenders must implement the
+ <a
href="../xref/ch/qos/logback/core/Appender.html"><code>ch.qos.logback.core.Appender</code></a>
interface.
The salient methods of this interface are summarized
below:
</p>
<div class="source"><pre>package ch.qos.logback.core;
@@ -96,7 +97,8 @@
<h2>AppenderBase</h2>
<p>
- The <code>ch.qos.logback.core.AppenderSkeleton</code> class is
an abstract
+ The <a href="../xref/ch/qos/logback/core/AppenderBase.html">
+ <code>ch.qos.logback.core.AppenderBase</code></a> class is an
abstract
class implementing the <code>Appender</code> interface.
It provides basic functionality shared by all appenders,
such as methods for getting or setting their name, their
started status,
@@ -211,7 +213,7 @@
<h3>WriterAppender</h3>
<p>
- <code>WriterAppender</code> appends events to a
<code>java.io.Writer</code>.
+ <a
href="../xref/ch/qos/logback/core/WriterAppender.html"><code>WriterAppender</code></a>
appends events to a <code>java.io.Writer</code>.
This class provides basic services that other appenders build
upon.
Users do not usually instantiate <code>WriterAppender</code>
objects directly.
Since <code>java.io.Writer</code> type cannot be mapped to a
string, there is no
@@ -267,8 +269,7 @@
will be lost as illustrated by the next example.
</p>
- <em>Example 4.1: Exiting an application without flushing
(logback-examples/src/main/java/chapter4/
- <a href="../xref/chapter4/ExitWoes.html">ExitWoes.java</a>)</em>
+ <em>Example 4.1: Exiting an application without flushing (<a
href="../xref/chapter4/ExitWoes.html">logback-examples/src/main/java/chapter4/ExitWoes.java</a>)</em>
<div class="source"><pre>package chapter4;
import java.io.FileOutputStream;
@@ -280,15 +281,15 @@
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.WriterAppender;
-import ch.qos.logback.core.layout.DummyLayout;
+import ch.qos.logback.core.layout.EchoLayout;
public class ExitWoes {
public static void main(String[] args) throws Exception {
- LoggerContext lc = new LoggerContext();
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
WriterAppender writerAppender = new WriterAppender();
writerAppender.setContext(lc);
- writerAppender.setLayout(new DummyLayout());
+ writerAppender.setLayout(new EchoLayout());
OutputStream os = new FileOutputStream("exitWoes1.log");
writerAppender.setWriter(new OutputStreamWriter(os));
@@ -314,12 +315,11 @@
running <code>ExitWoes1</code> will not produce any output in
the file
<em>exitWoes1.log</em>
because the Java VM does not flush output streams when it
exits.
- Calling the <code>shutdown()</code> method of a <b>XXXXXX</b>
ensures that all
+ Calling the <code>reset()</code> method of a
<code>LoggerContext</code> ensures that all
appenders in the hierarchy are closed and their buffers are
flushed.
For most applications this is as simple as including the
following statement
before exiting the application.
</p>
- <p>WHAT TO DO IN LB ???</p>
<p>
The <code>WriterAppender</code> is the super class of four
other appenders,
@@ -333,7 +333,8 @@
<h3>ConsoleAppender</h3>
<p>
- The <code>ConsoleAppender</code>, as the name indicates,
appends on the console,
+ The <a href="../xref/ch/qos/logback/core/ConsoleAppender.html">
+ <code>ConsoleAppender</code></a>, as the name indicates,
appends on the console,
or more precisely on <em>System.out</em> or
<em>System.err</em>, the former
being the default target. <code>ConsoleAppender</code> formats
events with
a layout specified by the user. Both <em>System.out</em> and
<em>System.err</em>
@@ -371,7 +372,8 @@
<h3>FileAppender</h3>
<p>
- The <code>FileAppender</code>, a subclass of
<code>WriterAppender</code>,
+ The <a
href="../xref/ch/qos/logback/core/FileAppender.html"><code>FileAppender</code></a>,
+ a subclass of <code>WriterAppender</code>,
appends log events into a file. The file to write to is
specified by
the <span class="option">File</span> option.
If the file already exists, it is either appended to, or
truncated
@@ -464,7 +466,8 @@
<h3>RollingFileAppender</h3>
<p>
- <code>RollingFileAppender</code> extends
<code>FileAppender</code> by
+ <a
href="../xref/ch/qos/logback/core/rolling/RollingFileAppender.html"><code>RollingFileAppender</code></a>
+ extends <code>FileAppender</code> by
allowing rolling from a log file to another. For example,
<code>RollingFileAppender</code> can log to a <em>log.txt</em>
file and,
once a certain condition is met, change its logging target to
another file.
@@ -546,7 +549,8 @@
<h3>Rolling policies</h3>
- <p><code>RollingPolicy</code> implementations are responsible for the
+ <p><a
href="../xref/ch/qos/logback/core/rolling/RollingPolicy.html"><code>RollingPolicy</code></a>
+ implementations are responsible for the
procedure of the rollover. They manage file renaming and sometimes
deleting.</p>
<p>The <code>RollingPolicy</code> interface is rather simple:</p>
@@ -575,7 +579,8 @@
<h4>FixedWindowRollingPolicy</h4>
<p>
- When rolling over, <code>FixedWindowRollingPolicy</code>
+ When rolling over, <a
href="../xref/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.html">
+ <code>FixedWindowRollingPolicy</code></a>
renames files according to a fixed window algorithm as
described below.
</p>
<p>
@@ -787,7 +792,8 @@
<a name="TimeBasedRollingPolicy" />
<h4>TimeBasedRollingPolicy</h4>
<p>
- <code>TimeBasedRollingPolicy</code> is both easy to configure
and quite powerful.
+ <a
href="../xref/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.html">
+ <code>TimeBasedRollingPolicy</code></a> is both easy to
configure and quite powerful.
It allows the rollover to be made based on time conditions. It
is possible to specify
that the rollover must occur each day, or month, for example.
</p>
@@ -1017,7 +1023,8 @@
<a name="TriggeringPolicy"/>
<h3>Triggering policies</h3>
- <p><code>TriggeringPolicy</code> implementations are
responsible for instructing
+ <p><a
href="../xref/ch/qos/logback/core/rolling/TriggeringPolicy.html"><code>TriggeringPolicy</code></a>
+ implementations are responsible for instructing
the <code>RollingFileAppender</code> to proceed to the
rollover.</p>
<p>The <code>TriggeringPolicy</code> interface is pretty
simple.</p>
@@ -1045,7 +1052,8 @@
<h4>SizeBasedTriggeringPolicy</h4>
<p>
- <code>SizeBasedTriggeringPolicy</code>
+ <a
href="../xref/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.html">
+ <code>SizeBasedTriggeringPolicy</code></a>
looks at size of the file being currently written to.
If it
grows bigger than the specified size, the
<code>FileAppender</code> using the
@@ -1108,21 +1116,286 @@
<code>SMTPAppender</code>, which will be covered soon,
when to send an email
containing the last logging events.
</p>
+
+ <p>
+ In that case, the <code>isTriggeringEvent()</code>
method takes <em>null</em>
+ as its first parameter (of type <code>File</code>) and
takes the logging event
+ as its second parameter. It is based on that last
element that the decision is
+ made to send the email or not. By default, a
<code>TriggeringPolicy</code> is
+ included with <code>SMTPAppender</code> that triggers
the mail each time an event
+ with a <code>Level</code> of <em>ERROR</em> or more is
issued.
+ </p>
+ <a name="Classic"/>
+ <h2>Logback Classic</h2>
+
+ <p><b>Keep this??</b>While logging event are declared as
<code>Object</code> in logback core,
+ they are instances of the <code>LoggingEvent</code> class in
logback classic.</p>
+
+ <a name="SocketAppender" />
+ <h3>SockerAppender</h3>
+
+ <p>
+ The appenders covered this far were only able to log to
local resources.
+ In contrast, the <a
href="../xref/ch/qos/logback/classic/net/SocketAppender.html">
+ <code>SocketAppender</code></a> is designed to log to a
+ remote entity by transmitting serialized LoggingEvent
objects over the wire.
+ Remote logging is non-intrusive as far as the logging
event is concerned.
+ On the receiving end after de-serialization, the event
can be logged as
+ if it were generated locally. Multiple
<code>SocketAppender</code> instances
+ running of different machines can direct their logging
output
+ to a central log server. <code>SocketAppender</code>
does not admit an
+ associated layout because it sends serialized events to
a remote server.
+ <code>SocketAppender</code> operates above the
+ <em>Transmission Control Protocol (TCP)</em>
+ layer which provides a reliable, sequenced,
flow-controlled end-to-end octet stream.
+ Consequently, if the remote server is reachable, then
log events
+ will eventually arrive there. Otherwise, if the remote
server is down or
+ unreachable, the logging events will simply be dropped.
If and when the server
+ comes back up, then event transmission will be resumed
transparently.
+ This transparent reconnection is performed by a
connector thread which
+ periodically attempts to connect to the server.
+ </p>
+
+ <p>
+ Logging events are automatically buffered by the native
TCP implementation.
+ This means that if the link to server is slow but still
faster than the
+ rate of event production by the client, the client will
not be affected by
+ the slow network connection. However, if the network
connection is slower
+ then the rate of event production, then the client can
only progress at the
+ network rate. In particular, in the extreme case where
the network link
+ to the server is down, the client will be eventually
blocked.
+ Alternatively, if the network link is up, but the
server is down,
+ the client will not be blocked although the log events
will be
+ lost due to server unavailability.
+ </p>
+
+ <p>
+ Even if a <code>SocketAppender</code> is no longer
attached to any logger,
+ it will not be garbage collected in the presence of a
connector thread.
+ A connector thread exists only if the connection to the
server is down.
+ To avoid this garbage collection problem, you should
close the <code>SocketAppender</code>
+ explicitly. Long lived applications which
create/destroy many
+ <code>SocketAppender</code> instances should be aware
of this
+ garbage collection problem. Most other applications can
safely ignore it.
+ If the JVM hosting the <code>SocketAppender</code>
exits before the
+ <code>SocketAppender</code> is closed, either
explicitly or subsequent
+ to garbage collection, then there might be
untransmitted data in the
+ pipe which may be lost. This is a common problem on
Windows based systems.
+ To avoid lost data, it is usually sufficient to
<code>close()</code> the
+ <code>SocketAppender</code> either explicitly or by
calling the
+ <code>LoggerContext</code>'s <code>reset()</code>
method before exiting the application.
+ </p>
+
+ <p>
+ The remote server is identified by the <span
class="option">RemoteHost</span> and
+ <span class="option">Port</span> options.
+ <code>SocketAppender</code> options are listed in the
following table.
+ </p>
+ <table>
+ <tr>
+ <th>Option Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><b><span
class="option">IncludeCallerData</span></b></td>
+ <td><code>boolean</code></td>
+ <td>
+ <p>
+ The <span
class="option">IncludeCallerData</span> option takes a boolean value.
+ If true, the caller data will be
available to the remote host.
+ By default no caller data is sent to
the server.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><b><span class="option">Port</span></b></td>
+ <td><code>int</code></td>
+ <td>
+ <p>
+ The port number of the remote server.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><b><span
class="option">ReconnectionDelay</span></b></td>
+ <td><code>int</code></td>
+ <td>
+ The <span
class="option">ReconnectionDelay</span> option takes a
+ positive integer representing the
number of milliseconds to wait between
+ each failed connection attempt to the
server.
+ The default value of this option is
30'000 which corresponds to 30 seconds.
+ Setting this option to zero turns off
reconnection capability.
+ Note that in case of successful
connection to the server, there will be no
+ connector thread present.
+ </td>
+ </tr>
+ <tr>
+ <td><b><span class="option">RemoteHost</span></b></td>
+ <td><code>String</code></td>
+ <td>
+ The host name of the server.
+ </td>
+ </tr>
+ </table>
+
+ <p>
+ The standard logback distribution includes a simple log server
application named
+ <code>ch.qos.logback.classic.net.SimpleSocketServer</code> that
can service multiple
+ <code>SocketAppender</code> clients. It waits for logging
events from
+ <code>SocketAppender</code> clients. After reception by
+ <code>SimpleSocketServer</code>, the events are logged
according to local server policy.
+ The <code>SimpleSocketServer</code> application takes two
parameters:
+ port and configFile; where port is the port to listen on and
configFile is
+ configuration script in XML format.
+ </p>
+
+ <p>
+ Assuming you are in the
<em>logback-examples/target/classes/</em> directory,
+ start <code>SimpleSocketServer</code> with the following
command:
+ </p>
+
+<div class="source"><pre> java ch.qos.logback.classic.net.SimpleSocketServer
6000 \
+ chapter4/socket/server1.xml
+</pre></div>
+ <p>
+ where 6000 is the port number to listen on and
<em>server1.xml</em> is a
+ configuration script that adds a <code>ConsoleAppender</code>
and a
+ <code>RollingFileAppender</code> to the root logger.
+ After you have started <code>SimpleSocketServer</code>, you can
send it
+ log events from multiple clients using
<code>SocketAppender</code>.
+ The examples associated with this manual include two such
clients:
+ <code>chapter4.SocketClient1</code> and
<code>chapter4.SocketClient2</code>
+ Both clients wait for the user to type a line of text on the
console.
+ The text is encapsulated in a logging event of level debug and
then sent
+ to the remote server. The two clients differ in the
configuration of the
+ <code>SocketAppender</code>. <code>SocketClient1</code>
configures the appender
+ programmatically while <code>SocketClient2</code> requires a
configuration file.
+ </p>
+
+ <p>
+ Assuming <code>SimpleSocketServer</code> is running on the
local host,
+ you connect to it with the following command:
+ </p>
+
+<div class="source"><pre>java chapter4.socket.SocketClient1 localhost
6000</pre></div>
+ <p>
+ Each line that you type should appear on the console of
the
+ <code>SimpleSocketServer</code>
+ launched in the previous step. If you stop and restart
the
+ <code>SimpleSocketServer</code>
+ the client will transparently reconnect to the new
server
+ instance, although the events generated while
disconnected
+ will be simply and irrevocably lost.
+ </p>
+ <p>
+ Unlike
+ <code>SocketClient1</code>, the sample application
+ <code>SocketClient2</code> does not configure logback
by itself.
+ It requires a configuration file in XML format.
+ The configuration file <em>client1.xml</em>
+ shown below creates a <code>SocketAppender</code>
+ and attaches it to the root logger.
+ </p>
+ <em>Example 4.1: SocketAppender configuration (<a
href="../xref/chapter4/socket/client1.html">logback-examples/src/main/java/chapter4/socket/client1.xml</a>)</em>
+<div class="source"><pre><configuration>
+
+ <appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
+ <RemoteHost>${host}</RemoteHost>
+ <Port>${port}</Port>
+ <ReconnectionDelay>10000</ReconnectionDelay>
+ </appender>
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="SOCKET" />
+ </root>
+</configuration></pre></div>
+
+
+ <p>
+ Note that in the above configuration scripts the values
for the
+ <span class="option">RemoteHost</span>, <span
class="option">Port</span> and
+ <span class="option">IncludeCallerData</span> options
+ are not given directly but as substituted variable
keys. The values for the variables
+ can be specified as system properties:
+ </p>
+
+<div class="source"><pre>java -Dhost=localhost -Dport=6000
-DincludeCallerData=false \
+ chapter4.socket.SocketClient2 chapter4/socket/client1.xml
+</pre></div>
+ <p>
+ This command should give similar results to the previous
+ <code>SocketClient1</code>
+ example.
+ </p>
+
+ <p>
+ Allow us to repeat for emphasis that serialization of
logging events is not
+ intrusive. A de-serialized event carries the same
information as any other
+ logging event. It can be manipulated as if it were
generated locally;
+ except that serialized logging events by default do not
include location
+ information. Here is an example to illustrate the
point. First, start
+ <code>SimpleSocketServer</code> with the following
command:
+ </p>
- <h2>Logback Classic</h2>
-
- <h2>Logback Access</h2>
+<div class="source"><pre> java ch.qos.logback.classic.net.SimpleSocketServer
6000 \
+ chapter4/socket/server2.xml
+</pre></div>
+
+ <p>
+ The configuration file <em>server2.xml</em> creates a
<code>ConsoleAppender</code>
+ whose layout outputs the callers file name and line
number along with other
+ information. If you run <code>SocketClient2</code> with
the configuration file
+ <em>client1.xml</em> as previously, you will notice
that the output on the
+ server side will contain two question marks between
parentheses instead of
+ the file name and the line number of the caller:
+ </p>
+
+<div class="source"><pre>2006-11-06 17:37:30,968 DEBUG [Thread-0] [?:?]
chapter4.socket.SocketClient2 - Hi</pre></div>
+
+ <p>
+ The outcome can be easily changed by instructing the
<code>SocketAppender</code>
+ to include caller data by setting the <span
class="option">IncludeCallerData</span>
+ option to true. Using the following command will do the
trick:
+ </p>
+
+<div class="source"><pre>java -Dhost=localhost -Dport=6000
-DincludeCallerData=true \
+ chapter4.socket.SocketClient2 chapter4/socket/client1.xml
+</pre></div>
+
+ <p>
+ As deserialized events can be handled in the same way
as locally
+ generated events, they even can be sent to a second
server for further treatment.
+ As an exercise, you may wish to setup two servers where
the first server
+ tunnels the events it receives from its clients to a
second server.
+ </p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Logback Access</h2>
Modified: logback/trunk/logback-site/src/site/xdocTemplates/manual/index.xml
==============================================================================
--- logback/trunk/logback-site/src/site/xdocTemplates/manual/index.xml
(original)
+++ logback/trunk/logback-site/src/site/xdocTemplates/manual/index.xml Mon Nov
6 17:43:33 2006
@@ -38,6 +38,11 @@
page size</em> enabled, or <a
href="http://www.opera.com">Opera</a>.
</p>
+ <p>
+ To run the examples provided in this book, you might have
+ to add the logback jars to your classpath. They are available
+ on our <a href="../download.html">download page</a>.
+ </p>
</div>
<p>The logback manual describes the logback API in considerable
_______________________________________________
logback-dev mailing list
[email protected]
http://qos.ch/mailman/listinfo/logback-dev