[logback-dev] svn commit: r875 - in logback/trunk: logback-examples/src/main/java/chapter4 logback-examples/src/main/java/chapter4/socket logback-site/src/site/xdocTemplates/manual

noreply.seb at qos.ch noreply.seb at qos.ch
Mon Nov 6 17:43:33 CET 2006


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>&lt;configuration>
+	  
+  &lt;appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
+    &lt;RemoteHost>${host}&lt;/RemoteHost>
+    &lt;Port>${port}&lt;/Port>
+    &lt;ReconnectionDelay>10000&lt;/ReconnectionDelay>
+  &lt;/appender>
 
+  &lt;root>
+    &lt;level value ="debug"/>
+    &lt;appender-ref ref="SOCKET" />
+  &lt;/root>  
 
+&lt;/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



More information about the logback-dev mailing list