logback-dev
Threads by month
- ----- 2025 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
September 2006
- 8 participants
- 123 discussions

svn commit: r609 - in logback/trunk/logback-access/src: main/java/ch/qos/logback/access/jetty main/java/ch/qos/logback/access/spi test/java/ch/qos/logback/access/jetty
by noreply.seb@qos.ch 28 Sep '06
by noreply.seb@qos.ch 28 Sep '06
28 Sep '06
Author: seb
Date: Thu Sep 28 12:28:07 2006
New Revision: 609
Modified:
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java
Log:
- modified RequestLogImpl javadoc
- AccessEvent now remembers if the postContent has already been accessed
- updated tests
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java Thu Sep 28 12:28:07 2006
@@ -39,6 +39,17 @@
* Layouts are declared the exact same way. However, loggers elements are not
* allowed.
* <p>
+ * It is possible to put the logback configuration file anywhere, as long as it's path is
+ * specified. Here is another example, with a path to the logback.xml file.
+ * <pre>
+ * <Ref id="requestLog">
+ * <Set name="requestLog">
+ * <New id="requestLogImpl" class="ch.qos.logback.access.jetty.RequestLogImpl"></New>
+ * <Set name="fileName">path/to/logback.xml</Set>
+ * </Set>
+ * </Ref>
+ * </pre>
+ * <p>
* Here is a sample logback.xml file that can be used right away:
* <pre>
* <configuration>
@@ -51,6 +62,9 @@
* <appender-ref ref="STDOUT" />
* </configuration>
* </pre>
+ *
+ *
+ * <p>
* A special, module-specific implementation of PatternLayout was implemented to allow
* http-specific patterns to be used. The {@link ch.qos.logback.access.PatternLayout} provides
* a way to format the logging output that is just as easy and flexible as the usual
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java Thu Sep 28 12:28:07 2006
@@ -11,6 +11,15 @@
import ch.qos.logback.access.pattern.AccessConverter;
+/**
+ * The Access module's internal representation of logging events. When the
+ * RequestLogImpl instance is called to log then a <code>AccessEvent</code>
+ * instance is created. This instance is passed around to the different logback
+ * components.
+ *
+ * @author Ceki Gülcü
+ * @author Sébastien Pennec
+ */
public class AccessEvent implements Serializable {
private static final long serialVersionUID = -3118194368414470960L;
@@ -29,6 +38,7 @@
String protocol;
String method;
String serverName;
+ String postContent;
Map<String, Object> requestHeaderMap;
@@ -280,17 +290,20 @@
}
public String getPostContent() {
- String content = null;
+ if (postContent != null) {
+ return postContent;
+ }
+
try {
- content = Util.readToString(httpRequest.getInputStream());
+ postContent = Util.readToString(httpRequest.getInputStream());
} catch (Exception ex) {
// do nothing
}
- if (content != null && content.length() > 0) {
- return content;
- } else {
- return NA;
+ if (postContent == null || postContent.length() == 0) {
+ postContent = NA;
}
+
+ return postContent;
}
public int getLocalPort() {
Modified: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java
==============================================================================
--- logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java (original)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java Thu Sep 28 12:28:07 2006
@@ -1,6 +1,5 @@
package ch.qos.logback.access.jetty;
-
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
@@ -15,57 +14,81 @@
import ch.qos.logback.core.appender.ListAppender;
public class JettyBasicTest extends TestCase {
-
+
static RequestLogImpl requestLogImpl;
-
+
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(JettyBasicTest.class);
requestLogImpl = new RequestLogImpl();
return new JettyTestSetup(suite, requestLogImpl);
}
-
-// public void testGetRequest() throws Exception {
-// URL url = new URL("http://localhost:8080/");
-// HttpURLConnection connection = (HttpURLConnection)url.openConnection();
-// connection.setDoInput(true);
-//
-// String result = Util.readToString(connection.getInputStream());
-//
-// assertEquals("hello world", result);
-//
-// ListAppender appender = (ListAppender)requestLogImpl.getAppender("list");
-// appender.list.clear();
-// }
-
+
+ public void testGetRequest() throws Exception {
+ URL url = new URL("http://localhost:8080/");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setDoInput(true);
+
+ String result = Util.readToString(connection.getInputStream());
+
+ assertEquals("hello world", result);
+
+ ListAppender appender = (ListAppender) requestLogImpl.getAppender("list");
+ appender.list.clear();
+ }
+
+ public void testEventGoesToAppenders() throws Exception {
+ URL url = new URL("http://localhost:8080/");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setDoInput(true);
+
+ String result = Util.readToString(connection.getInputStream());
+
+ assertEquals("hello world", result);
+
+ ListAppender appender = (ListAppender) requestLogImpl.getAppender("list");
+ AccessEvent event = (AccessEvent) appender.list.get(0);
+ assertEquals("127.0.0.1", event.getRemoteHost());
+ assertEquals("localhost", event.getServerName());
+ appender.list.clear();
+ }
+
public void testPostContentConverter() throws Exception {
System.out.println("into test");
URL url = new URL("http://localhost:8080/");
- HttpURLConnection connection = (HttpURLConnection)url.openConnection();
- ((HttpURLConnection)connection).setRequestMethod("POST");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ ((HttpURLConnection) connection).setRequestMethod("POST");
+
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "text/plain");
-
+ // connection.setRequestProperty("Content-Type",
+ // "application/x-www-form-urlencoded");
+
String msg = "test message";
- PrintWriter output = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()));
+ PrintWriter output = new PrintWriter(new OutputStreamWriter(connection
+ .getOutputStream()));
output.print(msg);
output.flush();
output.close();
-
+ // System.out.println("length: " + connection.getContentLength());
+
+ // Reading the response
String result = Util.readToString(connection.getInputStream());
+ assertEquals("hello world", result);
+
+ // StatusPrinter.print(requestLogImpl.getStatusManager());
+
+ ListAppender listAppender = (ListAppender) requestLogImpl
+ .getAppender("list");
+ AccessEvent event = (AccessEvent) listAppender.list.get(0);
+ assertEquals(msg, event.getPostContent());
- ListAppender appender = (ListAppender)requestLogImpl.getAppender("list");
- //assertEquals(1, appender.list.size());
- Iterator it = appender.list.iterator();
- int i = 0;
- while(it.hasNext()) {
- AccessEvent event = (AccessEvent)it.next();
- System.out.println(i++ + ": " + event.getPostContent());
+ Iterator it = listAppender.list.iterator();
+ while (it.hasNext()) {
+ AccessEvent event2 = (AccessEvent) it.next();
+ System.out.println("Event PostContent: " + event2.getPostContent());
}
- //System.out.println("0: " + event.getPostContent());
-
}
-
}
Modified: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java
==============================================================================
--- logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java (original)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java Thu Sep 28 12:28:07 2006
@@ -27,7 +27,6 @@
public class JettyTestSetup extends TestSetup {
- ListAppender appender;
RequestLogImpl requestLogImpl;
public JettyTestSetup(Test suite, RequestLogImpl impl) {
@@ -68,32 +67,30 @@
System.out.println("into tearDown");
super.tearDown();
server.stop();
-// Thread.sleep(1000);
-// server = null;
-// appender = null;
-// requestLogImpl = null;
+ Thread.sleep(1000);
+ server = null;
+ requestLogImpl = null;
}
private void buildContext() {
- appender = new ListAppender();
+ ListAppender appender = new ListAppender();
appender.setContext(requestLogImpl);
appender.setName("list");
appender.start();
-// ConsoleAppender console = new ConsoleAppender();
-// console.setContext(requestLogImpl);
-// console.setName("console");
-// PatternLayout layout = new PatternLayout();
-// layout.setContext(requestLogImpl);
-// layout
-// .setPattern("%date %server %remoteIP %clientHost %user %requestURL %post");
-// console.setLayout(layout);
-// layout.start();
-// console.start();
+ ConsoleAppender console = new ConsoleAppender();
+ console.setContext(requestLogImpl);
+ console.setName("console");
+ PatternLayout layout = new PatternLayout();
+ layout.setContext(requestLogImpl);
+ layout.setPattern("%date %server %clientHost %post");
+ console.setLayout(layout);
+ layout.start();
+ console.start();
- //requestLogImpl.addAppender(console);
requestLogImpl.addAppender(appender);
+ requestLogImpl.addAppender(console);
}
}
@@ -103,6 +100,9 @@
HttpServletResponse response, int dispatch) throws IOException,
ServletException {
+ // String requestContent = Util.readToString(request.getInputStream());
+ // System.out.println("request content: " + requestContent);
+
OutputStream out = response.getOutputStream();
ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer();
writer.write("hello world");
1
0

svn commit: r608 - in logback/trunk/logback-access/src: main/java/ch/qos/logback/access main/java/ch/qos/logback/access/jetty main/java/ch/qos/logback/access/pattern main/java/ch/qos/logback/access/spi test/java/ch/qos/logback/access/jetty
by noreply.seb@qos.ch 27 Sep '06
by noreply.seb@qos.ch 27 Sep '06
27 Sep '06
Author: seb
Date: Wed Sep 27 16:17:35 2006
New Revision: 608
Added:
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/PostContentConverter.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java
Modified:
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java
Log:
Work in progress:
- added a PostContentConverter
- created a test case and test setup to create and launch a Jetty server
- added a getPostContent method to AccessEvent
- added the corresponding pattern to PatternLayout
- added javadoc to RequestLogImpl
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java Wed Sep 27 16:17:35 2006
@@ -17,6 +17,7 @@
import ch.qos.logback.access.pattern.LineSeparatorConverter;
import ch.qos.logback.access.pattern.LocalIPAddressConverter;
import ch.qos.logback.access.pattern.NAConverter;
+import ch.qos.logback.access.pattern.PostContentConverter;
import ch.qos.logback.access.pattern.RemoteHostConverter;
import ch.qos.logback.access.pattern.RemoteIPAddressConverter;
import ch.qos.logback.access.pattern.RemoteUserConverter;
@@ -49,8 +50,6 @@
defaultConverterMap.put("b", ContentLengthConverter.class.getName());
defaultConverterMap.put("B", ContentLengthConverter.class.getName());
defaultConverterMap.put("bytesSent", ContentLengthConverter.class.getName());
-
-
defaultConverterMap.put("h", RemoteHostConverter.class.getName());
defaultConverterMap.put("clientHost", RemoteHostConverter.class.getName());
@@ -85,6 +84,9 @@
defaultConverterMap.put("v", ServerNameConverter.class.getName());
defaultConverterMap.put("server", ServerNameConverter.class.getName());
+ defaultConverterMap.put("p", PostContentConverter.class.getName());
+ defaultConverterMap.put("post", PostContentConverter.class.getName());
+
}
public PatternLayout() {
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java Wed Sep 27 16:17:35 2006
@@ -31,5 +31,4 @@
public String getResponseHeader(String key) {
return response.getHeader(key);
}
-
}
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java Wed Sep 27 16:17:35 2006
@@ -16,7 +16,51 @@
import ch.qos.logback.core.status.ErrorStatus;
import ch.qos.logback.core.util.StatusPrinter;
-
+/**
+ * This class is logback's implementation of jetty's RequestLog interface.
+ * <p>
+ * It can be seen as logback classic's LoggerContext. Appenders can be attached
+ * directly to RequestLogImpl and RequestLogImpl uses the same StatusManager as
+ * LoggerContext does. It also provides containers for properties.
+ * <p>
+ * To configure jetty in order to use RequestLogImpl, the following lines must
+ * be added to the jetty configuration file:
+ * <pre>
+ * <Ref id="requestLog">
+ * <Set name="requestLog">
+ * <New id="requestLogImpl" class="ch.qos.logback.access.jetty.RequestLogImpl"></New>
+ * </Set>
+ * </Ref>
+ * </pre>
+ * By default, RequestLogImpl looks for a logback configuration file called
+ * logback.xml, in the same folder where jetty.xml is located, that is
+ * /etc/logback.xml. The logback.xml file is slightly different than the usual
+ * logback classic configuration file. Most of it is the same: Appenders and
+ * Layouts are declared the exact same way. However, loggers elements are not
+ * allowed.
+ * <p>
+ * Here is a sample logback.xml file that can be used right away:
+ * <pre>
+ * <configuration>
+ * <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ * <layout class="ch.qos.logback.access.PatternLayout">
+ * <param name="Pattern" value="%date %server %remoteIP %clientHost %user %requestURL %post" />
+ * </layout>
+ * </appender>
+ *
+ * <appender-ref ref="STDOUT" />
+ * </configuration>
+ * </pre>
+ * A special, module-specific implementation of PatternLayout was implemented to allow
+ * http-specific patterns to be used. The {@link ch.qos.logback.access.PatternLayout} provides
+ * a way to format the logging output that is just as easy and flexible as the usual
+ * PatternLayout.
+ * For more information about the general use of a PatternLayout, please refer to logback
+ * classic's {@link ch.qos.logback.classic.PatternLayout}. For information about logback
+ * access' specific PatternLayout, please refer to it's javadoc.
+ *
+ * @author Ceki Gülcü
+ */
public class RequestLogImpl extends ContextBase implements RequestLog,
AppenderAttachable {
@@ -27,8 +71,10 @@
String filename;
public void log(Request jettyRequest, Response jettyResponse) {
- JettyServerAdapter adapter = new JettyServerAdapter(jettyRequest, jettyResponse);
- AccessEvent accessEvent = new AccessEvent(jettyRequest, jettyResponse, adapter);
+ JettyServerAdapter adapter = new JettyServerAdapter(jettyRequest,
+ jettyResponse);
+ AccessEvent accessEvent = new AccessEvent(jettyRequest, jettyResponse,
+ adapter);
// TODO better exception handling
aai.appendLoopOnAppenders(accessEvent);
}
@@ -51,18 +97,18 @@
StatusPrinter.print(getStatusManager());
} else {
getStatusManager().add(
- new ErrorStatus("["+filename+"] does not exist", this));
+ new ErrorStatus("[" + filename + "] does not exist", this));
}
}
public void stop() throws Exception {
- System.out.println("RequestLogImpl-stop called");
+ // System.out.println("RequestLogImpl-stop called");
aai.detachAndStopAllAppenders();
}
public boolean isRunning() {
- System.out.println("RequestLogImpl-isRunning called");
+ // System.out.println("RequestLogImpl-isRunning called");
return false;
}
@@ -71,22 +117,22 @@
}
public boolean isStarted() {
- System.out.println("RequestLogImpl-isStarted called");
+ // System.out.println("RequestLogImpl-isStarted called");
return true;
}
public boolean isStarting() {
- System.out.println("RequestLogImpl-isStarting called");
+ // System.out.println("RequestLogImpl-isStarting called");
return false;
}
public boolean isStopping() {
- System.out.println("RequestLogImpl-isStopping called");
+ // System.out.println("RequestLogImpl-isStopping called");
return false;
}
public boolean isFailed() {
- System.out.println("RequestLogImpl-isFailed called");
+ // System.out.println("RequestLogImpl-isFailed called");
return false;
}
Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/PostContentConverter.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/PostContentConverter.java Wed Sep 27 16:17:35 2006
@@ -0,0 +1,12 @@
+package ch.qos.logback.access.pattern;
+
+import ch.qos.logback.access.spi.AccessEvent;
+
+public class PostContentConverter extends AccessConverter {
+
+ @Override
+ protected String convert(AccessEvent accessEvent) {
+ return accessEvent.getPostContent();
+ }
+
+}
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java Wed Sep 27 16:17:35 2006
@@ -279,6 +279,20 @@
return statusCode;
}
+ public String getPostContent() {
+ String content = null;
+ try {
+ content = Util.readToString(httpRequest.getInputStream());
+ } catch (Exception ex) {
+ // do nothing
+ }
+ if (content != null && content.length() > 0) {
+ return content;
+ } else {
+ return NA;
+ }
+ }
+
public int getLocalPort() {
if (localPort == SENTINEL) {
if (httpRequest != null) {
Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java Wed Sep 27 16:17:35 2006
@@ -0,0 +1,20 @@
+package ch.qos.logback.access.spi;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Util {
+
+ public static String readToString(InputStream in) throws IOException {
+ StringBuffer sb = new StringBuffer();
+ BufferedReader inbr = new BufferedReader(new InputStreamReader(in));
+ String line;
+ while ((line = inbr.readLine()) != null) {
+ sb.append(line);
+ }
+
+ return sb.toString();
+ }
+}
Added: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java Wed Sep 27 16:17:35 2006
@@ -0,0 +1,71 @@
+package ch.qos.logback.access.jetty;
+
+
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Iterator;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import ch.qos.logback.access.spi.AccessEvent;
+import ch.qos.logback.access.spi.Util;
+import ch.qos.logback.core.appender.ListAppender;
+
+public class JettyBasicTest extends TestCase {
+
+ static RequestLogImpl requestLogImpl;
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(JettyBasicTest.class);
+ requestLogImpl = new RequestLogImpl();
+ return new JettyTestSetup(suite, requestLogImpl);
+ }
+
+// public void testGetRequest() throws Exception {
+// URL url = new URL("http://localhost:8080/");
+// HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+// connection.setDoInput(true);
+//
+// String result = Util.readToString(connection.getInputStream());
+//
+// assertEquals("hello world", result);
+//
+// ListAppender appender = (ListAppender)requestLogImpl.getAppender("list");
+// appender.list.clear();
+// }
+
+ public void testPostContentConverter() throws Exception {
+ System.out.println("into test");
+ URL url = new URL("http://localhost:8080/");
+ HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+ ((HttpURLConnection)connection).setRequestMethod("POST");
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ connection.setUseCaches(false);
+ connection.setRequestProperty("Content-Type", "text/plain");
+
+ String msg = "test message";
+ PrintWriter output = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()));
+ output.print(msg);
+ output.flush();
+ output.close();
+
+ String result = Util.readToString(connection.getInputStream());
+
+ ListAppender appender = (ListAppender)requestLogImpl.getAppender("list");
+ //assertEquals(1, appender.list.size());
+ Iterator it = appender.list.iterator();
+ int i = 0;
+ while(it.hasNext()) {
+ AccessEvent event = (AccessEvent)it.next();
+ System.out.println(i++ + ": " + event.getPostContent());
+ }
+ //System.out.println("0: " + event.getPostContent());
+
+ }
+
+}
Added: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java Wed Sep 27 16:17:35 2006
@@ -0,0 +1,119 @@
+package ch.qos.logback.access.jetty;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Handler;
+import org.mortbay.jetty.HttpConnection;
+import org.mortbay.jetty.Request;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.AbstractHandler;
+import org.mortbay.jetty.handler.ContextHandler;
+import org.mortbay.jetty.handler.RequestLogHandler;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.util.ByteArrayISO8859Writer;
+
+import ch.qos.logback.access.PatternLayout;
+import ch.qos.logback.core.ConsoleAppender;
+import ch.qos.logback.core.appender.ListAppender;
+
+public class JettyTestSetup extends TestSetup {
+
+ ListAppender appender;
+ RequestLogImpl requestLogImpl;
+
+ public JettyTestSetup(Test suite, RequestLogImpl impl) {
+ super(suite);
+ requestLogImpl = impl;
+ }
+
+ Server server;
+ String url = "http://localhost:8080/";
+
+ public void setUp() throws Exception {
+ System.out.println("into setUp");
+ super.setUp();
+
+ server = new Server();
+ Connector connector = new SelectChannelConnector();
+ connector.setPort(8080);
+ server.setConnectors(new Connector[] { connector });
+
+ ContextHandler context = new ContextHandler();
+ context.setContextPath("/");
+ context.setResourceBase(".");
+ context.setClassLoader(Thread.currentThread().getContextClassLoader());
+ server.addHandler(context);
+
+ RequestLogHandler requestLogHandler = new RequestLogHandler();
+ buildContext();
+ requestLogHandler.setRequestLog(requestLogImpl);
+ server.addHandler(requestLogHandler);
+
+ Handler handler = new BasicHandler();
+ context.addHandler(handler);
+
+ server.start();
+ }
+
+ public void tearDown() throws Exception {
+ System.out.println("into tearDown");
+ super.tearDown();
+ server.stop();
+// Thread.sleep(1000);
+// server = null;
+// appender = null;
+// requestLogImpl = null;
+ }
+
+ private void buildContext() {
+
+ appender = new ListAppender();
+ appender.setContext(requestLogImpl);
+ appender.setName("list");
+ appender.start();
+
+// ConsoleAppender console = new ConsoleAppender();
+// console.setContext(requestLogImpl);
+// console.setName("console");
+// PatternLayout layout = new PatternLayout();
+// layout.setContext(requestLogImpl);
+// layout
+// .setPattern("%date %server %remoteIP %clientHost %user %requestURL %post");
+// console.setLayout(layout);
+// layout.start();
+// console.start();
+
+ //requestLogImpl.addAppender(console);
+ requestLogImpl.addAppender(appender);
+ }
+
+}
+
+class BasicHandler extends AbstractHandler {
+ public void handle(String target, HttpServletRequest request,
+ HttpServletResponse response, int dispatch) throws IOException,
+ ServletException {
+
+ OutputStream out = response.getOutputStream();
+ ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer();
+ writer.write("hello world");
+ writer.flush();
+ response.setContentLength(writer.size());
+ writer.writeTo(out);
+ out.flush();
+
+ Request base_request = (request instanceof Request) ? (Request) request
+ : HttpConnection.getCurrentConnection().getRequest();
+ base_request.setHandled(true);
+
+ }
+}
\ No newline at end of file
1
0

