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
- 9940 discussions

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

svn commit: r599 - logback/trunk/logback-skin/src/main/resources/css
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:10:02 2006
New Revision: 599
Modified:
logback/trunk/logback-skin/src/main/resources/css/site.css
Log:
- updated source css style
Modified: logback/trunk/logback-skin/src/main/resources/css/site.css
==============================================================================
--- logback/trunk/logback-skin/src/main/resources/css/site.css (original)
+++ logback/trunk/logback-skin/src/main/resources/css/site.css Mon Sep 25 16:10:02 2006
@@ -249,7 +249,7 @@
padding-top: 0.5ex;
padding-left: 1ex;
white-space: pre;
- width: 60em;
+ width: 55em;
}
1
0

svn commit: r598 - in logback/trunk/logback-classic/src: main/java/ch/qos/logback/classic/db main/java/ch/qos/logback/classic/db/dialect test/input/db test/java/ch/qos/logback/classic/db
by noreply.seb@qos.ch 22 Sep '06
by noreply.seb@qos.ch 22 Sep '06
22 Sep '06
Author: seb
Date: Fri Sep 22 17:12:36 2006
New Revision: 598
Added:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/
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/DBHelper.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/
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/DBUtil.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/MsSQLDialect.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/MySQLDialect.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/OracleDialect.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/PostgreSQLDialect.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/SQLDialect.java
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/hsqldb.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/mysql.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
logback/trunk/logback-classic/src/test/input/db/
logback/trunk/logback-classic/src/test/input/db/dbAppenderUsingConnectionSource.xml
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java
Log:
Work in progress:
- added DBAppender and related classes.
- added a configuration example
- added a empty-for-now test case.
A simple logback to mysql test worked with this first version
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java Fri Sep 22 17:12:36 2006
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.qos.logback.classic.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 log4j 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-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java Fri Sep 22 17:12:36 2006
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.qos.logback.classic.db;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import ch.qos.logback.classic.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 conneciton");
+ 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-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java Fri Sep 22 17:12:36 2006
@@ -0,0 +1,394 @@
+/**
+ * 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.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;
+
+/**
+ * The DBAppender inserts loggin events into three database tables in a format
+ * independent of the Java programming language. The three tables that
+ * DBAppender inserts to must exists before DBAppender can be used. These tables
+ * may be created with the help of SQL scripts found in the
+ * <em>src/main/java/ch/qos/logback/classic/db/dialect</em> directory. There
+ * is a specific script for each of the most popular database systems. If the
+ * script for your particular type of database system is missing, it should be
+ * quite easy to write one, taking example on the already existing scripts. If
+ * you send them to us, we will gladly include missing scripts in future
+ * releases.
+ *
+ * <p>
+ * If the JDBC driver you are using supports the
+ * {@link java.sql.Statement#getGeneratedKeys}method introduced in JDBC 3.0
+ * specification, then you are all set. Otherwise, there must be an
+ * {@link SQLDialect}appropriate for your database system. Currently, we have
+ * dialects for PostgreSQL, MySQL, Oracle and MsSQL. As mentioed previously, an
+ * SQLDialect is required only if the JDBC driver for your database system does
+ * not support the {@link java.sql.Statement#getGeneratedKeys getGeneratedKeys}
+ * method.
+ * </p>
+ *
+ * <table border="1" cellpadding="4">
+ * <tr>
+ * <th>RDBMS</th>
+ * <th>supports <br/><code>getGeneratedKeys()</code> method</th>
+ * <th>specific <br/>SQLDialect support</th>
+ * <tr>
+ * <tr>
+ * <td>PostgreSQL</td>
+ * <td align="center">NO</td>
+ * <td>present and used</td>
+ * <tr>
+ * <tr>
+ * <td>MySQL</td>
+ * <td align="center">YES</td>
+ * <td>present, but not actually needed or used</td>
+ * <tr>
+ * <tr>
+ * <td>Oracle</td>
+ * <td align="center">YES</td>
+ * <td>present, but not actually needed or used</td>
+ * <tr>
+ * <tr>
+ * <td>DB2</td>
+ * <td align="center">YES</td>
+ * <td>not present, and not needed or used</td>
+ * <tr>
+ * <tr>
+ * <td>MsSQL</td>
+ * <td align="center">YES</td>
+ * <td>not present, and not needed or used</td>
+ * <tr>
+ * <tr>
+ * <td>HSQL</td>
+ * <td align="center">NO</td>
+ * <td>present and used</td>
+ * <tr>
+ *
+ * </table>
+ * <p>
+ * <b>Performance: </b> Experiments show that writing a single event into the
+ * database takes approximately 50 milliseconds, on a "standard" PC. If pooled
+ * connections are used, this figure drops to under 10 milliseconds. Note that
+ * most JDBC drivers already ship with connection pooling support.
+ * </p>
+ *
+ *
+ *
+ * <p>
+ * <b>Configuration </b> DBAppender can be configured programmatically, or using
+ * {@link ch.qos.logback.classic.joran.JoranConfigurator JoranConfigurator}.
+ * Example scripts can be found in the <em>tests/input/db</em> directory.
+ *
+ * @author Ceki Gülcü
+ * @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;
+ boolean locationInfo = false;
+
+ public DBAppender() {
+ }
+
+ @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
+ 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);
+ }
+ }
+
+ void addLoggingEvent(PreparedStatement stmt, LoggingEvent event)
+ throws SQLException {
+ stmt.setLong(1, event.getTimeStamp());
+ stmt.setString(2, event.getFormattedMessage());
+ stmt.setString(3, event.getLoggerRemoteView().getName());
+ stmt.setString(4, event.getLevel().toString());
+ stmt.setString(5, event.getThreadName());
+ stmt.setShort(6, DBHelper.computeReferenceMask(event));
+ }
+
+ void addCallerData(PreparedStatement stmt, CallerData[] callerDataArray)
+ throws SQLException {
+ CallerData callerData = callerDataArray[0];
+ if (callerData != null) {
+ stmt.setString(7, callerData.getFileName());
+ stmt.setString(8, callerData.getClassName());
+ stmt.setString(9, callerData.getMethodName());
+ stmt.setString(10, Integer.toString(callerData.getLineNumber()));
+ }
+ }
+
+ 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
+ // we consider that event-specific properties should have priority over
+ // context-wide
+ // properties.
+ Map<String, String> loggerContextMap = event.getLoggerRemoteView()
+ .getLoggerContextView().getPropertyMap();
+ Map<String, String> mdcMap = event.getMDCPropertyMap();
+ if (loggerContextMap != null) {
+ mergedMap.putAll(loggerContextMap);
+ }
+ if (mdcMap != null) {
+ mergedMap.putAll(mdcMap);
+ }
+
+ 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) {
+ }
+
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java Fri Sep 22 17:12:36 2006
@@ -0,0 +1,72 @@
+/**
+ * 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.classic.db;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import ch.qos.logback.classic.spi.LoggingEvent;
+
+/**
+ * @author Ceki Gülcü
+ *
+ */
+public class DBHelper {
+
+ public static short PROPERTIES_EXIST = 0x01;
+ public static short EXCEPTION_EXISTS = 0x02;
+
+ public static short computeReferenceMask(LoggingEvent event) {
+ short mask = 0;
+
+ int mdcPropSize = 0;
+ if (event.getMDCPropertyMap() != null) {
+ mdcPropSize = event.getMDCPropertyMap().keySet().size();
+ }
+ int contextPropSize = 0;
+ if (event.getLoggerRemoteView().getLoggerContextView().getPropertyMap() != null) {
+ contextPropSize = event.getLoggerRemoteView().getLoggerContextView()
+ .getPropertyMap().size();
+ }
+
+ if (mdcPropSize > 0 || contextPropSize > 0) {
+ mask = PROPERTIES_EXIST;
+ }
+ if (event.getThrowableInformation() != null) {
+ String[] strRep = event.getThrowableInformation().getThrowableStrRep();
+ if (strRep != null) {
+ mask |= EXCEPTION_EXISTS;
+ }
+ }
+ 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) {
+ }
+ }
+ }
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java Fri Sep 22 17:12:36 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.classic.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 org.apache.log4j.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-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java Fri Sep 22 17:12:36 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.classic.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 log4j DriverManagerConnectionSource.");
+ }
+ } catch (final ClassNotFoundException cnfe) {
+ addError("Could not load JDBC driver class: " + driverClass, cnfe);
+ }
+ }
+
+ /**
+ * @see org.apache.log4j.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-classic/src/main/java/ch/qos/logback/classic/db/JNDIConnectionSource.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/JNDIConnectionSource.java Fri Sep 22 17:12:36 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.classic.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-classic/src/main/java/ch/qos/logback/classic/db/dialect/DBUtil.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/DBUtil.java Fri Sep 22 17:12:36 2006
@@ -0,0 +1,125 @@
+/*
+ * Copyright 1999,2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.qos.logback.classic.db.dialect;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import ch.qos.logback.classic.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-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java Fri Sep 22 17:12:36 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.classic.db.dialect;
+
+/**
+ * The HSQLDB dialect.
+ *
+ * @author <a href="http://www.qos.ch/log4j/">Ceki Gülcü</a>
+*/
+public class HSQLDBDialect implements SQLDialect {
+ public static final String SELECT_CURRVAL = "CALL IDENTITY()";
+
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/MsSQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/MsSQLDialect.java Fri Sep 22 17:12:36 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.classic.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-classic/src/main/java/ch/qos/logback/classic/db/dialect/MySQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/MySQLDialect.java Fri Sep 22 17:12:36 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.classic.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-classic/src/main/java/ch/qos/logback/classic/db/dialect/OracleDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/OracleDialect.java Fri Sep 22 17:12:36 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.classic.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-classic/src/main/java/ch/qos/logback/classic/db/dialect/PostgreSQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/PostgreSQLDialect.java Fri Sep 22 17:12:36 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.classic.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-classic/src/main/java/ch/qos/logback/classic/db/dialect/SQLDialect.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/SQLDialect.java Fri Sep 22 17:12:36 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.classic.db.dialect;
+
+/**
+ * @author ceki
+ *
+ */
+public interface SQLDialect {
+
+ public String getSelectInsertId();
+
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2.sql Fri Sep 22 17:12:36 2006
@@ -0,0 +1,49 @@
+# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
+# org.apache.log4j.db.DBReceiver.
+#
+# 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-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2l.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/db2l.sql Fri Sep 22 17:12:36 2006
@@ -0,0 +1,47 @@
+# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
+# org.apache.log4j.db.DBReceiver.
+#
+# 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-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql Fri Sep 22 17:12:36 2006
@@ -0,0 +1,46 @@
+// This SQL script creates the required tables by
+// org.apache.log4j.db.DBAppender and org.apache.log4j.db.DBReceiver.
+//
+// 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
+ (
+ 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,
+ reference_flag SMALLINT,
+ caller_filename VARCHAR,
+ caller_class VARCHAR,
+ caller_method VARCHAR,
+ 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 NOT NULL,
+ PRIMARY KEY(event_id, i),
+ FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
+ );
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mssql.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mssql.sql Fri Sep 22 17:12:36 2006
@@ -0,0 +1,45 @@
+-- This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
+-- org.apache.log4j.db.DBReceiver.
+--
+-- 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-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql Fri Sep 22 17:12:36 2006
@@ -0,0 +1,54 @@
+# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
+# org.apache.log4j.db.DBReceiver.
+#
+# It is intended for MySQL databases. It has been tested on MySQL 4.1.1 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
+ (
+ 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 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-classic/src/main/java/ch/qos/logback/classic/db/dialect/oracle.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/oracle.sql Fri Sep 22 17:12:36 2006
@@ -0,0 +1,67 @@
+-- This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
+-- org.apache.log4j.db.DBReceiver.
+--
+-- 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-classic/src/main/java/ch/qos/logback/classic/db/dialect/postgresql.sql
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/postgresql.sql Fri Sep 22 17:12:36 2006
@@ -0,0 +1,48 @@
+# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
+# org.apache.log4j.db.DBReceiver.
+#
+# 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)
+ );
Added: logback/trunk/logback-classic/src/test/input/db/dbAppenderUsingConnectionSource.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/db/dbAppenderUsingConnectionSource.xml Fri Sep 22 17:12:36 2006
@@ -0,0 +1,23 @@
+<configuration>
+
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.classic.db.DriverManagerConnectionSource">
+ <param name="driverClass" value="com.mysql.jdbc.Driver"/>
+ <param name="url" value="jdbc:mysql://host_name:3306/datebase_name"/>
+ <param name="user" value="logback"/>
+ <param name="password" value="logback"/>
+ </connectionSource>
+ </appender>
+
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <param name="pattern" value="%p %t %c - %m%n"/>
+ </layout>
+ </appender>
+ <root>
+ <level value="debug"/>
+ <appender-ref ref="STDOUT"/>
+ <appender-ref ref="DB"/>
+ </root>
+</configuration>
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java Fri Sep 22 17:12:36 2006
@@ -0,0 +1,7 @@
+package ch.qos.logback.classic.db;
+
+import junit.framework.TestCase;
+
+public class DBAppenderTest extends TestCase {
+
+}
1
0

21 Sep '06
Author: seb
Date: Thu Sep 21 15:57:39 2006
New Revision: 597
Added:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CssBuilder.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java
Removed:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/helpers/CssBuilder.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/IThrowableRenderer.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/NOPThrowableRenderer.java
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
Log:
- created HTMLLayoutBase
- updated HTMLLayout accordingly
- moved some classes to core module when appropriate.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java Thu Sep 21 15:57:39 2006
@@ -4,6 +4,7 @@
import ch.qos.logback.classic.helpers.Transform;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.ThrowableInformation;
+import ch.qos.logback.core.html.IThrowableRenderer;
public class DefaultThrowableRenderer implements IThrowableRenderer {
@@ -37,7 +38,8 @@
}
}
- public void render(StringBuffer sbuf, LoggingEvent event) {
+ public void render(StringBuffer sbuf, Object eventObject) {
+ LoggingEvent event = (LoggingEvent)eventObject;
ThrowableInformation ti = event.getThrowableInformation();
if (ti != null) {
render(sbuf, ti.getThrowableStrRep());
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 Thu Sep 21 15:57:39 2006
@@ -10,16 +10,13 @@
package ch.qos.logback.classic.html;
+import java.util.Map;
+
import ch.qos.logback.classic.ClassicLayout;
import ch.qos.logback.classic.PatternLayout;
-import ch.qos.logback.classic.helpers.CssBuilder;
import ch.qos.logback.classic.spi.LoggingEvent;
-import ch.qos.logback.core.LayoutBase;
+import ch.qos.logback.core.html.HTMLLayoutBase;
import ch.qos.logback.core.pattern.Converter;
-import ch.qos.logback.core.pattern.DynamicConverter;
-import ch.qos.logback.core.pattern.parser.Node;
-import ch.qos.logback.core.pattern.parser.Parser;
-import ch.qos.logback.core.pattern.parser.ScanException;
/**
*
@@ -83,7 +80,7 @@
* @author Ceki Gülcü
* @author Sébastien Pennec
*/
-public class HTMLLayout extends LayoutBase implements ClassicLayout {
+public class HTMLLayout extends HTMLLayoutBase implements ClassicLayout {
/**
* Default pattern string for log output. Currently set to the string <b>"%m"
@@ -91,21 +88,6 @@
*/
static final String DEFAULT_CONVERSION_PATTERN = "%date%thread%level%logger%mdc%msg";
- private String pattern;
-
- private Converter head;
-
- private String title = "Logback Log Messages";
-
- private CssBuilder cssBuilder;
-
- IThrowableRenderer throwableRenderer = new DefaultThrowableRenderer();
-
- // counter keeping track of the rows output
- private long counter = 0;
- // max number of rows before we close the table and create a new one
- private static final int ROW_LIMIT = 10000;
-
/**
* Constructs a PatternLayout using the DEFAULT_LAYOUT_PATTERN.
*
@@ -114,167 +96,9 @@
public HTMLLayout() {
pattern = DEFAULT_CONVERSION_PATTERN;
}
-
- /**
- * Set the <b>ConversionPattern </b> option. This is the string which controls
- * formatting and consists of a mix of literal content and conversion
- * specifiers.
- */
- public void setPattern(String conversionPattern) {
- pattern = conversionPattern;
- }
-
- /**
- * Returns the value of the <b>ConversionPattern </b> option.
- */
- public String getPattern() {
- return pattern;
- }
-
- public CssBuilder getCssBuilder() {
- return cssBuilder;
- }
-
- public void setCssBuilder(CssBuilder cssBuilder) {
- this.cssBuilder = cssBuilder;
- }
-
- /**
- * Parses the pattern and creates the Converter linked list.
- */
- @Override
- public void start() {
- int errorCount = 0;
-
- if (throwableRenderer == null) {
- addError("ThrowableRender cannot be null.");
- errorCount++;
- }
-
- try {
- Parser p = new Parser(pattern);
- if (getContext() != null) {
- p.setStatusManager(getContext().getStatusManager());
- }
- Node t = p.parse();
- this.head = p.compile(t, PatternLayout.defaultConverterMap);
- DynamicConverter.startConverters(this.head);
- } catch (ScanException ex) {
- addError("Incorrect pattern found", ex);
- errorCount++;
- }
-
- if (errorCount == 0) {
- started = true;
- }
- }
-
- /**
- * The <b>Title </b> option takes a String value. This option sets the
- * document title of the generated HTML document.
- *
- * <p>
- * Defaults to 'Logback Log Messages'.
- */
- public void setTitle(String title) {
- this.title = title;
- }
-
- /**
- * Returns the current value of the <b>Title </b> option.
- */
- public String getTitle() {
- return title;
- }
-
- /**
- * Returns the content type output by this layout, i.e "text/html".
- */
- @Override
- public String getContentType() {
- return "text/html";
- }
-
- /**
- * Returns appropriate HTML headers.
- */
- @Override
- public String getHeader() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
- sbuf.append(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
- sbuf.append(LINE_SEP);
- sbuf.append("<html>");
- sbuf.append(LINE_SEP);
- sbuf.append("<head>");
- sbuf.append(LINE_SEP);
- sbuf.append("<title>");
- sbuf.append(title);
- sbuf.append("</title>");
- sbuf.append(LINE_SEP);
- if (cssBuilder == null) {
- CssBuilder.addDefaultCSS(sbuf);
- } else {
- cssBuilder.addExternalCSS(sbuf);
- }
- sbuf.append(LINE_SEP);
- sbuf.append("</head>");
- sbuf.append(LINE_SEP);
- sbuf.append("<body>");
- sbuf.append(LINE_SEP);
-
- sbuf.append("<hr size=\"1\" noshade=\"true\" />");
- sbuf.append(LINE_SEP);
-
- sbuf.append("Log session start time ");
- sbuf.append(new java.util.Date());
- sbuf.append("<br />");
- sbuf.append(LINE_SEP);
- sbuf.append("<br />");
- sbuf.append(LINE_SEP);
- sbuf.append("<table cellspacing=\"0\">");
- sbuf.append(LINE_SEP);
-
- createTableHeader(sbuf);
-
- return sbuf.toString();
- }
-
- private void createTableHeader(StringBuffer sbuf) {
- Converter c = head;
- String name;
- sbuf.append("<tr class=\"header\">");
- sbuf.append(LINE_SEP);
- while (c != null) {
- name = computeConverterName(c);
- if (name == null) {
- c = c.getNext();
- continue;
- }
- sbuf.append("<td class=\"");
- sbuf.append(computeConverterName(c));
- sbuf.append("\">");
- sbuf.append(computeConverterName(c));
- sbuf.append("</td>");
- sbuf.append(LINE_SEP);
- c = c.getNext();
- }
- sbuf.append("</tr>");
- sbuf.append(LINE_SEP);
- }
-
- /**
- * Returns the appropriate HTML footers.
- */
- @Override
- public String getFooter() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("</table>");
- sbuf.append(LINE_SEP);
- sbuf.append("<br>");
- sbuf.append(LINE_SEP);
- sbuf.append("</body></html>");
- return sbuf.toString();
+
+ protected Map<String, String> getDefaultConverterMap() {
+ return PatternLayout.defaultConverterMap;
}
public String doLayout(Object event) {
@@ -316,18 +140,6 @@
return buf.toString();
}
- private void handleTableClosing(StringBuffer sbuf) {
- if (this.counter >= ROW_LIMIT) {
- counter = 0;
- sbuf.append("</table>");
- sbuf.append(LINE_SEP);
- sbuf.append("<br />");
- sbuf.append("<table cellspacing=\"0\">");
- sbuf.append(LINE_SEP);
- createTableHeader(sbuf);
- }
- }
-
private void appendEventToBuffer(StringBuffer buf, Converter c,
LoggingEvent event) {
buf.append("<td class=\"");
@@ -337,24 +149,4 @@
buf.append("</td>");
buf.append(LINE_SEP);
}
-
- private String computeConverterName(Converter c) {
- String className = c.getClass().getSimpleName();
- int index = className.indexOf("Converter");
- if (index == -1) {
- return className;
- } else {
- return className.substring(0, index);
- }
- }
-
- public IThrowableRenderer getThrowableRenderer() {
- return throwableRenderer;
- }
-
- public void setThrowableRenderer(IThrowableRenderer throwableRenderer) {
- this.throwableRenderer = throwableRenderer;
- }
-
-
}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java Thu Sep 21 15:57:39 2006
@@ -66,7 +66,7 @@
public void testAppendThrowable() throws Exception {
StringBuffer buf = new StringBuffer();
String[] strArray = { "test1", "test2" };
- DefaultThrowableRenderer renderer = (DefaultThrowableRenderer)layout.throwableRenderer;
+ DefaultThrowableRenderer renderer = (DefaultThrowableRenderer)layout.getThrowableRenderer();
renderer.render(buf, strArray);
System.out.println(buf.toString());
String[] result = buf.toString().split(HTMLLayout.LINE_SEP);
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CssBuilder.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CssBuilder.java Thu Sep 21 15:57:39 2006
@@ -0,0 +1,81 @@
+/**
+ * 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.helpers;
+
+import static ch.qos.logback.core.Layout.LINE_SEP;
+
+/**
+ * This class helps the HTMLLayout build the CSS link.
+ * It either provides the HTMLLayout with a default css file,
+ * or builds the link to an external, user-specified, file.
+ *
+ * @author Sébastien Pennec
+ */
+public class CssBuilder {
+
+ String url;
+
+ public CssBuilder() {
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public void addExternalCSS(StringBuffer sbuf) {
+ sbuf.append("<LINK REL=StyleSheet HREF=\"");
+ sbuf.append(url);
+ sbuf.append("\" TITLE=\"Basic\" />");
+ }
+
+ public static void addDefaultCSS(StringBuffer buf) {
+ buf.append("<STYLE type=\"text/css\">");
+ buf.append(LINE_SEP);
+ buf.append("table { margin-left: 2em; margin-right: 2em; border-left: 2px solid #AAA; }");
+ buf.append(LINE_SEP);
+
+ buf.append("TR.even { background: #FFFFFF; }");
+ buf.append(LINE_SEP);
+
+ buf.append("TR.odd { background: #DADADA; }");
+ buf.append(LINE_SEP);
+
+ buf.append("TR.warn TD.level, TR.error TD.level, TR.fatal TD.level {font-weight: bold; color: #FF4040 }");
+ buf.append(LINE_SEP);
+
+ buf.append("TD { padding-right: 1ex; padding-left: 1ex; border-right: 2px solid #AAA; }");
+ buf.append(LINE_SEP);
+
+ buf.append("TD.Time, TD.Date { text-align: right; font-family: courier, monospace; font-size: smaller; }");
+ buf.append(LINE_SEP);
+
+ buf.append("TD.Thread { text-align: left; }");
+ buf.append(LINE_SEP);
+
+ buf.append("TD.Level { text-align: right; }");
+ buf.append(LINE_SEP);
+
+ buf.append("TD.Logger { text-align: left; }");
+ buf.append(LINE_SEP);
+
+ buf.append("TR.header { background: #9090FF; color: #FFF; font-weight: bold; font-size: larger; }");
+ buf.append(LINE_SEP);
+
+ buf.append("TD.Exception { background: #C0C0F0; font-family: courier, monospace;}");
+ buf.append(LINE_SEP);
+
+ buf.append("</STYLE>");
+ buf.append(LINE_SEP);
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java Thu Sep 21 15:57:39 2006
@@ -0,0 +1,232 @@
+package ch.qos.logback.core.html;
+
+import java.util.Map;
+
+import ch.qos.logback.core.LayoutBase;
+import ch.qos.logback.core.helpers.CssBuilder;
+import ch.qos.logback.core.pattern.Converter;
+import ch.qos.logback.core.pattern.DynamicConverter;
+import ch.qos.logback.core.pattern.parser.Node;
+import ch.qos.logback.core.pattern.parser.Parser;
+import ch.qos.logback.core.pattern.parser.ScanException;
+
+/**
+ * This class is a base class for logback component-specific HTMLLayout classes
+ *
+ * @author Sébastien Pennec
+ */
+public abstract class HTMLLayoutBase extends LayoutBase {
+
+ protected String pattern;
+
+ protected Converter head;
+
+ protected String title = "Logback Log Messages";
+
+ protected CssBuilder cssBuilder;
+
+ protected IThrowableRenderer throwableRenderer; //no more initialization ??????
+
+ // counter keeping track of the rows output
+ protected long counter = 0;
+ // max number of rows before we close the table and create a new one
+ protected static final int ROW_LIMIT = 10000;
+
+ /**
+ * Set the <b>ConversionPattern </b> option. This is the string which controls
+ * formatting and consists of a mix of literal content and conversion
+ * specifiers.
+ */
+ public void setPattern(String conversionPattern) {
+ pattern = conversionPattern;
+ }
+
+ /**
+ * Returns the value of the <b>ConversionPattern </b> option.
+ */
+ public String getPattern() {
+ return pattern;
+ }
+
+ public CssBuilder getCssBuilder() {
+ return cssBuilder;
+ }
+
+ public void setCssBuilder(CssBuilder cssBuilder) {
+ this.cssBuilder = cssBuilder;
+ }
+
+ /**
+ * Parses the pattern and creates the Converter linked list.
+ */
+ @Override
+ public void start() {
+ int errorCount = 0;
+
+ if (throwableRenderer == null) {
+ addError("ThrowableRender cannot be null.");
+ errorCount++;
+ }
+
+ try {
+ Parser p = new Parser(pattern);
+ if (getContext() != null) {
+ p.setStatusManager(getContext().getStatusManager());
+ }
+ Node t = p.parse();
+ this.head = p.compile(t, getDefaultConverterMap());
+ DynamicConverter.startConverters(this.head);
+ } catch (ScanException ex) {
+ addError("Incorrect pattern found", ex);
+ errorCount++;
+ }
+
+ if (errorCount == 0) {
+ started = true;
+ }
+ }
+
+ protected abstract Map<String, String> getDefaultConverterMap();
+
+ /**
+ * The <b>Title </b> option takes a String value. This option sets the
+ * document title of the generated HTML document.
+ *
+ * <p>
+ * Defaults to 'Logback Log Messages'.
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ /**
+ * Returns the current value of the <b>Title </b> option.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Returns the content type output by this layout, i.e "text/html".
+ */
+ @Override
+ public String getContentType() {
+ return "text/html";
+ }
+
+ /**
+ * Returns appropriate HTML headers.
+ */
+ @Override
+ public String getHeader() {
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
+ sbuf.append(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
+ sbuf.append(LINE_SEP);
+ sbuf.append("<html>");
+ sbuf.append(LINE_SEP);
+ sbuf.append("<head>");
+ sbuf.append(LINE_SEP);
+ sbuf.append("<title>");
+ sbuf.append(title);
+ sbuf.append("</title>");
+ sbuf.append(LINE_SEP);
+ if (cssBuilder == null) {
+ CssBuilder.addDefaultCSS(sbuf);
+ } else {
+ cssBuilder.addExternalCSS(sbuf);
+ }
+ sbuf.append(LINE_SEP);
+ sbuf.append("</head>");
+ sbuf.append(LINE_SEP);
+ sbuf.append("<body>");
+ sbuf.append(LINE_SEP);
+
+ sbuf.append("<hr size=\"1\" noshade=\"true\" />");
+ sbuf.append(LINE_SEP);
+
+ sbuf.append("Log session start time ");
+ sbuf.append(new java.util.Date());
+ sbuf.append("<br />");
+ sbuf.append(LINE_SEP);
+ sbuf.append("<br />");
+ sbuf.append(LINE_SEP);
+ sbuf.append("<table cellspacing=\"0\">");
+ sbuf.append(LINE_SEP);
+
+ createTableHeader(sbuf);
+
+ return sbuf.toString();
+ }
+
+
+ private void createTableHeader(StringBuffer sbuf) {
+ Converter c = head;
+ String name;
+ sbuf.append("<tr class=\"header\">");
+ sbuf.append(LINE_SEP);
+ while (c != null) {
+ name = computeConverterName(c);
+ if (name == null) {
+ c = c.getNext();
+ continue;
+ }
+ sbuf.append("<td class=\"");
+ sbuf.append(computeConverterName(c));
+ sbuf.append("\">");
+ sbuf.append(computeConverterName(c));
+ sbuf.append("</td>");
+ sbuf.append(LINE_SEP);
+ c = c.getNext();
+ }
+ sbuf.append("</tr>");
+ sbuf.append(LINE_SEP);
+ }
+
+ /**
+ * Returns the appropriate HTML footers.
+ */
+ @Override
+ public String getFooter() {
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.append("</table>");
+ sbuf.append(LINE_SEP);
+ sbuf.append("<br>");
+ sbuf.append(LINE_SEP);
+ sbuf.append("</body></html>");
+ return sbuf.toString();
+ }
+
+ protected void handleTableClosing(StringBuffer sbuf) {
+ if (this.counter >= ROW_LIMIT) {
+ counter = 0;
+ sbuf.append("</table>");
+ sbuf.append(LINE_SEP);
+ sbuf.append("<br />");
+ sbuf.append("<table cellspacing=\"0\">");
+ sbuf.append(LINE_SEP);
+ createTableHeader(sbuf);
+ }
+ }
+
+ protected String computeConverterName(Converter c) {
+ String className = c.getClass().getSimpleName();
+ int index = className.indexOf("Converter");
+ if (index == -1) {
+ return className;
+ } else {
+ return className.substring(0, index);
+ }
+ }
+
+ public IThrowableRenderer getThrowableRenderer() {
+ return throwableRenderer;
+ }
+
+ public void setThrowableRenderer(IThrowableRenderer throwableRenderer) {
+ this.throwableRenderer = throwableRenderer;
+ }
+
+
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java Thu Sep 21 15:57:39 2006
@@ -0,0 +1,8 @@
+package ch.qos.logback.core.html;
+
+
+public interface IThrowableRenderer {
+
+ public void render(StringBuffer sbuf, Object event);
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java Thu Sep 21 15:57:39 2006
@@ -0,0 +1,12 @@
+package ch.qos.logback.core.html;
+
+import ch.qos.logback.core.html.IThrowableRenderer;
+
+
+public class NOPThrowableRenderer implements IThrowableRenderer {
+
+ public void render(StringBuffer sbuf, Object event) {
+ return;
+ }
+
+}
1
0
I've already contacted them by leaving a comment on their website.
--
Ceki Gülcü
1
0
Boris,
Thank you for bringing the existence of the logbag prokect to our attention.
I had not heard of it before. The logback and logback projets are not
related in any way, except the sound of their names. We should contact them,
asking them politely whether they know about our project (logback) and
whether they would not mind renaming theirs (logbag).
Cheers,
--
Ceki Gülcü
1
0

svn commit: r596 - 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/pattern test/java/ch/qos/logback/access/pattern/helpers
by noreply.seb@qos.ch 20 Sep '06
by noreply.seb@qos.ch 20 Sep '06
20 Sep '06
Author: seb
Date: Wed Sep 20 17:03:16 2006
New Revision: 596
Added:
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/spi/ServerAdapter.java
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyValuesAdapter.java
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/pattern/ConverterTest.java
Log:
- added a ServerAdapter interface to allow the server-independent AccessEvent to reach server-specific methods
- impemented this interface in JettyServerAdapter and DummyValuesAdapter, the latter used for testing only.
- updated ConverterTest.
Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java Wed Sep 20 17:03:16 2006
@@ -0,0 +1,35 @@
+package ch.qos.logback.access.jetty;
+
+import org.mortbay.jetty.Request;
+import org.mortbay.jetty.Response;
+
+import ch.qos.logback.access.spi.ServerAdapter;
+
+/**
+ * A jetty specific implementation of the {@link ServerAdapter} interface.
+ *
+ * @author Sébastien Pennec
+ */
+public class JettyServerAdapter implements ServerAdapter {
+
+ Request request;
+ Response response;
+
+ public JettyServerAdapter(Request jettyRequest, Response jettyResponse) {
+ this.request = jettyRequest;
+ this.response = jettyResponse;
+ }
+
+ public long getContentLength() {
+ return response.getContentCount();
+ }
+
+ public int getStatusCode() {
+ return response.getStatus();
+ }
+
+ 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 20 17:03:16 2006
@@ -27,7 +27,8 @@
String filename;
public void log(Request jettyRequest, Response jettyResponse) {
- AccessEvent accessEvent = new AccessEvent(jettyRequest, jettyResponse);
+ JettyServerAdapter adapter = new JettyServerAdapter(jettyRequest, jettyResponse);
+ AccessEvent accessEvent = new AccessEvent(jettyRequest, jettyResponse, adapter);
// TODO better exception handling
aai.appendLoopOnAppenders(accessEvent);
}
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 20 17:03:16 2006
@@ -9,8 +9,6 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.mortbay.jetty.Response;
-
import ch.qos.logback.access.pattern.AccessConverter;
public class AccessEvent implements Serializable {
@@ -31,26 +29,27 @@
String protocol;
String method;
String serverName;
-
- Map requestHeaderMap;
+
+ Map<String, Object> requestHeaderMap;
long contentLength = SENTINEL;
int statusCode = SENTINEL;
int localPort = SENTINEL;
+ ServerAdapter serverAdapter;
+
/**
* The number of milliseconds elapsed from 1/1/1970 until logging event was
* created.
*/
private long timeStamp = 0;
-
-
public AccessEvent(HttpServletRequest httpRequest,
- HttpServletResponse httpResponse) {
+ HttpServletResponse httpResponse, ServerAdapter adapter) {
this.httpRequest = httpRequest;
this.httpResponse = httpResponse;
this.timeStamp = System.currentTimeMillis();
+ this.serverAdapter = adapter;
}
public long getTimeStamp() {
@@ -159,7 +158,6 @@
return serverName;
}
-
public String getRemoteAddr() {
if (remoteAddr == null) {
if (httpRequest != null) {
@@ -190,25 +188,18 @@
}
public void buildRequestHeaderMap() {
- requestHeaderMap = new HashMap();
+ requestHeaderMap = new HashMap<String, Object>();
Enumeration e = httpRequest.getHeaderNames();
- while(e.hasMoreElements()) {
+ while (e.hasMoreElements()) {
String key = (String) e.nextElement();
requestHeaderMap.put(key, httpRequest.getHeader(key));
}
}
-
+
public String getResponseHeader(String key) {
- //TODO buildMap
- if (httpResponse instanceof org.mortbay.jetty.Response) {
- return ((org.mortbay.jetty.Response)httpResponse).getHeader(key);
- }
- if (httpResponse instanceof ch.qos.logback.access.pattern.helpers.DummyResponse) {
- return ((ch.qos.logback.access.pattern.helpers.DummyResponse)httpResponse).getHeader(key);
- }
-
- return null;
+ return serverAdapter.getResponseHeader(key);
}
+
/**
* Attributes are not serialized
*
@@ -248,15 +239,20 @@
public long getContentLength() {
if (contentLength == SENTINEL) {
if (httpResponse != null) {
- if (httpResponse instanceof org.mortbay.jetty.Response) {
- // TODO
- } else if (httpResponse instanceof com.caucho.server.connection.AbstractHttpResponse) {
- contentLength = ((com.caucho.server.connection.AbstractHttpResponse) httpResponse)
- .getContentLength();
- } else if (httpResponse instanceof org.apache.catalina.connector.Response) {
- contentLength = ((org.apache.catalina.connector.Response) httpResponse)
- .getContentLength();
- }
+ return serverAdapter.getContentLength();
+ // if (httpResponse instanceof org.mortbay.jetty.Response) {
+ // // TODO
+ // } else if (httpResponse instanceof
+ // com.caucho.server.connection.AbstractHttpResponse) {
+ // contentLength = ((com.caucho.server.connection.AbstractHttpResponse)
+ // httpResponse)
+ // .getContentLength();
+ // } else if (httpResponse instanceof
+ // org.apache.catalina.connector.Response) {
+ // contentLength = ((org.apache.catalina.connector.Response)
+ // httpResponse)
+ // .getContentLength();
+ // }
}
}
return contentLength;
@@ -265,15 +261,19 @@
public int getStatusCode() {
if (statusCode == SENTINEL) {
if (httpResponse != null) {
- if (httpResponse instanceof org.mortbay.jetty.Response) {
- statusCode = ((org.mortbay.jetty.Response) httpResponse).getStatus();
- } else if (httpResponse instanceof com.caucho.server.connection.AbstractHttpResponse) {
- statusCode = ((com.caucho.server.connection.AbstractHttpResponse) httpResponse)
- .getStatusCode();
- } else if (httpResponse instanceof org.apache.catalina.connector.Response) {
- statusCode = ((org.apache.catalina.connector.Response) httpResponse)
- .getStatus();
- }
+ return serverAdapter.getStatusCode();
+ // if (httpResponse instanceof org.mortbay.jetty.Response) {
+ // statusCode = ((org.mortbay.jetty.Response) httpResponse).getStatus();
+ // } else if (httpResponse instanceof
+ // com.caucho.server.connection.AbstractHttpResponse) {
+ // statusCode = ((com.caucho.server.connection.AbstractHttpResponse)
+ // httpResponse)
+ // .getStatusCode();
+ // } else if (httpResponse instanceof
+ // org.apache.catalina.connector.Response) {
+ // statusCode = ((org.apache.catalina.connector.Response) httpResponse)
+ // .getStatus();
+ // }
}
}
return statusCode;
@@ -288,4 +288,8 @@
}
return localPort;
}
+
+ public ServerAdapter getServerAdapter() {
+ return serverAdapter;
+ }
}
\ No newline at end of file
Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/ServerAdapter.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/ServerAdapter.java Wed Sep 20 17:03:16 2006
@@ -0,0 +1,15 @@
+package ch.qos.logback.access.spi;
+
+/**
+ * An interface to access server-specific methods from
+ * the server-independent AccessEvent.
+ *
+ * @author Ceki Gülcü
+ * @author Sébastien Pennec
+ */
+public interface ServerAdapter {
+
+ long getContentLength();
+ int getStatusCode();
+ String getResponseHeader(String key);
+}
Modified: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/ConverterTest.java
==============================================================================
--- logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/ConverterTest.java (original)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/ConverterTest.java Wed Sep 20 17:03:16 2006
@@ -10,6 +10,7 @@
import junit.framework.TestCase;
import ch.qos.logback.access.pattern.helpers.DummyRequest;
import ch.qos.logback.access.pattern.helpers.DummyResponse;
+import ch.qos.logback.access.pattern.helpers.DummyValuesAdapter;
import ch.qos.logback.access.spi.AccessEvent;
public class ConverterTest extends TestCase {
@@ -33,7 +34,10 @@
}
public void testContentLengthConverter() {
- // TODO when AccessEvent has been modified
+ ContentLengthConverter converter = new ContentLengthConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(Long.toString(event.getServerAdapter().getContentLength()), result);
}
public void testDateConverter() {
@@ -150,11 +154,15 @@
}
public void testStatusCodeConverter() {
- //TODO
+ StatusCodeConverter converter = new StatusCodeConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(Integer.toString(event.getServerAdapter().getStatusCode()), result);
}
private AccessEvent createEvent() {
- AccessEvent ae = new AccessEvent(request, response);
+ DummyValuesAdapter dummyAdapter = new DummyValuesAdapter(request, response);
+ AccessEvent ae = new AccessEvent(request, response, dummyAdapter);
return ae;
}
Added: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyValuesAdapter.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyValuesAdapter.java Wed Sep 20 17:03:16 2006
@@ -0,0 +1,35 @@
+package ch.qos.logback.access.pattern.helpers;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import ch.qos.logback.access.spi.ServerAdapter;
+
+/**
+ * A test-only implementation of the {@link ServerAdapter} interface.
+ *
+ * @author Sébastien Pennec
+ */
+public class DummyValuesAdapter implements ServerAdapter {
+
+ DummyRequest request;
+ DummyResponse response;
+
+ public DummyValuesAdapter(HttpServletRequest request, HttpServletResponse response) {
+ this.request = (DummyRequest)request;
+ this.response = (DummyResponse)response;
+ }
+
+ public long getContentLength() {
+ return 123L;
+ }
+
+ public String getResponseHeader(String key) {
+ return response.getHeader(key);
+ }
+
+ public int getStatusCode() {
+ return 1;
+ }
+
+}
1
0

svn commit: r595 - logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling
by noreply.seb@qos.ch 19 Sep '06
by noreply.seb@qos.ch 19 Sep '06
19 Sep '06
Author: seb
Date: Tue Sep 19 16:53:10 2006
New Revision: 595
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
Log:
- corrected javadoc
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java Tue Sep 19 16:53:10 2006
@@ -24,13 +24,13 @@
* <configuration>
* <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
* <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- * <param name="ActiveFile" value="outputFile.log" />
+ * <param name="ActiveFileName" value="outputFile.log" />
* <param name="FileNamePattern" value="logFile.%i.log" />
* <param name="MinIndex" value="1" />
* <param name="MaxIndex" value="3" />
* </rollingPolicy>
*
- * <b><triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedRollingPolicy">
+ * <b><triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
* <param name="MaxFileSize" value="5MB" />
* </triggeringPolicy></b>
*
1
0