svn commit: r607 - in logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db: . dialect
by noreply.seb@qos.ch 26 Sep '06
by noreply.seb@qos.ch 26 Sep '06
26 Sep '06
Author: seb
Date: Tue Sep 26 18:14:59 2006
New Revision: 607
Added:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2.sql
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2l.sql
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/hsqldb.sql
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mssql.sql
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mysql.sql
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/oracle.sql
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/postgresql.sql
Log:
- Created DBAppenderBase, and modified DBAppender accordingly
- Moved classes to Core module when possible.
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,60 @@
+/**
+ * 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 ch.qos.logback.core.db;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import ch.qos.logback.core.spi.LifeCycle;
+
+
+/**
+ * The <id>ConnectionSource</id> interface provides a pluggable means of
+ * transparently obtaining JDBC {@link java.sql.Connection}s for logback classes
+ * that require the use of a {@link java.sql.Connection}.
+ *
+ * @author <a href="mailto:rdecampo@twcny.rr.com">Ray DeCampo</a>
+ */
+public interface ConnectionSource extends LifeCycle {
+
+ final int UNKNOWN_DIALECT = 0;
+ final int POSTGRES_DIALECT = 1;
+ final int MYSQL_DIALECT = 2;
+ final int ORACLE_DIALECT = 3;
+ final int MSSQL_DIALECT = 4;
+ final int HSQL_DIALECT = 5;
+ /**
+ * Obtain a {@link java.sql.Connection} for use. The client is
+ * responsible for closing the {@link java.sql.Connection} when it is no
+ * longer required.
+ *
+ * @throws SQLException if a {@link java.sql.Connection} could not be
+ * obtained
+ */
+ Connection getConnection() throws SQLException;
+
+ /**
+ * Get the SQL dialect that should be used for this connection. Note that the
+ * dialect is not needed if the JDBC driver supports the getGeneratedKeys
+ * method.
+ */
+ int getSQLDialectCode();
+
+ /**
+ * If the connection supports the JDBC 3.0 getGeneratedKeys method, then
+ * we do not need any specific dialect support.
+ */
+ boolean supportsGetGeneratedKeys();
+
+ /**
+ * If the connection does not support batch updates, we will avoid using them.
+ */
+ public boolean supportsBatchUpdates();
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,119 @@
+/**
+ * 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 ch.qos.logback.core.db;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import ch.qos.logback.core.db.dialect.DBUtil;
+import ch.qos.logback.core.spi.ContextAwareBase;
+
+
+/**
+ * @author Ceki Gülcü
+ */
+public abstract class ConnectionSourceBase extends ContextAwareBase implements ConnectionSource {
+
+ private boolean started;
+
+ private String user = null;
+ private String password = null;
+
+ // initially we have an unkonw dialect
+ private int dialectCode = UNKNOWN_DIALECT;
+ private boolean supportsGetGeneratedKeys = false;
+ private boolean supportsBatchUpdates = false;
+
+
+ /**
+ * Learn relevant information about this connection source.
+ *
+ */
+ public void discoverConnnectionProperties() {
+ try {
+ Connection connection = getConnection();
+ if (connection == null) {
+ addWarn("Could not get a connection");
+ return;
+ }
+ DatabaseMetaData meta = connection.getMetaData();
+ DBUtil util = new DBUtil();
+ util.setContext(getContext());
+ supportsGetGeneratedKeys = util.supportsGetGeneratedKeys(meta);
+ supportsBatchUpdates = util.supportsBatchUpdates(meta);
+ dialectCode = DBUtil.discoverSQLDialect(meta);
+ } catch (SQLException se) {
+ addWarn("Could not discover the dialect to use.", se);
+ }
+ }
+
+ /**
+ * Does this connection support the JDBC Connection.getGeneratedKeys method?
+ */
+ public final boolean supportsGetGeneratedKeys() {
+ return supportsGetGeneratedKeys;
+ }
+
+ public final int getSQLDialectCode() {
+ return dialectCode;
+ }
+
+ /**
+ * Get the password for this connection source.
+ */
+ public final String getPassword() {
+ return password;
+ }
+
+ /**
+ * Sets the password.
+ * @param password The password to set
+ */
+ public final void setPassword(final String password) {
+ this.password = password;
+ }
+
+ /**
+ * Get the user for this connection source.
+ */
+ public final String getUser() {
+ return user;
+ }
+
+ /**
+ * Sets the username.
+ * @param username The username to set
+ */
+ public final void setUser(final String username) {
+ this.user = username;
+ }
+
+ /**
+ * Does this connection support batch updates?
+ */
+ public final boolean supportsBatchUpdates() {
+ return supportsBatchUpdates;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void start() {
+ started = true;
+ }
+
+ public void stop() {
+ started = false;
+ }
+
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,261 @@
+/**
+ * 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 ch.qos.logback.core.db;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.Layout;
+import ch.qos.logback.core.db.dialect.DBUtil;
+import ch.qos.logback.core.db.dialect.SQLDialect;
+
+/**
+ * @author Ceki Gülcü
+ * @author Ray DeCampo
+ * @author Sébastien Pennec
+ */
+public abstract class DBAppenderBase extends AppenderBase {
+ protected static final String insertPropertiesSQL = "INSERT INTO logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
+ protected static final String insertExceptionSQL = "INSERT INTO logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)";
+ protected static final String insertSQL;
+ protected static final Method GET_GENERATED_KEYS_METHOD;
+
+ static {
+ StringBuffer sql = new StringBuffer();
+ sql.append("INSERT INTO logging_event (");
+ sql.append("timestmp, ");
+ sql.append("formatted_message, ");
+ sql.append("logger_name, ");
+ sql.append("level_string, ");
+ sql.append("thread_name, ");
+ sql.append("reference_flag, ");
+ sql.append("caller_filename, ");
+ sql.append("caller_class, ");
+ sql.append("caller_method, ");
+ sql.append("caller_line) ");
+ sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?,?)");
+ insertSQL = sql.toString();
+ //
+ // PreparedStatement.getGeneratedKeys added in JDK 1.4
+ //
+ Method getGeneratedKeysMethod;
+ try {
+ getGeneratedKeysMethod = PreparedStatement.class.getMethod(
+ "getGeneratedKeys", (Class[]) null);
+ } catch (Exception ex) {
+ getGeneratedKeysMethod = null;
+ }
+ GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
+ }
+
+ protected ConnectionSource connectionSource;
+ protected boolean cnxSupportsGetGeneratedKeys = false;
+ protected boolean cnxSupportsBatchUpdates = false;
+ protected SQLDialect sqlDialect;
+
+ public DBAppenderBase() {
+ }
+
+ @Override
+ public void start() {
+
+ if (connectionSource == null) {
+ throw new IllegalStateException(
+ "DBAppender cannot function without a connection source");
+ }
+
+ sqlDialect = DBUtil
+ .getDialectFromCode(connectionSource.getSQLDialectCode());
+ if (GET_GENERATED_KEYS_METHOD != null) {
+ cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys();
+ } else {
+ cnxSupportsGetGeneratedKeys = false;
+ }
+ cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates();
+ if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) {
+ throw new IllegalStateException(
+ "DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect");
+ }
+
+ // all nice and dandy on the eastern front
+ super.start();
+ }
+
+ /**
+ * @return Returns the connectionSource.
+ */
+ public ConnectionSource getConnectionSource() {
+ return connectionSource;
+ }
+
+ /**
+ * @param connectionSource
+ * The connectionSource to set.
+ */
+ public void setConnectionSource(ConnectionSource connectionSource) {
+ this.connectionSource = connectionSource;
+ }
+
+ @Override
+ public void append(Object eventObject) {
+ // LoggingEvent event = (LoggingEvent) eventObject;
+ Connection connection = null;
+ try {
+ connection = connectionSource.getConnection();
+ connection.setAutoCommit(false);
+
+ PreparedStatement insertStatement = connection
+ .prepareStatement(insertSQL);
+
+ subAppend(eventObject, connection, insertStatement);
+
+ // we no longer need the insertStatement
+ if (insertStatement != null) {
+ insertStatement.close();
+ insertStatement = null;
+ }
+
+ connection.commit();
+ } catch (Throwable sqle) {
+ addError("problem appending event", sqle);
+ } finally {
+ DBHelper.closeConnection(connection);
+ }
+ }
+
+ protected abstract void subAppend(Object eventObject, Connection connection,
+ PreparedStatement statement) throws Throwable;
+
+ protected int getEventId(PreparedStatement insertStatement,
+ Connection connection) throws SQLException, InvocationTargetException {
+ ResultSet rs = null;
+ Statement idStatement = null;
+ boolean gotGeneratedKeys = false;
+ if (cnxSupportsGetGeneratedKeys) {
+ try {
+ rs = (ResultSet) GET_GENERATED_KEYS_METHOD.invoke(insertStatement,
+ (Object[]) null);
+ gotGeneratedKeys = true;
+ } catch (InvocationTargetException ex) {
+ Throwable target = ex.getTargetException();
+ if (target instanceof SQLException) {
+ throw (SQLException) target;
+ }
+ throw ex;
+ } catch (IllegalAccessException ex) {
+ addWarn(
+ "IllegalAccessException invoking PreparedStatement.getGeneratedKeys",
+ ex);
+ }
+ }
+
+ if (!gotGeneratedKeys) {
+ insertStatement.close();
+ insertStatement = null;
+
+ idStatement = connection.createStatement();
+ idStatement.setMaxRows(1);
+ rs = idStatement.executeQuery(sqlDialect.getSelectInsertId());
+ }
+
+ // A ResultSet cursor is initially positioned before the first row;
+ // the
+ // first call to the method next makes the first row the current row
+ rs.next();
+ int eventId = rs.getInt(1);
+
+ rs.close();
+
+ if (idStatement != null) {
+ idStatement.close();
+ idStatement = null;
+ }
+
+ return eventId;
+ }
+
+ protected void insertProperties(Map<String, String> mergedMap,
+ Connection connection, int eventId) throws SQLException {
+ Set propertiesKeys = mergedMap.keySet();
+ if (propertiesKeys.size() > 0) {
+ PreparedStatement insertPropertiesStatement = connection
+ .prepareStatement(insertPropertiesSQL);
+
+ for (Iterator i = propertiesKeys.iterator(); i.hasNext();) {
+ String key = (String) i.next();
+ String value = (String) mergedMap.get(key);
+
+ insertPropertiesStatement.setInt(1, eventId);
+ insertPropertiesStatement.setString(2, key);
+ insertPropertiesStatement.setString(3, value);
+
+ if (cnxSupportsBatchUpdates) {
+ insertPropertiesStatement.addBatch();
+ } else {
+ insertPropertiesStatement.execute();
+ }
+ }
+
+ if (cnxSupportsBatchUpdates) {
+ insertPropertiesStatement.executeBatch();
+ }
+
+ insertPropertiesStatement.close();
+ insertPropertiesStatement = null;
+ }
+ }
+
+ protected void insertThrowable(String[] strRep, Connection connection,
+ int eventId) throws SQLException {
+
+ PreparedStatement insertExceptionStatement = connection
+ .prepareStatement(insertExceptionSQL);
+
+ for (short i = 0; i < strRep.length; i++) {
+ insertExceptionStatement.setInt(1, eventId);
+ insertExceptionStatement.setShort(2, i);
+ insertExceptionStatement.setString(3, strRep[i]);
+ if (cnxSupportsBatchUpdates) {
+ insertExceptionStatement.addBatch();
+ } else {
+ insertExceptionStatement.execute();
+ }
+ }
+ if (cnxSupportsBatchUpdates) {
+ insertExceptionStatement.executeBatch();
+ }
+ insertExceptionStatement.close();
+ insertExceptionStatement = null;
+
+ }
+
+ @Override
+ public void stop() {
+ super.stop();
+ }
+
+ public Layout getLayout() {
+ return null;
+ }
+
+ public void setLayout(Layout layout) {
+ }
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,42 @@
+/**
+ * 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 ch.qos.logback.core.db;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * @author Ceki Gülcü
+ *
+ */
+public class DBHelper {
+
+ static public void closeConnection(Connection connection) {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException sqle) {
+ // static utility classes should not log without an explicit repository
+ // reference
+ }
+ }
+ }
+
+ public static void closeStatement(Statement statement) {
+ if (statement != null) {
+ try {
+ statement.close();
+ } catch (SQLException sqle) {
+ }
+ }
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,78 @@
+/**
+ * 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 ch.qos.logback.core.db;
+
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.sql.DataSource;
+
+
+/**
+ * The DataSourceConnectionSource is an implementation of {@link ConnectionSource}
+ * that obtains the Connection in the recommended JDBC manner based on
+ * a {@link javax.sql.DataSource DataSource}.
+ * <p>
+ *
+ * @author Ray DeCampo
+ * @author Ceki Gülcü
+ */
+public class DataSourceConnectionSource extends ConnectionSourceBase {
+
+ private DataSource dataSource;
+
+ @Override
+ public void start() {
+ //LogLog.debug("**********DataSourceConnectionSource.activateOptions called");
+ if (dataSource == null) {
+ addWarn("WARNING: No data source specified");
+ } else {
+ Connection connection = null;
+ try {
+ connection = getConnection();
+ } catch(SQLException se) {
+ addWarn("Could not get a connection to discover the dialect to use.", se);
+ }
+ if(connection != null) {
+ discoverConnnectionProperties();
+ }
+ if(!supportsGetGeneratedKeys() && getSQLDialectCode() == ConnectionSource.UNKNOWN_DIALECT) {
+ addWarn("Connection does not support GetGeneratedKey method and could not discover the dialect.");
+ }
+ }
+ super.start();
+ }
+
+ /**
+ * @see ch.qos.logback.classic.db.ConnectionSource#getConnection()
+ */
+ public Connection getConnection() throws SQLException {
+ if (dataSource == null) {
+ addError("WARNING: No data source specified");
+ return null;
+ }
+
+ if (getUser() == null) {
+ return dataSource.getConnection();
+ } else {
+ return dataSource.getConnection(getUser(), getPassword());
+ }
+ }
+
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ public void setDataSource(DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,129 @@
+/**
+ * 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 ch.qos.logback.core.db;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+/**
+ * The DriverManagerConnectionSource is an implementation of
+ * {@link ConnectionSource} that obtains the Connection in the traditional JDBC
+ * manner based on the connection URL.
+ * <p>
+ * Note that this class will establish a new Connection for each call to
+ * {@link #getConnection()}. It is recommended that you either use a JDBC
+ * driver that natively supported Connection pooling or that you create your own
+ * implementation of {@link ConnectionSource} that taps into whatever pooling
+ * mechanism you are already using. (If you have access to a JNDI implementation
+ * that supports {@link javax.sql.DataSource}s, e.g. within a J2EE application
+ * server, see {@link JNDIConnectionSource}). See <a href="#dbcp">below</a>
+ * for a configuration example that uses the <a
+ * href="http://jakarta.apache.org/commons/dbcp/index.html">commons-dbcp</a>
+ * package from Apache.
+ * <p>
+ * Sample configuration:<br>
+ *
+ * <pre>
+ * <connectionSource class="org.apache.log4j.jdbc.DriverManagerConnectionSource">
+ * <param name="driver" value="com.mysql.jdbc.Driver" />
+ * <param name="url" value="jdbc:mysql://localhost:3306/mydb" />
+ * <param name="username" value="myUser" />
+ * <param name="password" value="myPassword" />
+ * </connectionSource>
+ * </pre>
+ *
+ * <p>
+ * <a name="dbcp">If</a> you do not have another connection pooling mechanism
+ * built into your application, you can use the <a
+ * href="http://jakarta.apache.org/commons/dbcp/index.html">commons-dbcp</a>
+ * package from Apache:<br>
+ *
+ * <pre>
+ * <connectionSource class="org.apache.log4j.jdbc.DriverManagerConnectionSource">
+ * <param name="driver" value="org.apache.commons.dbcp.PoolingDriver" />
+ * <param name="url" value="jdbc:apache:commons:dbcp:/myPoolingDriver" />
+ * </connectionSource>
+ * </pre>
+ *
+ * Then the configuration information for the commons-dbcp package goes into the
+ * file myPoolingDriver.jocl and is placed in the classpath. See the <a
+ * href="http://jakarta.apache.org/commons/dbcp/index.html">commons-dbcp</a>
+ * documentation for details.
+ *
+ * @author <a href="mailto:rdecampo@twcny.rr.com">Ray DeCampo</a>
+ */
+public class DriverManagerConnectionSource extends ConnectionSourceBase {
+ private String driverClass = null;
+ private String url = null;
+
+ public void start() {
+ try {
+ if (driverClass != null) {
+ Class.forName(driverClass);
+ discoverConnnectionProperties();
+ } else {
+ addError("WARNING: No JDBC driver specified for logback DriverManagerConnectionSource.");
+ }
+ } catch (final ClassNotFoundException cnfe) {
+ addError("Could not load JDBC driver class: " + driverClass, cnfe);
+ }
+ }
+
+ /**
+ * @see ch.qos.logback.classic.db.ConnectionSource#getConnection()
+ */
+ public Connection getConnection() throws SQLException {
+ if (getUser() == null) {
+ return DriverManager.getConnection(url);
+ } else {
+ return DriverManager.getConnection(url, getUser(), getPassword());
+ }
+ }
+
+ /**
+ * Returns the url.
+ *
+ * @return String
+ */
+ public String getUrl() {
+ return url;
+ }
+
+ /**
+ * Sets the url.
+ *
+ * @param url
+ * The url to set
+ */
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ /**
+ * Returns the name of the driver class.
+ *
+ * @return String
+ */
+ public String getDriverClass() {
+ return driverClass;
+ }
+
+ /**
+ * Sets the driver class.
+ *
+ * @param driverClass
+ * The driver class to set
+ */
+ public void setDriverClass(String driverClass) {
+ this.driverClass = driverClass;
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,140 @@
+/**
+ * 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 ch.qos.logback.core.db;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+// PortableRemoteObject was introduced in JDK 1.3. We won't use it.
+// import javax.rmi.PortableRemoteObject;
+import javax.sql.DataSource;
+
+/**
+ * The <id>JNDIConnectionSource</id> is an implementation of
+ * {@link ConnectionSource} that obtains a {@link javax.sql.DataSource} from a
+ * JNDI provider and uses it to obtain a {@link java.sql.Connection}. It is
+ * primarily designed to be used inside of J2EE application servers or
+ * application server clients, assuming the application server supports remote
+ * access of {@link javax.sql.DataSource}s. In this way one can take advantage
+ * of connection pooling and whatever other goodies the application server
+ * provides.
+ * <p>
+ * Sample configuration:<br>
+ *
+ * <pre>
+ * <connectionSource class="org.apache.log4j.jdbc.JNDIConnectionSource">
+ * <param name="jndiLocation" value="jdbc/MySQLDS" />
+ * </connectionSource>
+ * </pre>
+ *
+ * <p>
+ * Sample configuration (with username and password):<br>
+ *
+ * <pre>
+ * <connectionSource class="org.apache.log4j.jdbc.JNDIConnectionSource">
+ * <param name="jndiLocation" value="jdbc/MySQLDS" />
+ * <param name="username" value="myUser" />
+ * <param name="password" value="myPassword" />
+ * </connectionSource>
+ * </pre>
+ *
+ * <p>
+ * Note that this class will obtain an {@link javax.naming.InitialContext} using
+ * the no-argument constructor. This will usually work when executing within a
+ * J2EE environment. When outside the J2EE environment, make sure that you
+ * provide a jndi.properties file as described by your JNDI provider's
+ * documentation.
+ *
+ * @author <a href="mailto:rdecampo@twcny.rr.com">Ray DeCampo</a>
+ */
+public class JNDIConnectionSource extends ConnectionSourceBase {
+ private String jndiLocation = null;
+ private DataSource dataSource = null;
+
+ /**
+ * @see org.apache.log4j.spi.OptionHandler#activateOptions()
+ */
+ public void start() {
+ if (jndiLocation == null) {
+ addError("No JNDI location specified for JNDIConnectionSource.");
+ }
+
+ discoverConnnectionProperties();
+
+ }
+
+ /**
+ * @see org.apache.log4j.db.ConnectionSource#getConnection()
+ */
+ public Connection getConnection() throws SQLException {
+ Connection conn = null;
+ try {
+
+ if (dataSource == null) {
+ dataSource = lookupDataSource();
+ }
+ if (getUser() == null) {
+ conn = dataSource.getConnection();
+ } else {
+ conn = dataSource.getConnection(getUser(), getPassword());
+ }
+ } catch (final NamingException ne) {
+ addError("Error while getting data source", ne);
+ throw new SQLException("NamingException while looking up DataSource: "
+ + ne.getMessage());
+ } catch (final ClassCastException cce) {
+ addError("ClassCastException while looking up DataSource.", cce);
+ throw new SQLException("ClassCastException while looking up DataSource: "
+ + cce.getMessage());
+ }
+
+ return conn;
+ }
+
+ /**
+ * Returns the jndiLocation.
+ *
+ * @return String
+ */
+ public String getJndiLocation() {
+ return jndiLocation;
+ }
+
+ /**
+ * Sets the jndiLocation.
+ *
+ * @param jndiLocation
+ * The jndiLocation to set
+ */
+ public void setJndiLocation(String jndiLocation) {
+ this.jndiLocation = jndiLocation;
+ }
+
+ private DataSource lookupDataSource() throws NamingException, SQLException {
+ DataSource ds;
+ Context ctx = new InitialContext();
+ Object obj = ctx.lookup(jndiLocation);
+
+ // PortableRemoteObject was introduced in JDK 1.3. We won't use it.
+ // ds = (DataSource)PortableRemoteObject.narrow(obj, DataSource.class);
+ ds = (DataSource) obj;
+
+ if (ds == null) {
+ throw new SQLException("Failed to obtain data source from JNDI location "
+ + jndiLocation);
+ } else {
+ return ds;
+ }
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,118 @@
+/**
+ * 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 ch.qos.logback.core.db.dialect;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import ch.qos.logback.core.db.ConnectionSource;
+import ch.qos.logback.core.spi.ContextAwareBase;
+
+/**
+ *
+ * @author Ceki Gulcu
+ *
+ */
+public class DBUtil extends ContextAwareBase {
+ private static final String POSTGRES_PART = "postgresql";
+ private static final String MYSQL_PART = "mysql";
+ private static final String ORACLE_PART = "oracle";
+ // private static final String MSSQL_PART = "mssqlserver4";
+ private static final String MSSQL_PART = "microsoft";
+ private static final String HSQL_PART = "hsql";
+
+ public static int discoverSQLDialect(DatabaseMetaData meta) {
+ int dialectCode = 0;
+
+ try {
+
+ String dbName = meta.getDatabaseProductName().toLowerCase();
+
+ if (dbName.indexOf(POSTGRES_PART) != -1) {
+ return ConnectionSource.POSTGRES_DIALECT;
+ } else if (dbName.indexOf(MYSQL_PART) != -1) {
+ return ConnectionSource.MYSQL_DIALECT;
+ } else if (dbName.indexOf(ORACLE_PART) != -1) {
+ return ConnectionSource.ORACLE_DIALECT;
+ } else if (dbName.indexOf(MSSQL_PART) != -1) {
+ return ConnectionSource.MSSQL_DIALECT;
+ } else if (dbName.indexOf(HSQL_PART) != -1) {
+ return ConnectionSource.HSQL_DIALECT;
+ } else {
+ return ConnectionSource.UNKNOWN_DIALECT;
+ }
+ } catch (SQLException sqle) {
+ // we can't do much here
+ }
+
+ return dialectCode;
+ }
+
+ public static SQLDialect getDialectFromCode(int dialectCode) {
+ SQLDialect sqlDialect = null;
+
+ switch (dialectCode) {
+ case ConnectionSource.POSTGRES_DIALECT:
+ sqlDialect = new PostgreSQLDialect();
+
+ break;
+ case ConnectionSource.MYSQL_DIALECT:
+ sqlDialect = new MySQLDialect();
+
+ break;
+ case ConnectionSource.ORACLE_DIALECT:
+ sqlDialect = new OracleDialect();
+
+ break;
+ case ConnectionSource.MSSQL_DIALECT:
+ sqlDialect = new MsSQLDialect();
+
+ break;
+ case ConnectionSource.HSQL_DIALECT:
+ sqlDialect = new HSQLDBDialect();
+
+ break;
+ }
+ return sqlDialect;
+ }
+
+ /**
+ * This method handles cases where the
+ * {@link DatabaseMetaData#supportsGetGeneratedKeys} method is missing in the
+ * JDBC driver implementation.
+ */
+ public boolean supportsGetGeneratedKeys(DatabaseMetaData meta) {
+ try {
+ //
+ // invoking JDK 1.4 method by reflection
+ //
+ return ((Boolean) DatabaseMetaData.class.getMethod(
+ "supportsGetGeneratedKeys", (Class[]) null).invoke(meta,
+ (Object[]) null)).booleanValue();
+ } catch (Throwable e) {
+ addInfo("Could not call supportsGetGeneratedKeys method. This may be recoverable");
+ return false;
+ }
+ }
+
+ /**
+ * This method handles cases where the
+ * {@link DatabaseMetaData#supportsBatchUpdates} method is missing in the JDBC
+ * driver implementation.
+ */
+ public boolean supportsBatchUpdates(DatabaseMetaData meta) {
+ try {
+ return meta.supportsBatchUpdates();
+ } catch (Throwable e) {
+ addInfo("Missing DatabaseMetaData.supportsBatchUpdates method.");
+ return false;
+ }
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,23 @@
+/**
+ * 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 ch.qos.logback.core.db.dialect;
+
+/**
+ * The HSQLDB dialect.
+ *
+ * @author Ceki Gülcü
+*/
+public class HSQLDBDialect implements SQLDialect {
+ public static final String SELECT_CURRVAL = "CALL IDENTITY()";
+
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,27 @@
+/**
+ * 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 ch.qos.logback.core.db.dialect;
+
+/**
+* The MS SQL Server dialect is untested.
+*
+* Note that the dialect is not needed if your JDBC driver supports
+* the getGeneratedKeys method introduced in JDBC 3.0 specification.
+*
+* @author James Stauffer
+*/
+public class MsSQLDialect implements SQLDialect {
+ public static final String SELECT_CURRVAL = "SELECT @@identity id";
+
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,24 @@
+/**
+ * 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 ch.qos.logback.core.db.dialect;
+
+/**
+ *
+ *
+ * @author Ceki
+ *
+ */
+public class MySQLDialect implements SQLDialect {
+ public static final String SELECT_LAST_INSERT_ID = "SELECT LAST_INSERT_ID()";
+
+ public String getSelectInsertId() {
+ return SELECT_LAST_INSERT_ID;
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,26 @@
+/**
+ * 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 ch.qos.logback.core.db.dialect;
+
+/**
+ * The Oracle dialect. Tested successfully on Oracle9i Release 9.2.0.3.0 by
+ * James Stauffer.
+ *
+ * @author Ceki Gülcü
+ */
+public class OracleDialect implements SQLDialect {
+ public static final String SELECT_CURRVAL = "SELECT logging_event_id_seq.currval from dual";
+
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,28 @@
+/**
+ * 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 ch.qos.logback.core.db.dialect;
+
+
+/**
+ *
+ * @author ceki
+ *
+ * To change the template for this generated type comment go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+public class PostgreSQLDialect
+ implements SQLDialect {
+ public static final String SELECT_CURRVAL = "SELECT currval('logging_event_id_seq')";
+
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java Tue Sep 26 18:14:59 2006
@@ -0,0 +1,20 @@
+/**
+ * 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 ch.qos.logback.core.db.dialect;
+
+/**
+ * @author ceki
+ *
+ */
+public interface SQLDialect {
+
+ public String getSelectInsertId();
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2.sql Tue Sep 26 18:14:59 2006
@@ -0,0 +1,48 @@
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+#
+# It is intended for IBM DB2 databases.
+#
+# WARNING WARNING WARNING WARNING
+# =================================
+# This SQL script has not been tested on an actual DB2
+# instance. It may contain errors or even invalid SQL
+# statements.
+
+DROP TABLE logging_event_property;
+DROP TABLE logging_event_exception;
+DROP TABLE logging_event;
+
+CREATE TABLE logging_event
+ (
+ sequence_number BIGINT NOT NULL,
+ timestamp BIGINT NOT NULL,
+ rendered_message VARCHAR(4000) NOT NULL,
+ logger_name VARCHAR(254) NOT NULL,
+ level_string VARCHAR(254) NOT NULL,
+ ndc VARCHAR(4000),
+ thread_name VARCHAR(254),
+ reference_flag SMALLINT,
+ caller_filename VARCHAR(254) NOT NULL,
+ caller_class VARCHAR(254) NOT NULL,
+ caller_method VARCHAR(254) NOT NULL,
+ caller_line CHAR(4) NOT NULL,
+ event_id INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 1)
+ );
+
+CREATE TABLE logging_event_property
+ (
+ event_id INTEGER NOT NULL,
+ mapped_key VARCHAR(254) NOT NULL,
+ mapped_value VARCHAR(1024),
+ PRIMARY KEY(event_id, mapped_key),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
+
+CREATE TABLE logging_event_exception
+ (
+ event_id INTEGER NOT NULL,
+ i SMALLINT NOT NULL,
+ trace_line VARCHAR(254) NOT NULL,
+ PRIMARY KEY(event_id, i),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2l.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/db2l.sql Tue Sep 26 18:14:59 2006
@@ -0,0 +1,46 @@
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+#
+# It is intended for PostgreSQL databases.
+
+DROP TABLE logging_event_property;
+DROP TABLE logging_event_exception;
+DROP TABLE logging_event;
+
+
+CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START 1;
+
+
+CREATE TABLE logging_event
+ (
+ sequence_number BIGINT NOT NULL,
+ timestamp BIGINT NOT NULL,
+ rendered_message TEXT NOT NULL,
+ logger_name VARCHAR(254) NOT NULL,
+ level_string VARCHAR(254) NOT NULL,
+ ndc TEXT,
+ thread_name VARCHAR(254),
+ reference_flag SMALLINT,
+ caller_filename VARCHAR(254) NOT NULL,
+ caller_class VARCHAR(254) NOT NULL,
+ caller_method VARCHAR(254) NOT NULL,
+ caller_line CHAR(4) NOT NULL,
+ event_id INT IDENTITY GENERATED ALWAYS PRIMARY KEY
+ );
+
+CREATE TABLE logging_event_property
+ (
+ event_id INT NOT NULL,
+ mapped_key VARCHAR(254) NOT NULL,
+ mapped_value VARCHAR(1024),
+ PRIMARY KEY(event_id, mapped_key),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
+
+CREATE TABLE logging_event_exception
+ (
+ event_id INT NOT NULL,
+ i SMALLINT NOT NULL,
+ trace_line VARCHAR(254) NOT NULL,
+ PRIMARY KEY(event_id, i),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/hsqldb.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/hsqldb.sql Tue Sep 26 18:14:59 2006
@@ -0,0 +1,44 @@
+// This SQL script creates the required tables by
+// ch.qos.logback.classic.db.DBAppender.
+//
+// It is intended for HSQLDB.
+//
+
+DROP TABLE logging_event_exception IF EXISTS;
+DROP TABLE logging_event_property IF EXISTS;
+DROP TABLE logging_event IF EXISTS;
+
+
+CREATE TABLE logging_event
+ (
+ timestmp BIGINT NOT NULL,
+ formatted_message LONGVARCHAR NOT NULL,
+ logger_name VARCHAR(256) NOT NULL,
+ level_string VARCHAR(256) NOT NULL,
+ thread_name VARCHAR(256),
+ reference_flag SMALLINT,
+ caller_filename VARCHAR(256),
+ caller_class VARCHAR(256),
+ caller_method VARCHAR(256),
+ caller_line CHAR(4),
+ event_id INT NOT NULL IDENTITY
+ );
+
+
+CREATE TABLE logging_event_property
+ (
+ event_id INT NOT NULL,
+ mapped_key VARCHAR(254) NOT NULL,
+ mapped_value LONGVARCHAR,
+ PRIMARY KEY(event_id, mapped_key),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
+
+CREATE TABLE logging_event_exception
+ (
+ event_id INT NOT NULL,
+ i SMALLINT NOT NULL,
+ trace_line VARCHAR(256) NOT NULL,
+ PRIMARY KEY(event_id, i),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mssql.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mssql.sql Tue Sep 26 18:14:59 2006
@@ -0,0 +1,44 @@
+-- This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+--
+-- It is intended for MS SQL Server databases. This has been tested with version 7.0.
+
+DROP TABLE logging_event_property
+DROP TABLE logging_event_exception
+DROP TABLE logging_event
+
+CREATE TABLE logging_event
+ (
+ sequence_number DECIMAL(20) NOT NULL,
+ timestamp DECIMAL(20) NOT NULL,
+ rendered_message VARCHAR(4000) NOT NULL,
+ logger_name VARCHAR(254) NOT NULL,
+ level_string VARCHAR(254) NOT NULL,
+ ndc VARCHAR(4000),
+ thread_name VARCHAR(254),
+ reference_flag SMALLINT,
+ caller_filename VARCHAR(254) NOT NULL,
+ caller_class VARCHAR(254) NOT NULL,
+ caller_method VARCHAR(254) NOT NULL,
+ caller_line CHAR(4) NOT NULL,
+ event_id INT NOT NULL identity,
+ PRIMARY KEY(event_id)
+ )
+
+CREATE TABLE logging_event_property
+ (
+ event_id INT NOT NULL,
+ mapped_key VARCHAR(254) NOT NULL,
+ mapped_value VARCHAR(1024),
+ PRIMARY KEY(event_id, mapped_key),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ )
+
+CREATE TABLE logging_event_exception
+ (
+ event_id INT NOT NULL,
+ i SMALLINT NOT NULL,
+ trace_line VARCHAR(254) NOT NULL,
+ PRIMARY KEY(event_id, i),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ )
+
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mysql.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/mysql.sql Tue Sep 26 18:14:59 2006
@@ -0,0 +1,51 @@
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender.
+#
+# It is intended for MySQL databases. It has been tested on MySQL 5.0.22 with
+# INNODB tables.
+
+
+BEGIN;
+DROP TABLE IF EXISTS logging_event_property;
+DROP TABLE IF EXISTS logging_event_exception;
+DROP TABLE IF EXISTS logging_event;
+COMMIT;
+
+
+BEGIN;
+CREATE TABLE logging_event
+ (
+ timestmp BIGINT NOT NULL,
+ formatted_message TEXT NOT NULL,
+ logger_name VARCHAR(254) NOT NULL,
+ level_string VARCHAR(254) NOT NULL,
+ thread_name VARCHAR(254),
+ reference_flag SMALLINT,
+ caller_filename VARCHAR(254) NOT NULL,
+ caller_class VARCHAR(254) NOT NULL,
+ caller_method VARCHAR(254) NOT NULL,
+ caller_line CHAR(4) NOT NULL,
+ event_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
+ );
+COMMIT;
+
+BEGIN;
+CREATE TABLE logging_event_property
+ (
+ event_id INT NOT NULL,
+ mapped_key VARCHAR(254) NOT NULL,
+ mapped_value TEXT,
+ PRIMARY KEY(event_id, mapped_key),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
+COMMIT;
+
+BEGIN;
+CREATE TABLE logging_event_exception
+ (
+ event_id INT NOT NULL,
+ i SMALLINT NOT NULL,
+ trace_line VARCHAR(254) NOT NULL,
+ PRIMARY KEY(event_id, i),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
+COMMIT;
\ No newline at end of file
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/oracle.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/oracle.sql Tue Sep 26 18:14:59 2006
@@ -0,0 +1,66 @@
+-- This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+--
+-- It is intended for Oracle databases.
+
+-- Tested successfully on Oracle9i Release 9.2.0.3.0 by James Stauffer
+
+-- The following lines are useful in cleaning any previous tables
+
+--drop TRIGGER logging_event_id_seq_trig;
+--drop SEQUENCE logging_event_id_seq;
+--drop table logging_event_property;
+--drop table logging_event_exception;
+--drop table logging_event;
+
+
+CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START WITH 1;
+
+CREATE TABLE logging_event
+ (
+ sequence_number NUMBER(20) NOT NULL,
+ timestamp NUMBER(20) NOT NULL,
+ rendered_message VARCHAR2(4000) NOT NULL,
+ logger_name VARCHAR2(254) NOT NULL,
+ level_string VARCHAR2(254) NOT NULL,
+ ndc VARCHAR2(4000),
+ thread_name VARCHAR2(254),
+ reference_flag SMALLINT,
+ caller_filename VARCHAR2(254) NOT NULL,
+ caller_class VARCHAR2(254) NOT NULL,
+ caller_method VARCHAR2(254) NOT NULL,
+ caller_line CHAR(4) NOT NULL,
+ event_id NUMBER(10) PRIMARY KEY
+ );
+
+
+CREATE TRIGGER logging_event_id_seq_trig
+ BEFORE INSERT ON logging_event
+ FOR EACH ROW
+ BEGIN
+ SELECT logging_event_id_seq.NEXTVAL
+ INTO :NEW.event_id
+ FROM DUAL;
+ END logging_event_id_seq_trig;
+
+
+CREATE TABLE logging_event_property
+ (
+ event_id NUMBER(10) NOT NULL,
+ mapped_key VARCHAR2(254) NOT NULL,
+ mapped_value VARCHAR2(1024),
+ PRIMARY KEY(event_id, mapped_key),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
+
+CREATE TABLE logging_event_exception
+ (
+ event_id NUMBER(10) NOT NULL,
+ i SMALLINT NOT NULL,
+ trace_line VARCHAR2(254) NOT NULL,
+ PRIMARY KEY(event_id, i),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
+
+
+
+
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/postgresql.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/dialect/postgresql.sql Tue Sep 26 18:14:59 2006
@@ -0,0 +1,47 @@
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
+#
+# It is intended for PostgreSQL databases.
+
+DROP TABLE logging_event_property;
+DROP TABLE logging_event_exception;
+DROP SEQUENCE logging_event_id_seq;
+DROP TABLE logging_event;
+
+
+CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START 1;
+
+
+CREATE TABLE logging_event
+ (
+ sequence_number BIGINT NOT NULL,
+ timestamp BIGINT NOT NULL,
+ rendered_message TEXT NOT NULL,
+ logger_name VARCHAR(254) NOT NULL,
+ level_string VARCHAR(254) NOT NULL,
+ ndc TEXT,
+ thread_name VARCHAR(254),
+ reference_flag SMALLINT,
+ caller_filename VARCHAR(254) NOT NULL,
+ caller_class VARCHAR(254) NOT NULL,
+ caller_method VARCHAR(254) NOT NULL,
+ caller_line CHAR(4) NOT NULL,
+ event_id INT DEFAULT nextval('logging_event_id_seq') PRIMARY KEY
+ );
+
+CREATE TABLE logging_event_property
+ (
+ event_id INT NOT NULL,
+ mapped_key VARCHAR(254) NOT NULL,
+ mapped_value VARCHAR(1024),
+ PRIMARY KEY(event_id, mapped_key),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
+
+CREATE TABLE logging_event_exception
+ (
+ event_id INT NOT NULL,
+ i SMALLINT NOT NULL,
+ trace_line VARCHAR(254) NOT NULL,
+ PRIMARY KEY(event_id, i),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
1
0

svn commit: r606 - in logback/trunk/logback-classic/src: main/java/ch/qos/logback/classic/db main/java/ch/qos/logback/classic/db/dialect test/java/ch/qos/logback/classic/db
by noreply.seb@qos.ch 26 Sep '06
by noreply.seb@qos.ch 26 Sep '06
26 Sep '06
Author: seb
Date: Tue Sep 26 18:14:39 2006
New Revision: 606
Removed:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/JNDIConnectionSource.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java
Log:
- Created DBAppenderBase, and modified DBAppender accordingly
- Moved classes to Core module when possible.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java Tue Sep 26 18:14:39 2006
@@ -10,25 +10,16 @@
package ch.qos.logback.classic.db;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
-import java.sql.ResultSet;
import java.sql.SQLException;
-import java.sql.Statement;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Set;
-import ch.qos.logback.classic.db.dialect.DBUtil;
-import ch.qos.logback.classic.db.dialect.SQLDialect;
import ch.qos.logback.classic.spi.CallerData;
import ch.qos.logback.classic.spi.LoggingEvent;
-import ch.qos.logback.classic.spi.ThrowableInformation;
-import ch.qos.logback.core.AppenderBase;
-import ch.qos.logback.core.Layout;
+import ch.qos.logback.core.db.DBAppenderBase;
+import ch.qos.logback.core.db.dialect.SQLDialect;
/**
* The DBAppender inserts loggin events into three database tables in a format
@@ -109,126 +100,32 @@
* @author Ray DeCampo
* @author Sébastien Pennec
*/
-public class DBAppender extends AppenderBase {
- static final String insertPropertiesSQL = "INSERT INTO logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
- static final String insertExceptionSQL = "INSERT INTO logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)";
- static final String insertSQL;
- private static final Method GET_GENERATED_KEYS_METHOD;
-
- static {
- StringBuffer sql = new StringBuffer();
- sql.append("INSERT INTO logging_event (");
- sql.append("timestmp, ");
- sql.append("formatted_message, ");
- sql.append("logger_name, ");
- sql.append("level_string, ");
- sql.append("thread_name, ");
- sql.append("reference_flag, ");
- sql.append("caller_filename, ");
- sql.append("caller_class, ");
- sql.append("caller_method, ");
- sql.append("caller_line) ");
- sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?,?)");
- insertSQL = sql.toString();
- //
- // PreparedStatement.getGeneratedKeys added in JDK 1.4
- //
- Method getGeneratedKeysMethod;
- try {
- getGeneratedKeysMethod = PreparedStatement.class.getMethod(
- "getGeneratedKeys", (Class[]) null);
- } catch (Exception ex) {
- getGeneratedKeysMethod = null;
- }
- GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
- }
-
- ConnectionSource connectionSource;
- boolean cnxSupportsGetGeneratedKeys = false;
- boolean cnxSupportsBatchUpdates = false;
- SQLDialect sqlDialect;
+public class DBAppender extends DBAppenderBase {
public DBAppender() {
}
@Override
- public void start() {
+ protected void subAppend(Object eventObject, Connection connection,
+ PreparedStatement insertStatement) throws Throwable {
+ LoggingEvent event = (LoggingEvent) eventObject;
- if (connectionSource == null) {
- throw new IllegalStateException(
- "DBAppender cannot function without a connection source");
- }
+ addLoggingEvent(insertStatement, event);
+ // This is very expensive... should we do it every time?
+ addCallerData(insertStatement, event.getCallerData());
- sqlDialect = DBUtil
- .getDialectFromCode(connectionSource.getSQLDialectCode());
- if (GET_GENERATED_KEYS_METHOD != null) {
- cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys();
- } else {
- cnxSupportsGetGeneratedKeys = false;
+ int updateCount = insertStatement.executeUpdate();
+ if (updateCount != 1) {
+ addWarn("Failed to insert loggingEvent");
}
- cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates();
- if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) {
- throw new IllegalStateException(
- "DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect");
- }
-
- // all nice and dandy on the eastern front
- super.start();
- }
- /**
- * @return Returns the connectionSource.
- */
- public ConnectionSource getConnectionSource() {
- return connectionSource;
- }
+ int eventId = getEventId(insertStatement, connection);
- /**
- * @param connectionSource
- * The connectionSource to set.
- */
- public void setConnectionSource(ConnectionSource connectionSource) {
- this.connectionSource = connectionSource;
- }
+ Map<String, String> mergedMap = mergePropertyMaps(event);
+ insertProperties(mergedMap, connection, eventId);
- @Override
- protected void append(Object eventObject) {
- LoggingEvent event = (LoggingEvent) eventObject;
- Connection connection = null;
- try {
- connection = connectionSource.getConnection();
- connection.setAutoCommit(false);
-
- PreparedStatement insertStatement = connection
- .prepareStatement(insertSQL);
-
- addLoggingEvent(insertStatement, event);
- // This is very expensive... should we do it every time?
- addCallerData(insertStatement, event.getCallerData());
-
- int updateCount = insertStatement.executeUpdate();
- if (updateCount != 1) {
- addWarn("Failed to insert loggingEvent");
- }
-
- int eventId = getEventId(insertStatement, connection);
-
- // we no longer need the insertStatement
- if (insertStatement != null) {
- insertStatement.close();
- insertStatement = null;
- }
-
- Map<String, String> mergedMap = mergePropertyMaps(event);
- insertProperties(mergedMap, connection, eventId);
-
- insertThrowable(event.getThrowableInformation(), connection, eventId);
-
- connection.commit();
- } catch (Throwable sqle) {
- addError("problem appending event", sqle);
- } finally {
- DBHelper.closeConnection(connection);
+ if (event.getThrowableInformation() != null) {
+ insertThrowable(event.getThrowableInformation().getThrowableStrRep(), connection, eventId);
}
}
@@ -253,54 +150,6 @@
}
}
- int getEventId(PreparedStatement insertStatement, Connection connection)
- throws SQLException, InvocationTargetException {
- ResultSet rs = null;
- Statement idStatement = null;
- boolean gotGeneratedKeys = false;
- if (cnxSupportsGetGeneratedKeys) {
- try {
- rs = (ResultSet) GET_GENERATED_KEYS_METHOD.invoke(insertStatement,
- (Object[]) null);
- gotGeneratedKeys = true;
- } catch (InvocationTargetException ex) {
- Throwable target = ex.getTargetException();
- if (target instanceof SQLException) {
- throw (SQLException) target;
- }
- throw ex;
- } catch (IllegalAccessException ex) {
- addWarn(
- "IllegalAccessException invoking PreparedStatement.getGeneratedKeys",
- ex);
- }
- }
-
- if (!gotGeneratedKeys) {
- insertStatement.close();
- insertStatement = null;
-
- idStatement = connection.createStatement();
- idStatement.setMaxRows(1);
- rs = idStatement.executeQuery(sqlDialect.getSelectInsertId());
- }
-
- // A ResultSet cursor is initially positioned before the first row;
- // the
- // first call to the method next makes the first row the current row
- rs.next();
- int eventId = rs.getInt(1);
-
- rs.close();
-
- if (idStatement != null) {
- idStatement.close();
- idStatement = null;
- }
-
- return eventId;
- }
-
Map<String, String> mergePropertyMaps(LoggingEvent event) {
Map<String, String> mergedMap = new HashMap<String, String>();
// we add the context properties first, then the event properties, since
@@ -319,75 +168,4 @@
return mergedMap;
}
-
- void insertProperties(Map<String, String> mergedMap, Connection connection,
- int eventId) throws SQLException {
- Set propertiesKeys = mergedMap.keySet();
- if (propertiesKeys.size() > 0) {
- PreparedStatement insertPropertiesStatement = connection
- .prepareStatement(insertPropertiesSQL);
-
- for (Iterator i = propertiesKeys.iterator(); i.hasNext();) {
- String key = (String) i.next();
- String value = (String) mergedMap.get(key);
-
- insertPropertiesStatement.setInt(1, eventId);
- insertPropertiesStatement.setString(2, key);
- insertPropertiesStatement.setString(3, value);
-
- if (cnxSupportsBatchUpdates) {
- insertPropertiesStatement.addBatch();
- } else {
- insertPropertiesStatement.execute();
- }
- }
-
- if (cnxSupportsBatchUpdates) {
- insertPropertiesStatement.executeBatch();
- }
-
- insertPropertiesStatement.close();
- insertPropertiesStatement = null;
- }
- }
-
- void insertThrowable(ThrowableInformation ti, Connection connection,
- int eventId) throws SQLException {
- String[] strRep = null;
- if (ti != null) {
- strRep = ti.getThrowableStrRep();
-
- PreparedStatement insertExceptionStatement = connection
- .prepareStatement(insertExceptionSQL);
-
- for (short i = 0; i < strRep.length; i++) {
- insertExceptionStatement.setInt(1, eventId);
- insertExceptionStatement.setShort(2, i);
- insertExceptionStatement.setString(3, strRep[i]);
- if (cnxSupportsBatchUpdates) {
- insertExceptionStatement.addBatch();
- } else {
- insertExceptionStatement.execute();
- }
- }
- if (cnxSupportsBatchUpdates) {
- insertExceptionStatement.executeBatch();
- }
- insertExceptionStatement.close();
- insertExceptionStatement = null;
- }
- }
-
- @Override
- public void stop() {
- super.stop();
- }
-
- public Layout getLayout() {
- return null;
- }
-
- public void setLayout(Layout layout) {
- }
-
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java Tue Sep 26 18:14:39 2006
@@ -10,10 +10,6 @@
package ch.qos.logback.classic.db;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-
import ch.qos.logback.classic.spi.LoggingEvent;
/**
@@ -49,24 +45,4 @@
}
return mask;
}
-
- static public void closeConnection(Connection connection) {
- if (connection != null) {
- try {
- connection.close();
- } catch (SQLException sqle) {
- // static utility classes should not log without an explicit repository
- // reference
- }
- }
- }
-
- public static void closeStatement(Statement statement) {
- if (statement != null) {
- try {
- statement.close();
- } catch (SQLException sqle) {
- }
- }
- }
}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java Tue Sep 26 18:14:39 2006
@@ -10,6 +10,7 @@
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.CallerData;
import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.db.DriverManagerConnectionSource;
public class DBAppenderTest extends DBAppenderTestBase {
1
0

svn commit: r605 - logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect
by noreply.seb@qos.ch 26 Sep '06
by noreply.seb@qos.ch 26 Sep '06
26 Sep '06
Author: seb
Date: Tue Sep 26 16:26:16 2006
New Revision: 605
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2.sql
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2l.sql
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mssql.sql
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/oracle.sql
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/postgresql.sql
Log:
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2.sql
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2.sql (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2.sql Tue Sep 26 16:26:16 2006
@@ -1,5 +1,4 @@
-# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
-# org.apache.log4j.db.DBReceiver.
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
#
# It is intended for IBM DB2 databases.
#
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2l.sql
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2l.sql (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2l.sql Tue Sep 26 16:26:16 2006
@@ -1,5 +1,4 @@
-# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
-# org.apache.log4j.db.DBReceiver.
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
#
# It is intended for PostgreSQL databases.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mssql.sql
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mssql.sql (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mssql.sql Tue Sep 26 16:26:16 2006
@@ -1,5 +1,4 @@
--- This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
--- org.apache.log4j.db.DBReceiver.
+-- This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
--
-- It is intended for MS SQL Server databases. This has been tested with version 7.0.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/oracle.sql
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/oracle.sql (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/oracle.sql Tue Sep 26 16:26:16 2006
@@ -1,5 +1,4 @@
--- This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
--- org.apache.log4j.db.DBReceiver.
+-- This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
--
-- It is intended for Oracle databases.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/postgresql.sql
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/postgresql.sql (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/postgresql.sql Tue Sep 26 16:26:16 2006
@@ -1,5 +1,4 @@
-# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
-# org.apache.log4j.db.DBReceiver.
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
#
# It is intended for PostgreSQL databases.
1
0

svn commit: r604 - in logback/trunk: . logback-classic logback-classic/src/main/java/ch/qos/logback/classic/db logback-classic/src/main/java/ch/qos/logback/classic/db/dialect logback-classic/src/test/java/ch/qos/logback/classic/db
by noreply.seb@qos.ch 26 Sep '06
by noreply.seb@qos.ch 26 Sep '06
26 Sep '06
Author: seb
Date: Tue Sep 26 16:23:33 2006
New Revision: 604
Added:
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTestBase.java
Modified:
logback/trunk/logback-classic/pom.xml
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java
logback/trunk/pom.xml
Log:
- added a dependency on HSQLDB, since we use this for DBAppender tests.
- corrected hsqldb.sql and mysql.sql
- added a testcase that creates an HSQLDB server, with a test database and uses it to test DBAppender.
- modified some javadoc
Modified: logback/trunk/logback-classic/pom.xml
==============================================================================
--- logback/trunk/logback-classic/pom.xml (original)
+++ logback/trunk/logback-classic/pom.xml Tue Sep 26 16:23:33 2006
@@ -46,7 +46,13 @@
<artifactId>dom4j</artifactId>
<scope>test</scope>
</dependency>
-
+
+ <dependency>
+ <groupId>hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java Tue Sep 26 16:23:33 2006
@@ -23,7 +23,7 @@
/**
* The <id>ConnectionSource</id> interface provides a pluggable means of
- * transparently obtaining JDBC {@link java.sql.Connection}s for log4j classes
+ * transparently obtaining JDBC {@link java.sql.Connection}s for logback classes
* that require the use of a {@link java.sql.Connection}.
*
* @author <a href="mailto:rdecampo@twcny.rr.com">Ray DeCampo</a>
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java Tue Sep 26 16:23:33 2006
@@ -48,7 +48,7 @@
try {
Connection connection = getConnection();
if (connection == null) {
- addWarn("Could not get a conneciton");
+ addWarn("Could not get a connection");
return;
}
DatabaseMetaData meta = connection.getMetaData();
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java Tue Sep 26 16:23:33 2006
@@ -147,7 +147,6 @@
boolean cnxSupportsGetGeneratedKeys = false;
boolean cnxSupportsBatchUpdates = false;
SQLDialect sqlDialect;
- boolean locationInfo = false;
public DBAppender() {
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java Tue Sep 26 16:23:33 2006
@@ -53,7 +53,7 @@
}
/**
- * @see org.apache.log4j.db.ConnectionSource#getConnection()
+ * @see ch.qos.logback.classic.db.ConnectionSource#getConnection()
*/
public Connection getConnection() throws SQLException {
if (dataSource == null) {
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java Tue Sep 26 16:23:33 2006
@@ -71,7 +71,7 @@
Class.forName(driverClass);
discoverConnnectionProperties();
} else {
- addError("WARNING: No JDBC driver specified for log4j DriverManagerConnectionSource.");
+ addError("WARNING: No JDBC driver specified for logback DriverManagerConnectionSource.");
}
} catch (final ClassNotFoundException cnfe) {
addError("Could not load JDBC driver class: " + driverClass, cnfe);
@@ -79,7 +79,7 @@
}
/**
- * @see org.apache.log4j.db.ConnectionSource#getConnection()
+ * @see ch.qos.logback.classic.db.ConnectionSource#getConnection()
*/
public Connection getConnection() throws SQLException {
if (getUser() == null) {
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java Tue Sep 26 16:23:33 2006
@@ -12,7 +12,7 @@
/**
* The HSQLDB dialect.
*
- * @author <a href="http://www.qos.ch/log4j/">Ceki Gülcü</a>
+ * @author Ceki Gülcü
*/
public class HSQLDBDialect implements SQLDialect {
public static final String SELECT_CURRVAL = "CALL IDENTITY()";
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql Tue Sep 26 16:23:33 2006
@@ -1,5 +1,5 @@
// This SQL script creates the required tables by
-// org.apache.log4j.db.DBAppender and org.apache.log4j.db.DBReceiver.
+// ch.qos.logback.classic.db.DBAppender.
//
// It is intended for HSQLDB.
//
@@ -11,17 +11,15 @@
CREATE TABLE logging_event
(
- sequence_number BIGINT NOT NULL,
- timestamp BIGINT NOT NULL,
- rendered_message LONGVARCHAR NOT NULL,
- logger_name VARCHAR NOT NULL,
- level_string VARCHAR NOT NULL,
- ndc LONGVARCHAR,
- thread_name VARCHAR,
+ timestmp BIGINT NOT NULL,
+ formatted_message LONGVARCHAR NOT NULL,
+ logger_name VARCHAR(256) NOT NULL,
+ level_string VARCHAR(256) NOT NULL,
+ thread_name VARCHAR(256),
reference_flag SMALLINT,
- caller_filename VARCHAR,
- caller_class VARCHAR,
- caller_method VARCHAR,
+ caller_filename VARCHAR(256),
+ caller_class VARCHAR(256),
+ caller_method VARCHAR(256),
caller_line CHAR(4),
event_id INT NOT NULL IDENTITY
);
@@ -40,7 +38,7 @@
(
event_id INT NOT NULL,
i SMALLINT NOT NULL,
- trace_line VARCHAR NOT NULL,
+ trace_line VARCHAR(256) NOT NULL,
PRIMARY KEY(event_id, i),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql Tue Sep 26 16:23:33 2006
@@ -1,7 +1,6 @@
-# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
-# org.apache.log4j.db.DBReceiver.
+# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender.
#
-# It is intended for MySQL databases. It has been tested on MySQL 4.1.1 with
+# It is intended for MySQL databases. It has been tested on MySQL 5.0.22 with
# INNODB tables.
@@ -15,12 +14,10 @@
BEGIN;
CREATE TABLE logging_event
(
- sequence_number BIGINT NOT NULL,
- timestamp BIGINT NOT NULL,
- rendered_message TEXT NOT NULL,
+ timestmp BIGINT NOT NULL,
+ formatted_message TEXT NOT NULL,
logger_name VARCHAR(254) NOT NULL,
level_string VARCHAR(254) NOT NULL,
- ndc TEXT,
thread_name VARCHAR(254),
reference_flag SMALLINT,
caller_filename VARCHAR(254) NOT NULL,
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java Tue Sep 26 16:23:33 2006
@@ -1,7 +1,146 @@
package ch.qos.logback.classic.db;
-import junit.framework.TestCase;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
-public class DBAppenderTest extends TestCase {
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.CallerData;
+import ch.qos.logback.classic.spi.LoggingEvent;
+public class DBAppenderTest extends DBAppenderTestBase {
+
+ LoggerContext lc;
+ Logger logger;
+ DBAppender appender;
+ DriverManagerConnectionSource connectionSource;
+
+ public DBAppenderTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws SQLException {
+ super.setUp();
+ lc = new LoggerContext();
+ lc.setName("default");
+ logger = lc.getLogger("root");
+ appender = new DBAppender();
+ appender.setName("DB");
+ appender.setContext(lc);
+ connectionSource = new DriverManagerConnectionSource();
+ connectionSource.setContext(lc);
+ connectionSource.setDriverClass(DRIVER_CLASS);
+ connectionSource.setUrl(url);
+ connectionSource.setUser(user);
+ connectionSource.setPassword(password);
+ connectionSource.start();
+ appender.setConnectionSource(connectionSource);
+ appender.start();
+ }
+
+ public void tearDown() throws SQLException {
+ super.tearDown();
+ logger = null;
+ lc = null;
+ appender = null;
+ connectionSource = null;
+ }
+
+ public void testAppendLoggingEvent() throws SQLException {
+ LoggingEvent event = createLoggingEvent();
+
+ appender.append(event);
+ //StatusPrinter.print(lc.getStatusManager());
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM logging_event");
+ if (rs.next()) {
+ assertEquals(event.getTimeStamp(), rs.getLong(1));
+ assertEquals(event.getFormattedMessage(), rs.getString(2));
+ assertEquals(event.getLoggerRemoteView().getName(), rs.getString(3));
+ assertEquals(event.getLevel().toString(), rs.getString(4));
+ assertEquals(event.getThreadName(), rs.getString(5));
+ assertEquals(DBHelper.computeReferenceMask(event), rs.getShort(6));
+ CallerData callerData = event.getCallerData()[0];
+ assertEquals(callerData.getFileName(), rs.getString(7));
+ assertEquals(callerData.getClassName(), rs.getString(8));
+ assertEquals(callerData.getMethodName(), rs.getString(9));
+ } else {
+ fail("No row was inserted in the database");
+ }
+
+ rs.close();
+ stmt.close();
+ }
+
+ public void testAppendThrowable() throws SQLException {
+ LoggingEvent event = createLoggingEvent();
+
+ appender.append(event);
+ //StatusPrinter.print(lc.getStatusManager());
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM logging_event_exception where event_id = 0");
+ int i = 0;
+ while (rs.next()) {
+ assertEquals(event.getThrowableInformation().getThrowableStrRep()[i], rs.getString(3));
+ i++;
+ }
+
+ rs.close();
+ stmt.close();
+ }
+
+ public void testContextInfo() throws SQLException {
+ LoggingEvent event = createLoggingEvent();
+ lc.setProperty("testKey1", "testValue1");
+
+ appender.append(event);
+ //StatusPrinter.print(lc.getStatusManager());
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM logging_event_property where event_id = 0");
+ Map<String, String> map = appender.mergePropertyMaps(event);
+ while (rs.next()) {
+ String key = rs.getString(2);
+ assertEquals(map.get(key), rs.getString(3));
+ System.out.println("value: " + map.get(key));
+ }
+
+ rs.close();
+ stmt.close();
+ }
+
+ public void testAppendMultipleEvents() throws SQLException {
+ for (int i = 0; i < 10; i++) {
+ LoggingEvent event = createLoggingEvent();
+ appender.append(event);
+ }
+ //StatusPrinter.print(lc.getStatusManager());
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM logging_event");
+ int count = 0;
+ while (rs.next()) {
+ count++;
+ }
+ assertEquals(10, count);
+
+ rs.close();
+ stmt.close();
+ }
+
+
+ private LoggingEvent createLoggingEvent() {
+ LoggingEvent le = new LoggingEvent(this.getClass().getName(), logger,
+ Level.DEBUG, "test message", new Exception("test Ex"), null);
+ return le;
+ }
}
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTestBase.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTestBase.java Tue Sep 26 16:23:33 2006
@@ -0,0 +1,143 @@
+package ch.qos.logback.classic.db;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+
+import org.hsqldb.Server;
+
+public abstract class DBAppenderTestBase extends TestCase {
+
+ public static final String DRIVER_CLASS = "org.hsqldb.jdbcDriver";
+ String serverProps;
+ String url;
+ String user = "sa";
+ String password = "";
+ Server server;
+ boolean isNetwork = true;
+
+ public DBAppenderTestBase(String name) {
+ super(name);
+ }
+
+ public DBAppenderTestBase(String name, String url, boolean isNetwork) {
+
+ super(name);
+
+ this.isNetwork = isNetwork;
+ this.url = url;
+ }
+
+ protected void setUp() throws SQLException {
+
+ if (isNetwork) {
+ if (url == null) {
+ url = "jdbc:hsqldb:hsql://localhost/test";
+ }
+
+ server = new Server();
+
+ server.setDatabaseName(0, "test");
+ server.setDatabasePath(0, "mem:test;sql.enforce_strict_size=true");
+ server.setLogWriter(null);
+ server.setErrWriter(null);
+ server.start();
+ } else {
+ if (url == null) {
+ url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
+ }
+ }
+
+ try {
+ Class.forName(DRIVER_CLASS);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println(this + ".setUp() error: " + e.getMessage());
+ }
+
+ createTables();
+ }
+
+ protected void tearDown() throws SQLException {
+ dropTables();
+
+ if (isNetwork) {
+ server.stop();
+
+ server = null;
+ }
+ }
+
+ Connection newConnection() throws SQLException {
+ return DriverManager.getConnection(url, user, password);
+ }
+
+ void createTables() throws SQLException {
+ Connection conn = newConnection();
+ StringBuffer buf = new StringBuffer();
+ buf.append("CREATE TABLE logging_event (");
+ buf.append("timestmp BIGINT NOT NULL,");
+ buf.append("formatted_message LONGVARCHAR NOT NULL,");
+ buf.append("logger_name VARCHAR(256) NOT NULL,");
+ buf.append("level_string VARCHAR(256) NOT NULL,");
+ buf.append("thread_name VARCHAR(256),");
+ buf.append("reference_flag SMALLINT,");
+ buf.append("caller_filename VARCHAR(256), ");
+ buf.append("caller_class VARCHAR(256), ");
+ buf.append("caller_method VARCHAR(256), ");
+ buf.append("caller_line CHAR(4), ");
+ buf.append("event_id INT NOT NULL IDENTITY);");
+ query(conn, buf.toString());
+
+ buf = new StringBuffer();
+ buf.append("CREATE TABLE logging_event_property (");
+ buf.append("event_id INT NOT NULL,");
+ buf.append("mapped_key VARCHAR(254) NOT NULL,");
+ buf.append("mapped_value LONGVARCHAR,");
+ buf.append("PRIMARY KEY(event_id, mapped_key),");
+ buf.append("FOREIGN KEY (event_id) REFERENCES logging_event(event_id));");
+ query(conn, buf.toString());
+
+ buf = new StringBuffer();
+ buf.append("CREATE TABLE logging_event_exception (");
+ buf.append("event_id INT NOT NULL,");
+ buf.append("i SMALLINT NOT NULL,");
+ buf.append("trace_line VARCHAR(256) NOT NULL,");
+ buf.append("PRIMARY KEY(event_id, i),");
+ buf.append("FOREIGN KEY (event_id) REFERENCES logging_event(event_id));");
+ query(conn, buf.toString());
+ }
+
+ void dropTables() throws SQLException {
+ Connection conn = newConnection();
+ StringBuffer buf = new StringBuffer();
+ buf.append("DROP TABLE logging_event_exception IF EXISTS;");
+ query(conn, buf.toString());
+
+ buf = new StringBuffer();
+ buf.append("DROP TABLE logging_event_property IF EXISTS;");
+ query(conn, buf.toString());
+
+ buf = new StringBuffer();
+ buf.append("DROP TABLE logging_event IF EXISTS;");
+ query(conn, buf.toString());
+ }
+
+ void query(Connection conn, String expression) throws SQLException {
+
+ Statement st = null;
+
+ st = conn.createStatement();
+
+ int i = st.executeUpdate(expression);
+
+ if (i == -1) {
+ System.out.println("db error : " + expression);
+ }
+
+ st.close();
+ }
+}
Modified: logback/trunk/pom.xml
==============================================================================
--- logback/trunk/pom.xml (original)
+++ logback/trunk/pom.xml Tue Sep 26 16:23:33 2006
@@ -74,6 +74,11 @@
<artifactId>slf4j-api</artifactId>
<version>1.1.0-beta0</version>
</dependency>
+ <dependency>
+ <groupId>hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>1.8.0.5</version>
+ </dependency>
<!-- Access Module Dependencies -->
<dependency>
1
0

svn commit: r603 - in logback/trunk/logback-classic: examples/classes src/main/java/ch/qos/logback/classic/html
by noreply.seb@qos.ch 25 Sep '06
by noreply.seb@qos.ch 25 Sep '06
25 Sep '06
Author: seb
Date: Mon Sep 25 17:04:00 2006
New Revision: 603
Modified:
logback/trunk/logback-classic/examples/classes/ (props changed)
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java
Log:
- corrected a possible null pointer in HTMLLayout
- modified ignore list on examples/classes/
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java Mon Sep 25 17:04:00 2006
@@ -95,6 +95,7 @@
*/
public HTMLLayout() {
pattern = DEFAULT_CONVERSION_PATTERN;
+ throwableRenderer = new DefaultThrowableRenderer();
}
protected Map<String, String> getDefaultConverterMap() {
1
0

svn commit: r602 - in logback/trunk/logback-classic/examples/src/chapter4: . conf sub sub/sample
by noreply.seb@qos.ch 25 Sep '06
by noreply.seb@qos.ch 25 Sep '06
25 Sep '06
Author: seb
Date: Mon Sep 25 17:01:50 2006
New Revision: 602
Added:
logback/trunk/logback-classic/examples/src/chapter4/
logback/trunk/logback-classic/examples/src/chapter4/ConfigurationTester.java
logback/trunk/logback-classic/examples/src/chapter4/conf/
logback/trunk/logback-classic/examples/src/chapter4/conf/logback-Console.xml
logback/trunk/logback-classic/examples/src/chapter4/conf/logback-HtmlToConsole.xml
logback/trunk/logback-classic/examples/src/chapter4/conf/logback-MDC.xml
logback/trunk/logback-classic/examples/src/chapter4/conf/logback-RollingSizeBased.xml
logback/trunk/logback-classic/examples/src/chapter4/conf/logback-RollingTimeBased.xml
logback/trunk/logback-classic/examples/src/chapter4/conf/logback-SMTP.xml
logback/trunk/logback-classic/examples/src/chapter4/conf/logback-SMTPWithHtml.xml
logback/trunk/logback-classic/examples/src/chapter4/sub/
logback/trunk/logback-classic/examples/src/chapter4/sub/sample/
logback/trunk/logback-classic/examples/src/chapter4/sub/sample/Bar.java
Log:
- added a chapter4 package in the examples, containing several configuration files for logback, as well as
a ConfigurationTester class to launch logback with a specified config. file.
Added: logback/trunk/logback-classic/examples/src/chapter4/ConfigurationTester.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/examples/src/chapter4/ConfigurationTester.java Mon Sep 25 17:01:50 2006
@@ -0,0 +1,43 @@
+package chapter4;
+
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.MDC;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.util.StatusPrinter;
+import chapter4.sub.sample.Bar;
+/**
+ *
+ * This class can be used to check the result of a configuration file.
+ * <p>
+ * When all the logback-core, logback-classic and their dependencies have been added
+ * to the ClassPath, one can launch this class using the following command:
+ * <p>
+ * java chapter4.ConfigurationTester chapter4/conf/name_of_the_configuration_file.xml
+ *
+ * @author Sébastien Pennec
+ */
+public class ConfigurationTester {
+
+ public static void main(String[] args) throws InterruptedException {
+ Logger logger = (Logger) LoggerFactory.getLogger(ConfigurationTester.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ configurator.doConfigure(args[0]);
+
+ logger.debug("**Hello {}", new Bar());
+ MDC.put("testKey", "testValueFromMDC");
+ MDC.put("testKey2", "value2");
+ for (int i = 0; i < 10; i++) {
+ logger.debug("logging statement " + i);
+ }
+ Bar bar = new Bar();
+ bar.createLoggingRequest();
+
+ StatusPrinter.print(lc.getStatusManager());
+ }
+}
Added: logback/trunk/logback-classic/examples/src/chapter4/conf/logback-Console.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/examples/src/chapter4/conf/logback-Console.xml Mon Sep 25 17:01:50 2006
@@ -0,0 +1,16 @@
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <param name="Pattern"
+ value="%-4relative [%thread] %-5level - %msg %n" />
+ </layout>
+ </appender>
+
+ <root>
+ <level value="debug" />
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
Added: logback/trunk/logback-classic/examples/src/chapter4/conf/logback-HtmlToConsole.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/examples/src/chapter4/conf/logback-HtmlToConsole.xml Mon Sep 25 17:01:50 2006
@@ -0,0 +1,19 @@
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.html.HTMLLayout">
+ <cssBuilder class="ch.qos.logback.core.helpers.CssBuilder">
+ <param name="url" value="path_to_StyleFile.css" />
+ </cssBuilder>
+ <param name="Pattern"
+ value="%-4relative [%thread] %-5level - %msg%n" />
+ </layout>
+ </appender>
+
+ <root>
+ <level value="debug" />
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
Added: logback/trunk/logback-classic/examples/src/chapter4/conf/logback-MDC.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/examples/src/chapter4/conf/logback-MDC.xml Mon Sep 25 17:01:50 2006
@@ -0,0 +1,16 @@
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <param name="Pattern"
+ value="%-4relative [%thread] %-5level %X{testKey} - %msg%n" />
+ </layout>
+ </appender>
+
+ <root>
+ <level value="debug" />
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
Added: logback/trunk/logback-classic/examples/src/chapter4/conf/logback-RollingSizeBased.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/examples/src/chapter4/conf/logback-RollingSizeBased.xml Mon Sep 25 17:01:50 2006
@@ -0,0 +1,30 @@
+<configuration>
+
+ <appender name="FILE"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <param name="ActiveFileName" value="testFile.log" />
+ <param name="FileNamePattern" value="testFile.%i.log" />
+ <param name="MinIndex" value="1" />
+ <param name="MaxIndex" value="3" />
+ </rollingPolicy>
+
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <param name="MaxFileSize" value="5MB" />
+ </triggeringPolicy>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <param name="Pattern"
+ value="%-4relative [%thread] %-5level %class - %msg%n" />
+ </layout>
+ </appender>
+
+
+
+ <root>
+ <level value="debug" />
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
+
Added: logback/trunk/logback-classic/examples/src/chapter4/conf/logback-RollingTimeBased.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/examples/src/chapter4/conf/logback-RollingTimeBased.xml Mon Sep 25 17:01:50 2006
@@ -0,0 +1,17 @@
+<configuration>
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <param name="ActiveFileName" value="outputFile.log" />
+ <param name="FileNamePattern" value="logFile.%d{yyyy-MM-dd}.log" />
+ </rollingPolicy>
+
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <param name="pattern" value="%-4relative [%thread] %-5level %class - %msg%n" />
+ </layout>
+ </appender>
+
+ <root>
+ <level value="debug" />
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
Added: logback/trunk/logback-classic/examples/src/chapter4/conf/logback-SMTP.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/examples/src/chapter4/conf/logback-SMTP.xml Mon Sep 25 17:01:50 2006
@@ -0,0 +1,22 @@
+<configuration>
+
+ <appender name="SMTP"
+ class="ch.qos.logback.classic.net.SMTPAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <param name="pattern"
+ value="%-4relative [%thread] %-5level %class - %msg%n" />
+ </layout>
+ <param name="From" value="test.nospam(a)qos.ch" />
+ <param name="SMTPHost" value="mail.qos.ch" />
+
+ <param name="Subject" value="Last Event: %-10logger %nopex" />
+
+ <param name="To" value="sebastien(a)qos.ch" />
+ </appender>
+
+ <root>
+ <level value="debug" />
+ <appender-ref ref="SMTP" />
+ </root>
+</configuration>
+
Added: logback/trunk/logback-classic/examples/src/chapter4/conf/logback-SMTPWithHtml.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/examples/src/chapter4/conf/logback-SMTPWithHtml.xml Mon Sep 25 17:01:50 2006
@@ -0,0 +1,21 @@
+<configuration>
+
+ <appender name="SMTP"
+ class="ch.qos.logback.classic.net.SMTPAppender">
+ <layout class="ch.qos.logback.classic.html.HTMLLayout">
+ <param name="pattern" value="%relative%thread%mdc%level%class%msg" />
+ <throwableRenderer class="ch.qos.logback.classic.html.DefaultThrowableRenderer" />
+ </layout>
+ <param name="From" value="test.nospam(a)qos.ch" />
+ <param name="SMTPHost" value="mail.qos.ch" />
+ <param name="Subject" value="LastEvent: %class - %msg %nopex" />
+
+ <param name="To" value="sebastien(a)qos.ch" />
+ </appender>
+
+ <root>
+ <level value="debug" />
+ <appender-ref ref="SMTP" />
+ </root>
+</configuration>
+
Added: logback/trunk/logback-classic/examples/src/chapter4/sub/sample/Bar.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/examples/src/chapter4/sub/sample/Bar.java Mon Sep 25 17:01:50 2006
@@ -0,0 +1,21 @@
+package chapter4.sub.sample;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Bar {
+ Logger logger = LoggerFactory.getLogger(Bar.class);
+
+ public String toString() {
+ return "test 123";
+ }
+
+ public void createLoggingRequest() {
+ subMethodToCreateRequest();
+ }
+
+ //this is done to create a stacktrace of more than one line
+ private void subMethodToCreateRequest() {
+ logger.error("error-level request", new Exception("test exception"));
+ }
+}
1
0

svn commit: r601 - logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling
by noreply.seb@qos.ch 25 Sep '06
by noreply.seb@qos.ch 25 Sep '06
25 Sep '06
Author: seb
Date: Mon Sep 25 16:11:49 2006
New Revision: 601
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java
Log:
- updated RollingFileAppender.java and FixedWindowRollingPolicy.java to show a link to the faq when adding errors to the context
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java Mon Sep 25 16:11:49 2006
@@ -53,7 +53,7 @@
*/
public class FixedWindowRollingPolicy extends RollingPolicyBase {
static final String FNP_NOT_SET = "The FileNamePattern option must be set before using FixedWindowRollingPolicy. ";
- static final String SEE_FNP_NOT_SET = "See also http://www.logback.com/doc/codes.html#tbr_fnp_not_set";
+ static final String SEE_FNP_NOT_SET = "See also http://logback.qos.ch/codes.html#tbr_fnp_not_set";
int maxIndex;
int minIndex;
RenameUtil util = new RenameUtil();
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java Mon Sep 25 16:11:49 2006
@@ -73,7 +73,8 @@
public void start() {
if (triggeringPolicy == null) {
- addWarn("Please set a TriggeringPolicy for the RollingFileAppender named "+ getName());
+ addWarn("No TriggeringPolicy was set for the RollingFileAppender named "+ getName());
+ addWarn("For more information, please visit http://logback.qos.ch/codes.html#rfa_no_tp");
return;
}
@@ -87,7 +88,8 @@
activeFile = new File(afn);
super.start();
} else {
- addWarn("Please set a rolling policy");
+ addWarn("No RollingPolicy was set for the RollingFileAppender named "+ getName());
+ addWarn("For more information, please visit http://logback.qos.ch/codes.html#rfa_no_rp");
}
}
1
0

svn commit: r600 - in logback/trunk/logback-site/src/site: . fml xdocTemplates
by noreply.seb@qos.ch 25 Sep '06
by noreply.seb@qos.ch 25 Sep '06
25 Sep '06
Author: seb
Date: Mon Sep 25 16:11:00 2006
New Revision: 600
Modified:
logback/trunk/logback-site/src/site/fml/codes.fml
logback/trunk/logback-site/src/site/site.xml
logback/trunk/logback-site/src/site/xdocTemplates/shortIntro.xml
Log:
- added some entries in codes.fml
- updated site.xml to use the new version of logback-skin
- updated shortIntro.xml
Modified: logback/trunk/logback-site/src/site/fml/codes.fml
==============================================================================
--- logback/trunk/logback-site/src/site/fml/codes.fml (original)
+++ logback/trunk/logback-site/src/site/fml/codes.fml Mon Sep 25 16:11:00 2006
@@ -30,6 +30,14 @@
<code>FixedWindowRollingPolicy</code>
is mandatory.
</p>
+ <p>
+ See the
+ <a
+ href="http://logback.qos.ch/apidocs/ch/qos/logback/core/rolling/FixedWindowRollin…">
+ FixedWindowRollingPolicy javadoc
+ </a>
+ for more information.
+ </p>
</answer>
</faq>
@@ -49,11 +57,15 @@
You can specify the remote host in the
configuration file like this:
</p>
- <source><appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
- ...
- <param name="remoteHost" value="127.0.0.1" />
+ <source>
+<appender name="SOCKET"
+ class="ch.qos.logback.classic.net.SocketAppender">
...
-</appender></source>
+ <param name="remoteHost"
+ value="127.0.0.1" />
+ ...
+</appender>
+ </source>
</answer>
</faq>
<faq id="socket_no_port">
@@ -72,39 +84,14 @@
You can specify the remote port in the
configuration file like this:
</p>
- <source><appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
- ...
- <param name="port" value="4560" />
- ...
-</appender></source>
- </answer>
- </faq>
- <faq id="smtp_no_tp">
- <question>
- No
- <code>TriggeringPolicy</code>
- is set for appender
- </question>
-
- <answer>
- <p>
- A
- <code>TriggeringPolicy</code>
- is mandatory for
- <code>SMTPAppender</code>
- . It allows the appender to know when to
- send the email to the specified address.
- </p>
- <p>
- You can specify the
- <code>TriggeringPolicy</code>
- in the configuration file like this:
- </p>
- <source><appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
- ...
- <param name="port" value="4560"/>
- ...
-</appender></source>
+ <source>
+<appender name="SOCKET"
+ class="ch.qos.logback.classic.net.SocketAppender">
+ ...
+ <param name="port" value="4560" />
+ ...
+</appender>
+ </source>
</answer>
</faq>
<faq id="smtp_no_layout">
@@ -135,13 +122,31 @@
<code>Layout</code>
in the configuration file like this:
</p>
- <source><appender name="SMTP" class="ch.qos.logback.classic.net.SMTPAppender">
- ...
- <layout class="ch.qos.logback.classic.PatternLayout">
- <param name="pattern" value="%-4relative [%thread] %-5level %class - %msg%n" />
- </layout>
- ...
-</appender></source>
+ <source>
+<appender name="SMTP"
+ class="ch.qos.logback.classic.net.SMTPAppender">
+ ...
+ <layout
+ class="ch.qos.logback.classic.PatternLayout">
+ <param name="pattern"
+ value="%-4relative [%thread] %-5level %class - %msg%n" />
+ </layout>
+ ...
+</appender>
+ </source>
+ <p>
+ You can see more examples in the
+ <a
+ href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/html/HTMLLayout.html">
+ HTMLLayout javadoc
+ </a>
+ and the
+ <a
+ href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/PatternLayout.html">
+ PatternLayout javadoc
+ </a>
+ .
+ </p>
</answer>
</faq>
<faq id="sbtp_size_format">
@@ -169,6 +174,84 @@
</p>
</answer>
</faq>
+ <faq id="rfa_no_tp">
+ <question>
+ No <code>TriggeringPolicy</code> was set for the
+ <code>RollingFileAppender</code>.
+ </question>
+
+ <answer>
+ <p>
+ The <code>RollingFileAppender</code> must be set up with
+ a <code>TriggeringPolicy</code>. It permits the Appender
+ to know when the rollover must be activated.
+ </p>
+ <p>
+ To find more information about
+ <code>TriggeringPolicy</code> objects, please read the
+ following javadocs:
+ </p>
+ <ul>
+ <li>
+ <a
+ href="http://logback.qos.ch/apidocs/ch/qos/logback/core/rolling/SizeBasedTriggeri…">
+ <code>SizeBasedTriggeringPolicy</code>
+ </a>
+ </li>
+ <li>
+ <a
+ href="http://logback.qos.ch/apidocs/ch/qos/logback/core/rolling/TimeBasedRollingP…">
+ <code>TimeBasedRollingPolicy</code>
+ </a>
+ </li>
+ </ul>
+ <p>
+ Please note that the <code>TimeBasedRollingPolicy</code>
+ is a TriggeringPolicy
+ <em>and</em>
+ and <code>RollingPolicy</code> at the same time.
+ </p>
+ </answer>
+ </faq>
+ <faq id="rfa_no_rp">
+ <question>
+ No <code>RollingPolicy</code> was set for the
+ <code>RollingFileAppender</code>.
+ </question>
+
+ <answer>
+ <p>
+ The <code>RollingFileAppender</code> must be set up with
+ a <code>RollingPolicy</code>. It permits the Appender
+ to know what to do when a rollover is requested.
+ </p>
+ <p>
+ To find more information about
+ <code>RollingPolicy</code> objects, please read the
+ following javadocs:
+ </p>
+ <ul>
+ <li>
+ <a
+ href="http://logback.qos.ch/apidocs/ch/qos/logback/core/rolling/FixedWindowRollin…">
+ <code>FixedWindowRollingPolicy</code>
+ </a>
+ </li>
+ <li>
+ <a
+ href="http://logback.qos.ch/apidocs/ch/qos/logback/core/rolling/TimeBasedRollingP…">
+ <code>TimeBasedRollingPolicy</code>
+ </a>
+ </li>
+ </ul>
+ <p>
+ Please note that the <code>TimeBasedRollingPolicy</code>
+ is a <code>TriggeringPolicy</code>
+ <em>and</em>
+ and RollingPolicy at the same time.
+ </p>
+ </answer>
+ </faq>
</part>
</faqs>
</body>
Modified: logback/trunk/logback-site/src/site/site.xml
==============================================================================
--- logback/trunk/logback-site/src/site/site.xml (original)
+++ logback/trunk/logback-site/src/site/site.xml Mon Sep 25 16:11:00 2006
@@ -4,7 +4,7 @@
<skin>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-skin</artifactId>
- <version>0.3-SNAPSHOT</version>
+ <version>0.4-SNAPSHOT</version>
</skin>
<publishDate position="navigation-bottom" format="dd-MM-yyyy"/>
Modified: logback/trunk/logback-site/src/site/xdocTemplates/shortIntro.xml
==============================================================================
--- logback/trunk/logback-site/src/site/xdocTemplates/shortIntro.xml (original)
+++ logback/trunk/logback-site/src/site/xdocTemplates/shortIntro.xml Mon Sep 25 16:11:00 2006
@@ -963,7 +963,8 @@
</p>
- <div class="source">logger.debug("Value {} was inserted between {} and {}.", new Object[] {newVal, below, above});</div>
+ <div class="source">Object[] paramArray = {newVal, below, above};
+logger.debug("Value {} was inserted between {} and {}.", paramArray);</div>
<h3>Configuration</h3>
1
0