logback-dev
Threads by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- 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
[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.29-10-g6e98d1b
by git-noreply@pixie.qos.ch 01 Jul '11
by git-noreply@pixie.qos.ch 01 Jul '11
01 Jul '11
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 6e98d1bb0c1c728aafaf64846207603b0f482946 (commit)
from 187647c5d3552e665cf365cf0fdfdf4023227b02 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=6e98d1bb0c1c728aafaf6484…
http://github.com/ceki/logback/commit/6e98d1bb0c1c728aafaf64846207603b0f482…
commit 6e98d1bb0c1c728aafaf64846207603b0f482946
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Fri Jul 1 18:31:23 2011 +0200
fixing LBCLASSIC-273
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java b/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java
index b0e0693..1dae9d6 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java
@@ -208,10 +208,13 @@ public class LoggerContext extends ContextBase implements ILoggerFactory,
}
/**
- * This method clears all internal properties, closes all appenders, removes
- * any turboFilters, fires an OnReset event, removes all status listeners,
- * removes all context listeners (except those which are reset resistant).
- */
+ * This method clears all internal properties, except internal status messages,
+ * closes all appenders, removes any turboFilters, fires an OnReset event,
+ * removes all status listeners, removes all context listeners
+ * (except those which are reset resistant).
+ * <p>
+ * As mentioned above, internal status messages survive resets.
+ * */
@Override
public void reset() {
resetCount++;
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConfigurationAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConfigurationAction.java
index 11fa9c5..6369585 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConfigurationAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConfigurationAction.java
@@ -30,10 +30,11 @@ public class ConfigurationAction extends Action {
static final String SCAN_PERIOD_ATTR = "scanPeriod";
boolean debugMode = false;
+ long threshold = 0;
public void begin(InterpretationContext ec, String name, Attributes attributes) {
String debugAttrib = ec.subst(attributes.getValue(INTERNAL_DEBUG_ATTR));
-
+ threshold = System.currentTimeMillis();
if (OptionHelper.isEmpty(debugAttrib)
|| debugAttrib.equalsIgnoreCase("false")
|| debugAttrib.equalsIgnoreCase("null")) {
@@ -79,7 +80,7 @@ public class ConfigurationAction extends Action {
if (debugMode) {
addInfo("End of configuration.");
LoggerContext loggerContext = (LoggerContext) context;
- StatusPrinter.print(loggerContext);
+ StatusPrinter.print(loggerContext, threshold);
}
ec.popObject();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
index cf12305..18f81cc 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
@@ -13,7 +13,6 @@
*/
package ch.qos.logback.core.status;
-import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
@@ -22,6 +21,8 @@ import java.util.regex.Pattern;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.CoreConstants;
+import static ch.qos.logback.core.status.StatusUtil.filterStatusListByTimeThreshold;
+
public class StatusChecker {
StatusManager sm;
@@ -34,18 +35,10 @@ public class StatusChecker {
this.sm = context.getStatusManager();
}
- private List<Status> filterStatusListByTimeThreshold(List<Status> rawList, long threshold) {
- List<Status> filteredList = new ArrayList<Status>();
- for (Status s : rawList) {
- if (s.getDate() >= threshold)
- filteredList.add(s);
- }
- return filteredList;
- }
-
public boolean hasXMLParsingErrors(long threshold) {
return containsMatch(threshold, Status.ERROR, CoreConstants.XML_PARSING);
}
+
public boolean noXMLParsingErrorsOccurred(long threshold) {
return !hasXMLParsingErrors(threshold);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusUtil.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusUtil.java
index d246c8b..c57daad 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusUtil.java
@@ -15,8 +15,20 @@ package ch.qos.logback.core.status;
import ch.qos.logback.core.Context;
+import java.util.ArrayList;
+import java.util.List;
+
public class StatusUtil {
+ static public List<Status> filterStatusListByTimeThreshold(List<Status> rawList, long threshold) {
+ List<Status> filteredList = new ArrayList<Status>();
+ for (Status s : rawList) {
+ if (s.getDate() >= threshold)
+ filteredList.add(s);
+ }
+ return filteredList;
+ }
+
static public void addStatus(Context context, Status status) {
if (context == null) {
return;
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java b/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
index 40394cd..2794a22 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
@@ -25,6 +25,8 @@ import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.status.StatusManager;
+import static ch.qos.logback.core.status.StatusUtil.filterStatusListByTimeThreshold;
+
public class StatusPrinter {
private static PrintStream ps = System.out;
@@ -88,26 +90,39 @@ public class StatusPrinter {
* @param context
*/
public static void print(Context context) {
- if (context == null) {
- throw new IllegalArgumentException("Context argument cannot be null");
- }
+ print(context, 0);
+ }
- StatusManager sm = context.getStatusManager();
- if (sm == null) {
- ps.println("WARN: Context named \"" + context.getName()
- + "\" has no status manager");
- } else {
- print(sm);
- }
+ /**
+ * Print context's status data with a timestamp higher than the threshold.
+ * @param context
+ */
+ public static void print(Context context, long threshold) {
+ if (context == null) {
+ throw new IllegalArgumentException("Context argument cannot be null");
+ }
+
+ StatusManager sm = context.getStatusManager();
+ if (sm == null) {
+ ps.println("WARN: Context named \"" + context.getName()
+ + "\" has no status manager");
+ } else {
+ print(sm, threshold);
+ }
+ }
+ public static void print(StatusManager sm) {
+ print(sm, 0);
}
- public static void print(StatusManager sm) {
+ public static void print(StatusManager sm, long threshold) {
StringBuilder sb = new StringBuilder();
- buildStrFromStatusManager(sb, sm);
+ List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
+ buildStrFromStatusList(sb, filteredList);
ps.println(sb.toString());
}
+
public static void print(List<Status> statusList) {
StringBuilder sb = new StringBuilder();
buildStrFromStatusList(sb, statusList);
@@ -123,9 +138,9 @@ public class StatusPrinter {
}
}
- private static void buildStrFromStatusManager(StringBuilder sb, StatusManager sm) {
- buildStrFromStatusList(sb, sm.getCopyOfStatusList());
- }
+// private static void buildStrFromStatusManager(StringBuilder sb, StatusManager sm) {
+// }
+
private static void appendThrowable(StringBuilder sb, Throwable t) {
String[] stringRep = ThrowableToStringArray.convert(t);
diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html
index dedf41c..da477fd 100644
--- a/logback-site/src/site/pages/news.html
+++ b/logback-site/src/site/pages/news.html
@@ -42,6 +42,16 @@
class="option">to</span> properties are suported.
</p>
+ <p>When debug attribute is set to true within
+ <code><the></code> configuration element, status messages are
+ printed on the console after Joran (re)configures
+ logback. Previously, all status messages were printed. With this
+ release, only status messages created during (re)configuration are
+ printed. This change fixes <a
+ href="http://jira.qos.ch/browse/LBCLASSIC-273">/LBCLASSIC-273</a>
+ reported by Joern Huxhorn.
+ </p>
+
<hr width="80%" align="center" />
<h3>June 9th, 2011 - Release of version 0.9.29</h3>
-----------------------------------------------------------------------
Summary of changes:
.../java/ch/qos/logback/classic/LoggerContext.java | 11 +++--
.../classic/joran/action/ConfigurationAction.java | 5 +-
.../ch/qos/logback/core/status/StatusChecker.java | 13 +----
.../ch/qos/logback/core/status/StatusUtil.java | 12 +++++
.../ch/qos/logback/core/util/StatusPrinter.java | 45 +++++++++++++-------
logback-site/src/site/pages/news.html | 10 ++++
6 files changed, 65 insertions(+), 31 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0
[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.29-9-g187647c
by git-noreply@pixie.qos.ch 29 Jun '11
by git-noreply@pixie.qos.ch 29 Jun '11
29 Jun '11
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 187647c5d3552e665cf365cf0fdfdf4023227b02 (commit)
from bca247de428261b8c99c2a02cc4fc8ca580d78d2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=187647c5d3552e665cf365cf…
http://github.com/ceki/logback/commit/187647c5d3552e665cf365cf0fdfdf4023227…
commit 187647c5d3552e665cf365cf0fdfdf4023227b02
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Wed Jun 29 12:34:45 2011 +0200
blurb about multiple email destinations separated by commas
diff --git a/logback-site/src/site/pages/manual/appenders.html b/logback-site/src/site/pages/manual/appenders.html
index f384485..72838df 100644
--- a/logback-site/src/site/pages/manual/appenders.html
+++ b/logback-site/src/site/pages/manual/appenders.html
@@ -1731,9 +1731,13 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<td>The email address of the recipient as a
<em>pattern</em>. The pattern is evaluated anew with the
triggering event as input for each outgoing email. Multiple
- recipients can be specified by using several
- <code><to></code> elements.</td>
+ recipients can be specified by separating the destination
+ addresses with commas. Alternatively, multiple recipients can
+ also be specified by using multiple <code><to></code>
+ elements.
+ </td>
</tr>
+
<tr class="alt">
<td><b><span class="option">from</span></b></td>
<td><code>String</code></td>
diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html
index fb530d1..dedf41c 100644
--- a/logback-site/src/site/pages/news.html
+++ b/logback-site/src/site/pages/news.html
@@ -28,6 +28,22 @@
<hr width="80%" align="center" />
+ <h3>July xxx, 2011 - Release of version 0.9.30</h3>
+
+ <p>It is now possible to specify multiple destination addresses
+ separated by commas in the the <span class="option">to</span>
+ property of <code>SMTPAppender</code>. This fixes <a
+ href="http://jira.qos.ch/browse/LBCORE-213">LBCORE-213</a>
+ reported by Alexandre Garnier who also provided the relevant
+ patch. In previous versions of logback multiple destination
+ addresses could only be specified by using multiple <span
+ class="option">to</span> properties. As of version 0.9.30 both
+ comma separated addresses and multiple <span
+ class="option">to</span> properties are suported.
+ </p>
+
+ <hr width="80%" align="center" />
+
<h3>June 9th, 2011 - Release of version 0.9.29</h3>
<p>Fixed <a
-----------------------------------------------------------------------
Summary of changes:
logback-site/src/site/pages/manual/appenders.html | 8 ++++++--
logback-site/src/site/pages/news.html | 16 ++++++++++++++++
2 files changed, 22 insertions(+), 2 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0
[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.29-8-gbca247d
by git-noreply@pixie.qos.ch 29 Jun '11
by git-noreply@pixie.qos.ch 29 Jun '11
29 Jun '11
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via bca247de428261b8c99c2a02cc4fc8ca580d78d2 (commit)
via 2b2edb0cc0d0e8c3f8c26a39e40811181aa4f632 (commit)
from 38d48fc3abfb16ca5a72668780ed5501ad3e422b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=bca247de428261b8c99c2a02…
http://github.com/ceki/logback/commit/bca247de428261b8c99c2a02cc4fc8ca580d7…
commit bca247de428261b8c99c2a02cc4fc8ca580d78d2
Merge: 38d48fc 2b2edb0
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Wed Jun 29 12:12:36 2011 +0200
Merge commit '2b2edb0cc0d0e8c3f8c26a39e40811181aa4f63'
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=2b2edb0cc0d0e8c3f8c26a39…
http://github.com/ceki/logback/commit/2b2edb0cc0d0e8c3f8c26a39e40811181aa4f…
commit 2b2edb0cc0d0e8c3f8c26a39e40811181aa4f632
Author: Alexandre Garnier <zigarn(a)gmail.com>
Date: Tue Jun 28 22:56:24 2011 +0200
Allow multiple recipient address in 1 <to> element in SMTPAppender (LBCORE-213)
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
index 9e4e4ba..0f39071 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
@@ -233,5 +233,20 @@ public class SMTPAppender_GreenTest {
assertEquals(msg, body);
}
+ @Test
+ public void testMultipleTo() throws Exception {
+ buildSMTPAppender();
+ smtpAppender.setLayout(buildPatternLayout(lc));
+ smtpAppender.addTo("Test <test(a)example.com>, other-test(a)example.com");
+ smtpAppender.start();
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+
+ StatusPrinter.print(lc);
+ MimeMessage[] mma = greenMail.getReceivedMessages();
+ assertNotNull(mma);
+ assertEquals(3, mma.length);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java
index 49cc3b4..13b9604 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java
@@ -307,6 +307,21 @@ public class SMTPAppender_SubethaSMTPTest {
StatusPrinter.print(lc);
}
+
+ @Test
+ public void testMultipleTo() throws Exception {
+ smtpAppender.setLayout(buildPatternLayout(lc));
+ smtpAppender.addTo("Test <test(a)example.com>, other-test(a)example.com");
+ smtpAppender.start();
+ Logger logger = lc.getLogger("test");
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+ List<WiserMessage> wiserMsgList = wiser.getMessages();
+
+ assertNotNull(wiserMsgList);
+ assertEquals(3, wiserMsgList.size());
+ }
public class TrivialAuthHandlerFactory implements AuthenticationHandlerFactory {
public AuthenticationHandler create() {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
index b692cd3..a0d72d0 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
@@ -14,6 +14,7 @@
package ch.qos.logback.core.net;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
@@ -266,8 +267,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
continue;
}
InternetAddress[] tmp = InternetAddress.parse(email, true);
- // one <To> element should contain one email address
- iaList.add(tmp[0]);
+ iaList.addAll(Arrays.asList(tmp));
} catch (AddressException e) {
addError("Could not parse email address for [" + toPatternLayoutList.get(i) + "] for event [" + event + "]", e);
return iaList;
-----------------------------------------------------------------------
Summary of changes:
.../classic/net/SMTPAppender_GreenTest.java | 15 +++++++++++++++
.../classic/net/SMTPAppender_SubethaSMTPTest.java | 15 +++++++++++++++
.../ch/qos/logback/core/net/SMTPAppenderBase.java | 4 ++--
3 files changed, 32 insertions(+), 2 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0
[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.29-6-g38d48fc
by git-noreply@pixie.qos.ch 24 Jun '11
by git-noreply@pixie.qos.ch 24 Jun '11
24 Jun '11
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 38d48fc3abfb16ca5a72668780ed5501ad3e422b (commit)
from 690ac09e30d017edea2681395b1fa33095f5f269 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=38d48fc3abfb16ca5a726687…
http://github.com/ceki/logback/commit/38d48fc3abfb16ca5a72668780ed5501ad3e4…
commit 38d48fc3abfb16ca5a72668780ed5501ad3e422b
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Fri Jun 24 14:01:54 2011 +0200
configuration recovery works with included files as well. Fixes LBCLASSIC-265
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
index 6615f51..9ffa390 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
@@ -19,9 +19,11 @@ import java.util.List;
import ch.qos.logback.classic.gaffer.GafferUtil;
import ch.qos.logback.classic.util.EnvUtil;
+import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.spi.ConfigurationWatchList;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
+import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.status.WarnStatus;
import org.slf4j.Marker;
@@ -175,34 +177,35 @@ public class ReconfigureOnChangeFilter extends TurboFilter {
jc.setContext(context);
StatusChecker statusChecker = new StatusChecker(context);
List<SaxEvent> eventList = jc.recallSafeConfiguration();
- lc.getStatusManager().add(
- new InfoStatus("Resetting the logging ", this));
+ URL mainURL = ConfigurationWatchListUtil.getMainWatchURL(context);
lc.reset();
-
+ long threshold = System.currentTimeMillis();
try {
jc.doConfigure(mainConfigurationURL);
+ if (statusChecker.hasXMLParsingErrors(threshold)) {
+ fallbackConfiguration(lc, eventList, mainURL);
+ }
} catch (JoranException e) {
- fallbackConfiguration(lc, eventList);
+ fallbackConfiguration(lc, eventList, mainURL);
}
}
- private void fallbackConfiguration(LoggerContext lc, List<SaxEvent> eventList) {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(context);
+ private void fallbackConfiguration(LoggerContext lc, List<SaxEvent> eventList, URL mainURL) {
+ JoranConfigurator joranConfigurator = new JoranConfigurator();
+ joranConfigurator.setContext(context);
if (eventList != null) {
- lc.getStatusManager().add(
- new WarnStatus("Falling back to previously registered safe configuration.", this));
+ addWarn("Falling back to previously registered safe configuration.");
try {
- jc.doConfigure(eventList);
- addInfo("Re-registering previous fallback configuration as a fallback point");
- jc.registerSafeConfiguration();
+ lc.reset();
+ joranConfigurator.informContextOfURLUsedForConfiguration(context, mainURL);
+ joranConfigurator.doConfigure(eventList);
+ addInfo("Re-registering previous fallback configuration once more as a fallback configuration point");
+ joranConfigurator.registerSafeConfiguration();
} catch (JoranException e) {
- addError("Unexpected exception thrown by configuration considered as safes", e);
+ addError("Unexpected exception thrown by a configuration considered safe.", e);
}
} else {
- lc.getStatusManager().add(
- new WarnStatus("No previous configuration to fall back to.", this));
-
+ addWarn("No previous configuration to fall back to.");
}
}
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
index 6def1ae..6004966 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
@@ -44,13 +44,14 @@ import ch.qos.logback.core.status.InfoStatus;
import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.testUtil.Env;
import ch.qos.logback.core.util.StatusPrinter;
+import sun.org.mozilla.javascript.internal.Context;
public class ReconfigureOnChangeTest {
final static int THREAD_COUNT = 5;
final static int LOOP_LEN = 1000 * 1000;
- static final boolean MUST_BE_ERROR_FREE = true;
- static final boolean ERRORS_EXPECTED = false;
+ static final boolean MUST_BE_ERROR_FREE = true;
+ static final boolean ERRORS_EXPECTED = false;
int diff = RandomUtil.getPositiveInt();
@@ -69,12 +70,18 @@ public class ReconfigureOnChangeTest {
final static String INCLUSION_SCAN_TOPLEVEL0_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ "turbo/inclusion/topLevel0.xml";
+ final static String INCLUSION_SCAN_TOPLEVEL2_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ + "turbo/inclusion/topLevel2.xml";
+
final static String INCLUSION_SCAN_TOP_BY_RESOURCE_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ "turbo/inclusion/topByResource.xml";
final static String INCLUSION_SCAN_INNER0_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ "turbo/inclusion/inner0.xml";
+ final static String INCLUSION_SCAN_INNER2_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ + "turbo/inclusion/inner2.xml";
+
final static String INCLUSION_SCAN_INNER1_AS_STR = "target/test-classes/asResource/inner1.xml";
@@ -148,27 +155,32 @@ public class ReconfigureOnChangeTest {
new InfoStatus("end of execution ", this));
long expectedReconfigurations = runnableArray[0].getCounter();
- if(forcedReconfigurationSkip)
+ if (forcedReconfigurationSkip)
expectedReconfigurations = 0;
verify(expectedReconfigurations, mustBeErrorFree);
}
// chose a test at random. These tests are rather long...
- // check for deadlocks
+ // check for deadlocks
@Test(timeout = 20000)
- public void randomTest() throws JoranException, IOException, InterruptedException {
+ public void randomTest() throws JoranException, IOException, InterruptedException {
Random rand = new Random(System.currentTimeMillis());
- switch(rand.nextInt(5)) {
- case 0: scan1();
+ switch (rand.nextInt(5)) {
+ case 0:
+ scan1();
break;
- case 1: scanWithFileInclusion();
+ case 1:
+ scanWithFileInclusion();
break;
- case 2: scanWithResourceInclusion();
+ case 2:
+ scanWithResourceInclusion();
break;
- case 3: scan_lbclassic154();
+ case 3:
+ scan_lbclassic154();
break;
- case 4: gscan1();
+ case 4:
+ gscan1();
break;
}
}
@@ -208,13 +220,26 @@ public class ReconfigureOnChangeTest {
@Test
public void fallbackToSafe() throws IOException, JoranException, InterruptedException {
- String path = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig-"+diff + ".xml";
+ String path = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_fallbackToSafe-" + diff + ".xml";
File file = new File(path);
writeToFile(file, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><root level=\"ERROR\"/></configuration> ");
configure(file);
doScanTest(file, UpdateType.MALFORMED, false, ERRORS_EXPECTED);
}
+ @Test
+ public void fallbackToSafeWithIncludedFile() throws IOException, JoranException, InterruptedException {
+ String topLevelFileAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_top-" + diff + ".xml";
+ String innerFileAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_inner-" + diff + ".xml";
+ File topLevelFile = new File(topLevelFileAsStr);
+ writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><include file=\""+innerFileAsStr+"\"/></configuration> ");
+
+ File innerFile = new File(innerFileAsStr);
+ writeToFile(innerFile, "<included><root level=\"ERROR\"/></included> ");
+ configure(topLevelFile);
+ doScanTest(innerFile, UpdateType.MALFORMED_INNER, false, ERRORS_EXPECTED);
+ }
+
@Test
public void gscan1() throws JoranException, IOException, InterruptedException {
@@ -248,12 +273,10 @@ public class ReconfigureOnChangeTest {
}
-
-
void verify(long expectedReconfigurations, boolean errorFreeness) {
StatusChecker checker = new StatusChecker(loggerContext);
StatusPrinter.print(loggerContext);
- if(errorFreeness == MUST_BE_ERROR_FREE) {
+ if (errorFreeness == MUST_BE_ERROR_FREE) {
assertTrue(checker.isErrorFree(0));
} else {
assertFalse(checker.isErrorFree(0));
@@ -262,9 +285,9 @@ public class ReconfigureOnChangeTest {
.matchCount("Will reset and reconfigure context");
// the number of effective resets must be equal or less than
// expectedReconfigurations
- System.out.println("effectiveResets="+effectiveResets);
+ System.out.println("effectiveResets=" + effectiveResets);
- System.out.println("expectedReconfigurations="+expectedReconfigurations);
+ System.out.println("expectedReconfigurations=" + expectedReconfigurations);
assertTrue(effectiveResets <= expectedReconfigurations);
// however, there should be some effective resets
@@ -351,7 +374,7 @@ public class ReconfigureOnChangeTest {
return (end - start) / (1.0d * LOOP_LEN);
}
- enum UpdateType {TOUCH, MALFORMED}
+ enum UpdateType {TOUCH, MALFORMED, MALFORMED_INNER}
void writeToFile(File file, String contents) {
try {
@@ -387,11 +410,15 @@ public class ReconfigureOnChangeTest {
}
counter++;
ReconfigureOnChangeTest.this.addInfo("***settting last modified", this);
- switch(updateType) {
- case TOUCH: updateFile();
+ switch (updateType) {
+ case TOUCH:
+ touchFile();
break;
case MALFORMED:
malformedUpdate(counter);
+ break;
+ case MALFORMED_INNER:
+ malformedInnerUpdate(counter);
}
}
}
@@ -401,11 +428,17 @@ public class ReconfigureOnChangeTest {
" <root level=\"ERROR\">\n" +
"</configuration>");
}
- void updateFile() {
+
+ private void malformedInnerUpdate(long counter) {
+ writeToFile(configFile, "<included>\n" +
+ " <root>\n" +
+ "</included>");
+ }
+
+ void touchFile() {
configFile.setLastModified(System.currentTimeMillis());
}
}
-
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
index ef1afb8..34b2c5d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
@@ -115,6 +115,9 @@ public class CoreConstants {
static public final String CONFIGURATION_WATCH_LIST_RESET = "CONFIGURATION_WATCH_LIST_RESET";
static public final String SAFE_JORAN_CONFIGURATION = "SAFE_JORAN_CONFIGURATION";
+ static public final String XML_PARSING = "XML_PARSING";
+
+
/**
* The key under which the local host name is registered in the logger
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java b/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
index d52c529..75a2014 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
@@ -23,7 +23,9 @@ import java.util.List;
import static ch.qos.logback.core.CoreConstants.SAFE_JORAN_CONFIGURATION;
+import ch.qos.logback.core.Context;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
+import ch.qos.logback.core.status.StatusChecker;
import org.xml.sax.InputSource;
import ch.qos.logback.core.joran.event.SaxEvent;
@@ -44,7 +46,7 @@ public abstract class GenericConfigurator extends ContextAwareBase {
final public void doConfigure(URL url) throws JoranException {
try {
- informContextOfURLUsedForConfiguration(url);
+ informContextOfURLUsedForConfiguration(getContext(), url);
URLConnection urlConnection = url.openConnection();
// per http://jira.qos.ch/browse/LBCORE-105
// per http://jira.qos.ch/browse/LBCORE-127
@@ -67,7 +69,7 @@ public abstract class GenericConfigurator extends ContextAwareBase {
final public void doConfigure(File file) throws JoranException {
FileInputStream fis = null;
try {
- informContextOfURLUsedForConfiguration(file.toURI().toURL());
+ informContextOfURLUsedForConfiguration(getContext(), file.toURI().toURL());
fis = new FileInputStream(file);
doConfigure(fis);
} catch (IOException ioe) {
@@ -87,7 +89,7 @@ public abstract class GenericConfigurator extends ContextAwareBase {
}
}
- protected void informContextOfURLUsedForConfiguration(URL url) {
+ static public void informContextOfURLUsedForConfiguration(Context context, URL url) {
ConfigurationWatchListUtil.setMainWatchURL(context, url);
}
@@ -122,16 +124,20 @@ public abstract class GenericConfigurator extends ContextAwareBase {
final public void doConfigure(final InputSource inputSource)
throws JoranException {
+ long threshold = System.currentTimeMillis();
if (!ConfigurationWatchListUtil.wasConfigurationWatchListReset(context)) {
- informContextOfURLUsedForConfiguration(null);
+ informContextOfURLUsedForConfiguration(getContext(), null);
}
SaxEventRecorder recorder = new SaxEventRecorder();
recorder.setContext(context);
recorder.recordEvents(inputSource);
doConfigure(recorder.saxEventList);
// no exceptions a this level
- addInfo("Registering current configuration as safe fallback point");
- registerSafeConfiguration();
+ StatusChecker statusChecker = new StatusChecker(context);
+ if(statusChecker.noXMLParsingErrorsOccurred(threshold)) {
+ addInfo("Registering current configuration as safe fallback point");
+ registerSafeConfiguration();
+ }
}
public void doConfigure(final List<SaxEvent> eventList)
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
index 286e2d2..275d981 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
@@ -59,17 +59,18 @@ public class IncludeAction extends Action {
try {
if (in != null) {
parseAndRecord(in, recorder);
+ // remove the <included> tag from the beginning and </included> from the end
+ trimHeadAndTail(recorder);
+
+ // offset = 2, because we need to get past this element as well as the end element
+ ec.getJoranInterpreter().getEventPlayer().addEventsDynamically(recorder.saxEventList, 2);
}
} catch (JoranException e) {
addError("Error while parsing " + attributeInUse, e);
} finally {
close(in);
}
- // remove the <included> tag from the beginning and </included> from the end
- trimHeadAndTail(recorder);
- // offset = 2, because we need to get past this element as well as the end element
- ec.getJoranInterpreter().getEventPlayer().addEventsDynamically(recorder.saxEventList, 2);
}
void close(InputStream in) {
@@ -197,7 +198,7 @@ public class IncludeAction extends Action {
InputStream getInputStream(InterpretationContext ec, Attributes attributes) {
URL inputURL = getInputURL(ec, attributes);
- if(inputURL == null)
+ if (inputURL == null)
return null;
ConfigurationWatchListUtil.addToWatchList(context, inputURL);
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
index 2e815e2..45bb694 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
@@ -21,7 +21,7 @@ import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
-import ch.qos.logback.core.CoreConstants;
+import static ch.qos.logback.core.CoreConstants.XML_PARSING;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
@@ -150,17 +150,17 @@ public class SaxEventRecorder extends DefaultHandler implements ContextAware {
}
public void error(SAXParseException spe) throws SAXException {
- addError("Parsing error on line " + spe.getLineNumber() + " and column "
+ addError(XML_PARSING +" - Parsing error on line " + spe.getLineNumber() + " and column "
+ spe.getColumnNumber(), spe);
}
public void fatalError(SAXParseException spe) throws SAXException {
- addError("Parsing fatal error on line " + spe.getLineNumber()
+ addError(XML_PARSING +" - Parsing fatal error on line " + spe.getLineNumber()
+ " and column " + spe.getColumnNumber(), spe);
}
public void warning(SAXParseException spe) throws SAXException {
- addWarn("Parsing warning on line " + spe.getLineNumber() + " and column "
+ addWarn(XML_PARSING +" - Parsing warning on line " + spe.getLineNumber() + " and column "
+ spe.getColumnNumber(), spe);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
index 3197407..aa52afb 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
@@ -40,8 +40,8 @@ public class EventPlayer {
return new ArrayList<SaxEvent>(eventList);
}
- public void play(List<SaxEvent> seList) {
- eventList = seList;
+ public void play(List<SaxEvent> aSaxEventList) {
+ eventList = aSaxEventList;
SaxEvent se;
for(currentIndex = 0; currentIndex < eventList.size(); currentIndex++) {
se = eventList.get(currentIndex);
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/util/ConfigurationWatchListUtil.java b/logback-core/src/main/java/ch/qos/logback/core/joran/util/ConfigurationWatchListUtil.java
index 6e61408..f2b0c53 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/util/ConfigurationWatchListUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/util/ConfigurationWatchListUtil.java
@@ -50,6 +50,15 @@ public class ConfigurationWatchListUtil {
cwl.setMainURL(url);
}
+ public static URL getMainWatchURL(Context context) {
+ ConfigurationWatchList cwl = getConfigurationWatchList(context);
+ if (cwl == null) {
+ return null;
+ } else {
+ return cwl.getMainURL();
+ }
+ }
+
public static void addToWatchList(Context context, URL url) {
ConfigurationWatchList cwl = getConfigurationWatchList(context);
if (cwl == null) {
@@ -62,12 +71,13 @@ public class ConfigurationWatchListUtil {
public static boolean wasConfigurationWatchListReset(Context context) {
Object o = context.getObject(CoreConstants.CONFIGURATION_WATCH_LIST_RESET);
- if(o == null)
+ if (o == null)
return false;
else {
return ((Boolean) o).booleanValue();
}
}
+
public static void setConfigurationWatchListResetFlag(Context context, boolean val) {
context.putObject(CoreConstants.CONFIGURATION_WATCH_LIST_RESET, new Boolean(val));
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
index ff82f46..cf12305 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
@@ -43,6 +43,13 @@ public class StatusChecker {
return filteredList;
}
+ public boolean hasXMLParsingErrors(long threshold) {
+ return containsMatch(threshold, Status.ERROR, CoreConstants.XML_PARSING);
+ }
+ public boolean noXMLParsingErrorsOccurred(long threshold) {
+ return !hasXMLParsingErrors(threshold);
+ }
+
public int getHighestLevel(long threshold) {
List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
int maxLevel = Status.INFO;
@@ -57,10 +64,11 @@ public class StatusChecker {
return Status.ERROR > getHighestLevel(threshold);
}
- public boolean containsMatch(int level, String regex) {
+ public boolean containsMatch(long threshold, int level, String regex) {
+ List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
Pattern p = Pattern.compile(regex);
- for (Status status : sm.getCopyOfStatusList()) {
+ for (Status status : filteredList) {
if (level != status.getLevel()) {
continue;
}
@@ -74,6 +82,10 @@ public class StatusChecker {
}
+ public boolean containsMatch(int level, String regex) {
+ return containsMatch(0, level, regex);
+ }
+
public boolean containsMatch(String regex) {
Pattern p = Pattern.compile(regex);
for (Status status : sm.getCopyOfStatusList()) {
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
index 236e01a..3697c58 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
@@ -64,7 +64,7 @@ public class TrivialConfiguratorTest {
int oldBeginCount = IncAction.beginCount;
int oldEndCount = IncAction.endCount;
int oldErrorCount = IncAction.errorCount;
- doTest(CoreTestConstants.TEST_DIR_PREFIX + "input/joran/"+"inc.xml");
+ doTest(CoreTestConstants.TEST_DIR_PREFIX + "input/joran/" + "inc.xml");
assertEquals(oldErrorCount, IncAction.errorCount);
assertEquals(oldBeginCount + 1, IncAction.beginCount);
assertEquals(oldEndCount + 1, IncAction.endCount);
@@ -85,7 +85,7 @@ public class TrivialConfiguratorTest {
tsl.list.size() >= 1);
Status s0 = tsl.list.get(0);
assertTrue(s0.getMessage().startsWith("Could not open ["));
- }
+ }
@Test
public void illFormedXML() {
@@ -98,8 +98,7 @@ public class TrivialConfiguratorTest {
}
assertEquals(1, tsl.list.size());
Status s0 = tsl.list.get(0);
- assertTrue(s0.getMessage().startsWith(
- "Parsing fatal error on line 5 and column 3"));
+ assertTrue(s0.getMessage().startsWith(CoreConstants.XML_PARSING));
}
@Test
-----------------------------------------------------------------------
Summary of changes:
.../classic/turbo/ReconfigureOnChangeFilter.java | 35 +++++----
.../classic/turbo/ReconfigureOnChangeTest.java | 77 ++++++++++++++------
.../java/ch/qos/logback/core/CoreConstants.java | 3 +
.../logback/core/joran/GenericConfigurator.java | 18 +++--
.../logback/core/joran/action/IncludeAction.java | 11 ++--
.../logback/core/joran/event/SaxEventRecorder.java | 8 +-
.../ch/qos/logback/core/joran/spi/EventPlayer.java | 4 +-
.../joran/util/ConfigurationWatchListUtil.java | 12 +++-
.../ch/qos/logback/core/status/StatusChecker.java | 16 ++++-
.../core/joran/TrivialConfiguratorTest.java | 7 +-
10 files changed, 129 insertions(+), 62 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0
What is the significance of the teacup icon for logback (and log4j)?
1
0
[JIRA] Created: (LBCLASSIC-265) Logging stops if invalid xml configuration is loaded by scanner
by Iwein Fuld (JIRA) 23 Jun '11
by Iwein Fuld (JIRA) 23 Jun '11
23 Jun '11
Logging stops if invalid xml configuration is loaded by scanner
---------------------------------------------------------------
Key: LBCLASSIC-265
URL: http://jira.qos.ch/browse/LBCLASSIC-265
Project: logback-classic
Issue Type: Bug
Affects Versions: 0.9.28
Reporter: Iwein Fuld
Assignee: Logback dev list
When logging with scan="true" it is possible to stop all logging of an application silently.
Steps to reproduce:
- start an application with valid configuration and scan=true
- break the logback.xml (leave out a quote or something)
-> log goes silent
Expected behavior:
Logger fails to load new config and keeps running on the old configuration (like when valid xml, but invalid configuration is loaded).
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
4
12
[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.29-5-g690ac09
by git-noreply@pixie.qos.ch 23 Jun '11
by git-noreply@pixie.qos.ch 23 Jun '11
23 Jun '11
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 690ac09e30d017edea2681395b1fa33095f5f269 (commit)
from 33a24d81695f2a90ed239c0054225992c6be4aab (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=690ac09e30d017edea268139…
http://github.com/ceki/logback/commit/690ac09e30d017edea2681395b1fa33095f5f…
commit 690ac09e30d017edea2681395b1fa33095f5f269
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Thu Jun 23 23:40:38 2011 +0200
fixed LBCLASSIC-265
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
index c514c68..6615f51 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
@@ -19,8 +19,11 @@ import java.util.List;
import ch.qos.logback.classic.gaffer.GafferUtil;
import ch.qos.logback.classic.util.EnvUtil;
+import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.spi.ConfigurationWatchList;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
+import ch.qos.logback.core.status.StatusChecker;
+import ch.qos.logback.core.status.WarnStatus;
import org.slf4j.Marker;
import ch.qos.logback.classic.Level;
@@ -51,26 +54,33 @@ public class ReconfigureOnChangeFilter extends TurboFilter {
URL mainConfigurationURL;
protected volatile long nextCheck;
- ConfigurationWatchList cwl;
+ ConfigurationWatchList configurationWatchList;
@Override
public void start() {
- cwl = ConfigurationWatchListUtil.getConfigurationWatchList(context);
- if (cwl != null) {
- mainConfigurationURL = cwl.getMainURL();
- List<File> watchList = cwl.getCopyOfFileWatchList();
+ configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(context);
+ if (configurationWatchList != null) {
+ mainConfigurationURL = configurationWatchList.getMainURL();
+ List<File> watchList = configurationWatchList.getCopyOfFileWatchList();
long inSeconds = refreshPeriod / 1000;
addInfo("Will scan for changes in [" + watchList + "] every "
+ inSeconds + " seconds. ");
- synchronized (cwl) {
+ synchronized (configurationWatchList) {
updateNextCheck(System.currentTimeMillis());
}
super.start();
- } else {
+ } else {
addWarn("Empty ConfigurationWatchList in context");
}
}
+ @Override
+ public String toString() {
+ return "ReconfigureOnChangeFilter{" +
+ "invocationCounter=" + invocationCounter +
+ '}';
+ }
+
// The next fields counts the number of time the decide method is called
//
// IMPORTANT: This field can be updated by multiple threads. It follows that
@@ -91,7 +101,7 @@ public class ReconfigureOnChangeFilter extends TurboFilter {
return FilterReply.NEUTRAL;
}
- synchronized (cwl) {
+ synchronized (configurationWatchList) {
if (changeDetected()) {
// Even though reconfiguration involves resetting the loggerContext,
// which clears the list of turbo filters including this instance, it is
@@ -109,7 +119,7 @@ public class ReconfigureOnChangeFilter extends TurboFilter {
// locks held by the current thread, in particular, the AppenderAttachable
// reader lock.
private void detachReconfigurationToNewThread() {
- addInfo("Detected change in [" + cwl.getCopyOfFileWatchList() + "]");
+ addInfo("Detected change in [" + configurationWatchList.getCopyOfFileWatchList() + "]");
new ReconfiguringThread().start();
}
@@ -121,7 +131,7 @@ public class ReconfigureOnChangeFilter extends TurboFilter {
long now = System.currentTimeMillis();
if (now >= nextCheck) {
updateNextCheck(now);
- return cwl.changeDetected();
+ return configurationWatchList.changeDetected();
}
return false;
}
@@ -140,23 +150,14 @@ public class ReconfigureOnChangeFilter extends TurboFilter {
class ReconfiguringThread extends Thread {
public void run() {
- if(mainConfigurationURL == null) {
+ if (mainConfigurationURL == null) {
addInfo("Due to missing top level configuration file, skipping reconfiguration");
return;
}
LoggerContext lc = (LoggerContext) context;
addInfo("Will reset and reconfigure context named [" + context.getName() + "]");
if (mainConfigurationURL.toString().endsWith("xml")) {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(context);
- lc.reset();
- try {
- jc.doConfigure(mainConfigurationURL);
- lc.getStatusManager().add(
- new InfoStatus("done resetting the logging context", this));
- } catch (JoranException e) {
- addError("Failure during reconfiguration", e);
- }
+ performXMLConfiguration(lc);
} else if (mainConfigurationURL.toString().endsWith("groovy")) {
if (EnvUtil.isGroovyAvailable()) {
lc.reset();
@@ -168,5 +169,41 @@ public class ReconfigureOnChangeFilter extends TurboFilter {
}
}
}
+
+ private void performXMLConfiguration(LoggerContext lc) {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ StatusChecker statusChecker = new StatusChecker(context);
+ List<SaxEvent> eventList = jc.recallSafeConfiguration();
+ lc.getStatusManager().add(
+ new InfoStatus("Resetting the logging ", this));
+ lc.reset();
+
+ try {
+ jc.doConfigure(mainConfigurationURL);
+ } catch (JoranException e) {
+ fallbackConfiguration(lc, eventList);
+ }
+ }
+
+ private void fallbackConfiguration(LoggerContext lc, List<SaxEvent> eventList) {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ if (eventList != null) {
+ lc.getStatusManager().add(
+ new WarnStatus("Falling back to previously registered safe configuration.", this));
+ try {
+ jc.doConfigure(eventList);
+ addInfo("Re-registering previous fallback configuration as a fallback point");
+ jc.registerSafeConfiguration();
+ } catch (JoranException e) {
+ addError("Unexpected exception thrown by configuration considered as safes", e);
+ }
+ } else {
+ lc.getStatusManager().add(
+ new WarnStatus("No previous configuration to fall back to.", this));
+
+ }
+ }
}
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
index 885e10f..6def1ae 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
@@ -14,6 +14,7 @@
package ch.qos.logback.classic.turbo;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.*;
@@ -22,7 +23,8 @@ import java.util.Random;
import ch.qos.logback.classic.gaffer.GafferConfigurator;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
-import org.hsqldb.lib.StringInputStream;
+import ch.qos.logback.core.testUtil.RandomUtil;
+import ch.qos.logback.core.util.CoreTestConstants;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -47,6 +49,12 @@ public class ReconfigureOnChangeTest {
final static int THREAD_COUNT = 5;
final static int LOOP_LEN = 1000 * 1000;
+ static final boolean MUST_BE_ERROR_FREE = true;
+ static final boolean ERRORS_EXPECTED = false;
+
+
+ int diff = RandomUtil.getPositiveInt();
+
// the space in the file name mandated by
// http://jira.qos.ch/browse/LBCORE-119
final static String SCAN1_FILE_AS_STR = ClassicTestConstants.INPUT_PREFIX
@@ -118,9 +126,9 @@ public class ReconfigureOnChangeTest {
gc.run(file);
}
- RunnableWithCounterAndDone[] buildRunnableArray(File configFile) {
+ RunnableWithCounterAndDone[] buildRunnableArray(File configFile, UpdateType updateType) {
RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[THREAD_COUNT];
- rArray[0] = new Updater(configFile);
+ rArray[0] = new Updater(configFile, updateType);
for (int i = 1; i < THREAD_COUNT; i++) {
rArray[i] = new LoggingRunnable(logger);
}
@@ -129,11 +137,11 @@ public class ReconfigureOnChangeTest {
void doScanTest(File fileToTouch) throws JoranException, IOException, InterruptedException {
- doScanTest(fileToTouch, false);
+ doScanTest(fileToTouch, UpdateType.TOUCH, false, MUST_BE_ERROR_FREE);
}
- void doScanTest(File fileToTouch, boolean forcedReconfigurationSkip) throws JoranException, IOException, InterruptedException {
- RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(fileToTouch);
+ void doScanTest(File fileToTouch, UpdateType updateType, boolean forcedReconfigurationSkip, boolean mustBeErrorFree) throws JoranException, IOException, InterruptedException {
+ RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(fileToTouch, updateType);
harness.execute(runnableArray);
loggerContext.getStatusManager().add(
@@ -143,7 +151,7 @@ public class ReconfigureOnChangeTest {
if(forcedReconfigurationSkip)
expectedReconfigurations = 0;
- verify(expectedReconfigurations);
+ verify(expectedReconfigurations, mustBeErrorFree);
}
// chose a test at random. These tests are rather long...
@@ -195,21 +203,31 @@ public class ReconfigureOnChangeTest {
String configurationStr = "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><include resource=\"asResource/inner1.xml\"/></configuration>";
configure(new ByteArrayInputStream(configurationStr.getBytes("UTF-8")));
File innerFile = new File(INCLUSION_SCAN_INNER1_AS_STR);
- doScanTest(innerFile, true);
+ doScanTest(innerFile, UpdateType.TOUCH, true, MUST_BE_ERROR_FREE);
+ }
+
+ @Test
+ public void fallbackToSafe() throws IOException, JoranException, InterruptedException {
+ String path = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig-"+diff + ".xml";
+ File file = new File(path);
+ writeToFile(file, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><root level=\"ERROR\"/></configuration> ");
+ configure(file);
+ doScanTest(file, UpdateType.MALFORMED, false, ERRORS_EXPECTED);
}
+
@Test
public void gscan1() throws JoranException, IOException, InterruptedException {
File file = new File(G_SCAN1_FILE_AS_STR);
gConfigure(file);
- RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(file);
+ RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(file, UpdateType.TOUCH);
harness.execute(runnableArray);
loggerContext.getStatusManager().add(
new InfoStatus("end of execution ", this));
long expectedRreconfigurations = runnableArray[0].getCounter();
- verify(expectedRreconfigurations);
+ verify(expectedRreconfigurations, MUST_BE_ERROR_FREE);
}
// check for deadlocks
@@ -219,23 +237,27 @@ public class ReconfigureOnChangeTest {
InterruptedException {
File file = new File(SCAN_LBCLASSIC_154_FILE_AS_STR);
configure(file);
- RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(file);
+ RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(file, UpdateType.TOUCH);
harness.execute(runnableArray);
loggerContext.getStatusManager().add(
new InfoStatus("end of execution ", this));
long expectedReconfigurations = runnableArray[0].getCounter();
- verify(expectedReconfigurations);
+ verify(expectedReconfigurations, MUST_BE_ERROR_FREE);
}
- void verify(long expectedReconfigurations) {
+ void verify(long expectedReconfigurations, boolean errorFreeness) {
StatusChecker checker = new StatusChecker(loggerContext);
StatusPrinter.print(loggerContext);
- assertTrue(checker.isErrorFree(0));
+ if(errorFreeness == MUST_BE_ERROR_FREE) {
+ assertTrue(checker.isErrorFree(0));
+ } else {
+ assertFalse(checker.isErrorFree(0));
+ }
int effectiveResets = checker
.matchCount("Will reset and reconfigure context");
// the number of effective resets must be equal or less than
@@ -329,11 +351,29 @@ public class ReconfigureOnChangeTest {
return (end - start) / (1.0d * LOOP_LEN);
}
+ enum UpdateType {TOUCH, MALFORMED}
+
+ void writeToFile(File file, String contents) {
+ try {
+ FileWriter fw = new FileWriter(file);
+ fw.write(contents);
+ fw.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
class Updater extends RunnableWithCounterAndDone {
File configFile;
+ UpdateType updateType;
- Updater(File configFile) {
+ Updater(File configFile, UpdateType updateType) {
this.configFile = configFile;
+ this.updateType = updateType;
+ }
+
+ Updater(File configFile) {
+ this(configFile, UpdateType.TOUCH);
}
public void run() {
@@ -347,9 +387,25 @@ public class ReconfigureOnChangeTest {
}
counter++;
ReconfigureOnChangeTest.this.addInfo("***settting last modified", this);
- configFile.setLastModified(System.currentTimeMillis());
+ switch(updateType) {
+ case TOUCH: updateFile();
+ break;
+ case MALFORMED:
+ malformedUpdate(counter);
+ }
}
}
+
+ private void malformedUpdate(long counter) {
+ writeToFile(configFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\">\n" +
+ " <root level=\"ERROR\">\n" +
+ "</configuration>");
+ }
+ void updateFile() {
+ configFile.setLastModified(System.currentTimeMillis());
+ }
}
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
index 3c624fa..ef1afb8 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
@@ -62,12 +62,12 @@ public class CoreConstants {
/**
* An empty string array.
*/
- public final static String[] EMPTY_STRING_ARRAY = new String[] {};
+ public final static String[] EMPTY_STRING_ARRAY = new String[]{};
/**
* An empty Class array.
*/
- public final static Class<?>[] EMPTY_CLASS_ARRAY = new Class[] {};
+ public final static Class<?>[] EMPTY_CLASS_ARRAY = new Class[]{};
public final static String CAUSED_BY = "Caused by: ";
@@ -111,9 +111,10 @@ public class CoreConstants {
static public final String SEE_FNP_NOT_SET = "See also http://logback.qos.ch/codes.html#tbr_fnp_not_set";
- public static String CONFIGURATION_WATCH_LIST = "CONFIGURATION_WATCH_LIST";
- public static String CONFIGURATION_WATCH_LIST_RESET = "CONFIGURATION_WATCH_LIST_RESET";
+ static public final String CONFIGURATION_WATCH_LIST = "CONFIGURATION_WATCH_LIST";
+ static public final String CONFIGURATION_WATCH_LIST_RESET = "CONFIGURATION_WATCH_LIST_RESET";
+ static public final String SAFE_JORAN_CONFIGURATION = "SAFE_JORAN_CONFIGURATION";
/**
* The key under which the local host name is registered in the logger
@@ -123,12 +124,11 @@ public class CoreConstants {
/**
* The key under which the current context name is registered in the logger
- * context.
+ * context.
*/
public static final String CONTEXT_NAME_KEY = "CONTEXT_NAME";
public static int BYTES_PER_INT = 4;
public static final int MILLIS_IN_ONE_SECOND = 1000;
- public final static String XML_PARSING_ERROR = "XML PARSING ERROR";
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java b/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
index 9b6ac3a..d52c529 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
@@ -21,6 +21,8 @@ import java.net.URL;
import java.net.URLConnection;
import java.util.List;
+import static ch.qos.logback.core.CoreConstants.SAFE_JORAN_CONFIGURATION;
+
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
import org.xml.sax.InputSource;
@@ -47,7 +49,7 @@ public abstract class GenericConfigurator extends ContextAwareBase {
// per http://jira.qos.ch/browse/LBCORE-105
// per http://jira.qos.ch/browse/LBCORE-127
urlConnection.setUseCaches(false);
-
+
InputStream in = urlConnection.getInputStream();
doConfigure(in);
in.close();
@@ -69,7 +71,7 @@ public abstract class GenericConfigurator extends ContextAwareBase {
fis = new FileInputStream(file);
doConfigure(fis);
} catch (IOException ioe) {
- String errMsg = "Could not open [" + file.getName() + "].";
+ String errMsg = "Could not open [" + file.getPath() + "].";
addError(errMsg, ioe);
throw new JoranException(errMsg, ioe);
} finally {
@@ -98,13 +100,13 @@ public abstract class GenericConfigurator extends ContextAwareBase {
abstract protected void addImplicitRules(Interpreter interpreter);
protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
-
+
}
-
+
protected Pattern initialPattern() {
return new Pattern();
}
-
+
protected void buildInterpreter() {
RuleStore rs = new SimpleRuleStore(context);
addInstanceRules(rs);
@@ -118,27 +120,43 @@ public abstract class GenericConfigurator extends ContextAwareBase {
// this is the most inner form of doConfigure whereto other doConfigure
// methods ultimately delegate
final public void doConfigure(final InputSource inputSource)
- throws JoranException {
+ throws JoranException {
- if(!ConfigurationWatchListUtil.wasConfigurationWatchListReset(context)) {
+ if (!ConfigurationWatchListUtil.wasConfigurationWatchListReset(context)) {
informContextOfURLUsedForConfiguration(null);
}
SaxEventRecorder recorder = new SaxEventRecorder();
recorder.setContext(context);
recorder.recordEvents(inputSource);
+ doConfigure(recorder.saxEventList);
+ // no exceptions a this level
+ addInfo("Registering current configuration as safe fallback point");
+ registerSafeConfiguration();
+ }
+
+ public void doConfigure(final List<SaxEvent> eventList)
+ throws JoranException {
buildInterpreter();
// disallow simultaneous configurations of the same context
synchronized (context.getConfigurationLock()) {
- interpreter.play(recorder.saxEventList);
+ interpreter.getEventPlayer().play(eventList);
}
+ }
+ /**
+ * Register the current event list in currently in the interpreter as a safe
+ * configuration point.
+ *
+ * @since 0.9.30
+ */
+ public void registerSafeConfiguration() {
+ context.putObject(SAFE_JORAN_CONFIGURATION, interpreter.getEventPlayer().getCopyOfPlayerEventList());
}
- // protected since v0.9.30
- protected void doConfigure(final List<SaxEvent> eventList)
- throws JoranException {
- buildInterpreter();
- EventPlayer player = new EventPlayer(interpreter);
- player.play(eventList);
+ /**
+ * Recall the event list previously registered as a safe point.
+ */
+ public List<SaxEvent> recallSafeConfiguration() {
+ return (List<SaxEvent>) context.getObject(SAFE_JORAN_CONFIGURATION);
}
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
index e29178d..286e2d2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
@@ -69,7 +69,7 @@ public class IncludeAction extends Action {
trimHeadAndTail(recorder);
// offset = 2, because we need to get past this element as well as the end element
- ec.getJoranInterpreter().addEventsDynamically(recorder.saxEventList, 2);
+ ec.getJoranInterpreter().getEventPlayer().addEventsDynamically(recorder.saxEventList, 2);
}
void close(InputStream in) {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
index e0e5f8b..97f9c80 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
@@ -112,7 +112,7 @@ public class IfAction extends Action {
// if boolResult==false & missing else, listToPlay may be null
if(listToPlay != null) {
// insert past this event
- interpreter.addEventsDynamically(listToPlay, 1);
+ interpreter.getEventPlayer().addEventsDynamically(listToPlay, 1);
}
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
index 5efbcd0..2e815e2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
@@ -59,11 +59,12 @@ public class SaxEventRecorder extends DefaultHandler implements ContextAware {
saxParser.parse(inputSource, this);
return saxEventList;
} catch (IOException ie) {
- handleError(CoreConstants.XML_PARSING_ERROR+ ". I/O error occurred while parsing xml file", ie);
+ handleError("I/O error occurred while parsing xml file", ie);
} catch(SAXException se) {
- handleError(CoreConstants.XML_PARSING_ERROR+ ". Problem parsing XML document. See previously reported errors.", se);
+ // Exception added into StatusManager via Sax error handling. No need to add it again
+ throw new JoranException("Problem parsing XML document. See previously reported errors.", se);
} catch (Exception ex) {
- handleError(CoreConstants.XML_PARSING_ERROR+ ". Unexpected exception while parsing XML document.", ex);
+ handleError("Unexpected exception while parsing XML document.", ex);
}
throw new IllegalStateException("This point can never be reached");
}
@@ -80,7 +81,7 @@ public class SaxEventRecorder extends DefaultHandler implements ContextAware {
spf.setNamespaceAware(true);
return spf.newSAXParser();
} catch (Exception pce) {
- String errMsg = "Parser configuration error occured";
+ String errMsg = "Parser configuration error occurred";
addError(errMsg, pce);
throw new JoranException(errMsg, pce);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
index 61d058f..3197407 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.joran.spi;
+import java.util.ArrayList;
import java.util.List;
import ch.qos.logback.core.joran.event.BodyEvent;
@@ -29,7 +30,16 @@ public class EventPlayer {
public EventPlayer(Interpreter interpreter) {
this.interpreter = interpreter;
}
-
+
+ /**
+ * Return a copy of the current event list in the player.
+ * @return
+ * @since 0.9.20
+ */
+ public List<SaxEvent> getCopyOfPlayerEventList() {
+ return new ArrayList<SaxEvent>(eventList);
+ }
+
public void play(List<SaxEvent> seList) {
eventList = seList;
SaxEvent se;
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
index 48f074b..3f2698a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
@@ -74,7 +74,7 @@ public class Interpreter {
final private CAI_WithLocatorSupport cai;
private Pattern pattern;
Locator locator;
- EventPlayer player;
+ EventPlayer eventPlayer;
/**
* The <id>actionListStack</id> contains a list of actions that are executing
@@ -100,7 +100,11 @@ public class Interpreter {
implicitActions = new ArrayList<ImplicitAction>(3);
this.pattern = initialPattern;
actionListStack = new Stack<List>();
- player = new EventPlayer(this);
+ eventPlayer = new EventPlayer(this);
+ }
+
+ public EventPlayer getEventPlayer() {
+ return eventPlayer;
}
public void setInterpretationContextPropertiesMap(
@@ -327,16 +331,6 @@ public class Interpreter {
public RuleStore getRuleStore() {
return ruleStore;
}
-
- public void play(List<SaxEvent> eventList) {
- player.play(eventList);
- }
-
- public void addEventsDynamically(List<SaxEvent> eventList, int offset) {
- if (player != null) {
- player.addEventsDynamically(eventList, offset);
- }
- }
}
/**
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
index 207db5d..ff82f46 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
@@ -20,6 +20,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ch.qos.logback.core.Context;
+import ch.qos.logback.core.CoreConstants;
public class StatusChecker {
@@ -46,7 +47,7 @@ public class StatusChecker {
List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
int maxLevel = Status.INFO;
for (Status s : filteredList) {
- if(s.getLevel() > maxLevel)
+ if (s.getLevel() > maxLevel)
maxLevel = s.getLevel();
}
return maxLevel;
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
index f8ce354..236e01a 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
@@ -28,6 +28,8 @@ import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import ch.qos.logback.core.CoreConstants;
+import ch.qos.logback.core.db.dialect.SQLDialect;
+import ch.qos.logback.core.util.StatusPrinter;
import org.junit.Test;
import ch.qos.logback.core.Context;
@@ -54,8 +56,7 @@ public class TrivialConfiguratorTest {
TrivialConfigurator trivialConfigurator = new TrivialConfigurator(rulesMap);
trivialConfigurator.setContext(context);
- trivialConfigurator.doConfigure(CoreTestConstants.TEST_DIR_PREFIX
- + "input/joran/" + filename);
+ trivialConfigurator.doConfigure(filename);
}
@Test
@@ -63,7 +64,7 @@ public class TrivialConfiguratorTest {
int oldBeginCount = IncAction.beginCount;
int oldEndCount = IncAction.endCount;
int oldErrorCount = IncAction.errorCount;
- doTest("inc.xml");
+ doTest(CoreTestConstants.TEST_DIR_PREFIX + "input/joran/"+"inc.xml");
assertEquals(oldErrorCount, IncAction.errorCount);
assertEquals(oldBeginCount + 1, IncAction.beginCount);
assertEquals(oldEndCount + 1, IncAction.endCount);
@@ -72,35 +73,33 @@ public class TrivialConfiguratorTest {
@Test
public void inexistentFile() {
TrivialStatusListener tsl = new TrivialStatusListener();
- String filename = "nothereBLAH.xml";
+ String filename = CoreTestConstants.TEST_DIR_PREFIX + "input/joran/"
+ + "nothereBLAH.xml";
context.getStatusManager().add(tsl);
try {
doTest(filename);
} catch (Exception e) {
+ assertTrue(e.getMessage().startsWith("Could not open ["));
}
assertTrue(tsl.list.size() + " should be greater than or equal to 1",
- tsl.list.size() >= 1);
+ tsl.list.size() >= 1);
Status s0 = tsl.list.get(0);
- assertTrue(s0.getMessage().startsWith("Could not open [" + filename + "]"));
- }
+ assertTrue(s0.getMessage().startsWith("Could not open ["));
+ }
@Test
public void illFormedXML() {
TrivialStatusListener tsl = new TrivialStatusListener();
- String filename = "illformed.xml";
+ String filename = CoreTestConstants.TEST_DIR_PREFIX + "input/joran/" + "illformed.xml";
context.getStatusManager().add(tsl);
try {
doTest(filename);
} catch (Exception e) {
}
- assertEquals(2, tsl.list.size());
+ assertEquals(1, tsl.list.size());
Status s0 = tsl.list.get(0);
assertTrue(s0.getMessage().startsWith(
- "Parsing fatal error on line 5 and column 3"));
- Status s1 = tsl.list.get(1);
- assertTrue(s1
- .getMessage()
- .startsWith(CoreConstants.XML_PARSING_ERROR));
+ "Parsing fatal error on line 5 and column 3"));
}
@Test
@@ -131,7 +130,7 @@ public class TrivialConfiguratorTest {
URLConnection urlConnection2 = url2.openConnection();
urlConnection2.setUseCaches(false);
InputStream is = urlConnection2.getInputStream();
-
+
TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
tc.setContext(context);
tc.doConfigure(url1);
@@ -149,16 +148,16 @@ public class TrivialConfiguratorTest {
outputDir.mkdirs();
int randomPart = RandomUtil.getPositiveInt();
return new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "foo-" + randomPart
- + ".jar");
+ + ".jar");
}
private void fillInJarFile(File jarFile, String jarEntryName)
- throws IOException {
+ throws IOException {
fillInJarFile(jarFile, jarEntryName, null);
}
private void fillInJarFile(File jarFile, String jarEntryName1,
- String jarEntryName2) throws IOException {
+ String jarEntryName2) throws IOException {
JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile));
jos.putNextEntry(new ZipEntry(jarEntryName1));
jos.write("<x/>".getBytes());
-----------------------------------------------------------------------
Summary of changes:
.../classic/turbo/ReconfigureOnChangeFilter.java | 79 +++++++++++++-----
.../classic/turbo/ReconfigureOnChangeTest.java | 88 ++++++++++++++++----
.../java/ch/qos/logback/core/CoreConstants.java | 12 ++--
.../logback/core/joran/GenericConfigurator.java | 46 +++++++---
.../logback/core/joran/action/IncludeAction.java | 2 +-
.../logback/core/joran/conditional/IfAction.java | 2 +-
.../logback/core/joran/event/SaxEventRecorder.java | 9 +-
.../ch/qos/logback/core/joran/spi/EventPlayer.java | 12 +++-
.../ch/qos/logback/core/joran/spi/Interpreter.java | 18 ++---
.../ch/qos/logback/core/status/StatusChecker.java | 3 +-
.../core/joran/TrivialConfiguratorTest.java | 35 ++++----
11 files changed, 211 insertions(+), 95 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0
[JIRA] Created: (LBCLASSIC-277) BLOCKED state on AppenderBase.java:64
by h mahboobi (JIRA) 23 Jun '11
by h mahboobi (JIRA) 23 Jun '11
23 Jun '11
BLOCKED state on AppenderBase.java:64
-------------------------------------
Key: LBCLASSIC-277
URL: http://jira.qos.ch/browse/LBCLASSIC-277
Project: logback-classic
Issue Type: Bug
Components: appender
Affects Versions: 0.9.22
Environment: 64 bit Hardware with 16 processors, 32 GB RAM
SUSE Enterprise Linux 10
Glassfish 2.1.1
JDK 1.6 U15
Reporter: h mahboobi
Assignee: Logback dev list
We're using Logback in high transactional system.
In some cases, our JVM memory abnormally increased and after some minutes, clients could not connect to our services.
Here is dump of JVM threads.
I think there is a problem on logback.
"pool-9-thread-1257" prio=10 tid=0x00002ab04d8c4000 nid=0x6613 waiting for monitor entry [0x000000004ec13000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ch.qos.logback.core.AppenderBase.doAppend(AppenderBase.java:64)
- waiting to lock <0x00002aab31180628> (a ch.qos.logback.classic.sift.SiftingAppender)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:64)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:283)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:270)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:471)
at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:425)
at ch.qos.logback.classic.Logger.debug(Logger.java:532)
at com.kishware.common.log.Slf4jLogger.debug(Slf4jLogger.java:47)
at com.kishware.core.framework.controller.PreOperationController.preOperationControl(PreOperationController.java:109)
at com.kishware.core.framework.controller.PreOperationController$1.call(PreOperationController.java:73)
at com.kishware.core.framework.controller.PreOperationController$1.call(PreOperationController.java:1)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
1
1
[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.29-4-g33a24d8
by git-noreply@pixie.qos.ch 20 Jun '11
by git-noreply@pixie.qos.ch 20 Jun '11
20 Jun '11
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 33a24d81695f2a90ed239c0054225992c6be4aab (commit)
from 218b66b5c0c7826c39abbc02e3728ad171bba8f8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=33a24d81695f2a90ed239c00…
http://github.com/ceki/logback/commit/33a24d81695f2a90ed239c0054225992c6be4…
commit 33a24d81695f2a90ed239c0054225992c6be4aab
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Tue Jun 21 00:35:19 2011 +0200
Preparatory work for fixing LBCLASSIC-265. The first step is to detect
SAX exceptions during Joran doConfigure invocation.
diff --git a/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java b/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java
index 678373a..dde4d7c 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java
@@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals;
import java.util.Random;
import ch.qos.logback.access.spi.IAccessEvent;
+import ch.qos.logback.core.status.StatusChecker;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -41,6 +42,7 @@ public class DBAppenderIntegrationTest {
int diff = new Random(System.nanoTime()).nextInt(10000);
AccessContext context = new AccessContext();
+ StatusChecker statusChecker = new StatusChecker(context);
@BeforeClass
public static void setUpBeforeClass() throws Exception {
@@ -74,7 +76,7 @@ public class DBAppenderIntegrationTest {
StatusPrinter.print(context);
// check that there were no errors
- assertEquals(Status.INFO, context.getStatusManager().getLevel());
+ assertEquals(Status.INFO, statusChecker.getHighestLevel(0));
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java
index 91661b2..752b1ed 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java
@@ -66,7 +66,7 @@ public class GEventEvaluatorTest {
gee.start();
StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- assertTrue(statusChecker.isErrorFree());
+ assertTrue(statusChecker.isErrorFree(0));
boolean result = gee.evaluate(event);
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderIntegrationTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderIntegrationTest.java
index 2508c2b..aa72ae5 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderIntegrationTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderIntegrationTest.java
@@ -110,7 +110,7 @@ public class DBAppenderIntegrationTest {
// check that there were no errors
StatusChecker checker = new StatusChecker(lc);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore211/Lbcore211.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore211/Lbcore211.java
new file mode 100644
index 0000000..20cc5d3
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore211/Lbcore211.java
@@ -0,0 +1,34 @@
+package ch.qos.logback.classic.issue.lbcore211;
+
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.util.StatusPrinter;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Ceki Gücü
+ */
+public class Lbcore211 {
+
+ @Test
+ public void lbcore211() throws JoranException {
+
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure("/home/ceki/lbcore211.xml");
+
+ Logger l = lc.getLogger("file.logger");
+ StatusPrinter.print(lc);
+ for (int i = 0; i < 10; i++) {
+ l.info("hello " + i);
+ }
+
+ lc.stop();
+ }
+}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java
index 3d8fb32..54c5f63 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java
@@ -302,7 +302,7 @@ public class JoranConfiguratorTest {
StatusPrinter.print(loggerContext);
StatusChecker checker = new StatusChecker(loggerContext);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
assertTrue(checker.containsMatch("Will reset and reconfigure context"));
}
@@ -336,7 +336,7 @@ public class JoranConfiguratorTest {
assertEquals("UTF-8", encoder.getCharset().displayName());
StatusChecker checker = new StatusChecker(loggerContext);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
}
void verifyJULLevel(String loggerName, Level expectedLevel) {
@@ -363,7 +363,7 @@ public class JoranConfiguratorTest {
+ "/jul/levelChangePropagator0.xml";
configure(configFileAsStr);
StatusChecker checker = new StatusChecker(loggerContext);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
verifyJULLevel("xx", null);
verifyJULLevel("a.b.c", Level.WARN);
verifyJULLevel(Logger.ROOT_LOGGER_NAME, Level.TRACE);
@@ -377,7 +377,7 @@ public class JoranConfiguratorTest {
+ "/jul/levelChangePropagator1.xml";
configure(configFileAsStr);
StatusChecker checker = new StatusChecker(loggerContext);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
verifyJULLevel("xx", Level.INFO);
verifyJULLevel("a.b.c", Level.WARN);
verifyJULLevel(Logger.ROOT_LOGGER_NAME, Level.TRACE);
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
index 459656f..1d4ee9c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
@@ -80,7 +80,7 @@ public class ConditionalTest {
ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
assertNotNull(consoleAppender);
StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
}
@SuppressWarnings("rawtypes")
@@ -97,7 +97,7 @@ public class ConditionalTest {
ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
assertNull(consoleAppender);
StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
}
@SuppressWarnings("rawtypes")
@@ -120,7 +120,7 @@ public class ConditionalTest {
// StatusPrinter.printIfErrorsOccured(context);
StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
}
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/TimeBasedRollingWithConfigFileTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/TimeBasedRollingWithConfigFileTest.java
index 7f4f720..bb9bda4 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/TimeBasedRollingWithConfigFileTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/TimeBasedRollingWithConfigFileTest.java
@@ -69,7 +69,7 @@ public class TimeBasedRollingWithConfigFileTest extends
loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId
+ ".xml");
StatusChecker sc = new StatusChecker(lc);
- assertTrue(sc.isErrorFree());
+ assertTrue(sc.isErrorFree(0));
Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
@@ -117,7 +117,7 @@ public class TimeBasedRollingWithConfigFileTest extends
.getAppender("ROLLING");
StatusChecker sc = new StatusChecker(lc);
- assertTrue(sc.isErrorFree());
+ assertTrue(sc.isErrorFree(0));
TimeBasedRollingPolicy tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa
.getTriggeringPolicy();
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/UniqueFileTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/UniqueFileTest.java
index 4c13f00..5624e8c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/UniqueFileTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/UniqueFileTest.java
@@ -56,7 +56,7 @@ public class UniqueFileTest {
String timestamp = sdf.format(System.currentTimeMillis());
StatusChecker sc = new StatusChecker(lc);
- assertTrue(sc.isErrorFree());
+ assertTrue(sc.isErrorFree(0));
Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
root.info("hello");
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
index cb21a9f..885e10f 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
@@ -235,7 +235,7 @@ public class ReconfigureOnChangeTest {
void verify(long expectedReconfigurations) {
StatusChecker checker = new StatusChecker(loggerContext);
StatusPrinter.print(loggerContext);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
int effectiveResets = checker
.matchCount("Will reset and reconfigure context");
// the number of effective resets must be equal or less than
diff --git a/logback-classic/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java b/logback-classic/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
index 1fa41a8..1b4bb16 100644
--- a/logback-classic/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
+++ b/logback-classic/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
@@ -15,6 +15,7 @@ package org.slf4j.impl;
import static org.junit.Assert.assertEquals;
+import ch.qos.logback.core.status.StatusChecker;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -56,8 +57,8 @@ public class RecursiveInitializationTest {
LoggerContext loggerContext = (LoggerContext) LoggerFactory
.getILoggerFactory();
StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
- StatusManager sm = loggerContext.getStatusManager();
- assertEquals("Was expecting no errors", Status.WARN, sm.getLevel());
+ StatusChecker statusChecker = new StatusChecker(loggerContext);
+ assertEquals("Was expecting no errors", Status.WARN, statusChecker.getHighestLevel(0));
}
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
index d04972e..3c624fa 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
@@ -130,4 +130,5 @@ public class CoreConstants {
public static int BYTES_PER_INT = 4;
public static final int MILLIS_IN_ONE_SECOND = 1000;
+ public final static String XML_PARSING_ERROR = "XML PARSING ERROR";
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java b/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
index 294c2ea..9b6ac3a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
@@ -131,9 +131,11 @@ public abstract class GenericConfigurator extends ContextAwareBase {
synchronized (context.getConfigurationLock()) {
interpreter.play(recorder.saxEventList);
}
+
}
- public void doConfigure(final List<SaxEvent> eventList)
+ // protected since v0.9.30
+ protected void doConfigure(final List<SaxEvent> eventList)
throws JoranException {
buildInterpreter();
EventPlayer player = new EventPlayer(interpreter);
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
index 1b94111..5efbcd0 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
@@ -21,6 +21,7 @@ import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
+import ch.qos.logback.core.CoreConstants;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
@@ -53,32 +54,36 @@ public class SaxEventRecorder extends DefaultHandler implements ContextAware {
public List<SaxEvent> recordEvents(InputSource inputSource)
throws JoranException {
- SAXParser saxParser = null;
+ SAXParser saxParser = buildSaxParser();
+ try {
+ saxParser.parse(inputSource, this);
+ return saxEventList;
+ } catch (IOException ie) {
+ handleError(CoreConstants.XML_PARSING_ERROR+ ". I/O error occurred while parsing xml file", ie);
+ } catch(SAXException se) {
+ handleError(CoreConstants.XML_PARSING_ERROR+ ". Problem parsing XML document. See previously reported errors.", se);
+ } catch (Exception ex) {
+ handleError(CoreConstants.XML_PARSING_ERROR+ ". Unexpected exception while parsing XML document.", ex);
+ }
+ throw new IllegalStateException("This point can never be reached");
+ }
+
+ private void handleError(String errMsg, Throwable t) throws JoranException {
+ addError(errMsg, t);
+ throw new JoranException(errMsg, t);
+ }
+
+ private SAXParser buildSaxParser() throws JoranException {
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setValidating(false);
spf.setNamespaceAware(true);
- saxParser = spf.newSAXParser();
+ return spf.newSAXParser();
} catch (Exception pce) {
String errMsg = "Parser configuration error occured";
addError(errMsg, pce);
throw new JoranException(errMsg, pce);
}
-
- try {
- saxParser.parse(inputSource, this);
- return saxEventList;
-
- } catch (IOException ie) {
- String errMsg = "I/O error occurred while parsing xml file";
- addError(errMsg, ie);
- throw new JoranException(errMsg, ie);
- } catch (Exception ex) {
- String errMsg = "Problem parsing XML document. See previously reported errors. Abandoning all further processing.";
- addError(errMsg, ex);
- throw new JoranException(errMsg, ex);
- }
-
}
public void startDocument() {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java
index 2a5184e..b5d5643 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.sift;
+import java.util.List;
import java.util.Map;
import ch.qos.logback.core.Appender;
@@ -20,7 +21,9 @@ import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.joran.GenericConfigurator;
import ch.qos.logback.core.joran.action.NestedBasicPropertyIA;
import ch.qos.logback.core.joran.action.NestedComplexPropertyIA;
+import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.spi.Interpreter;
+import ch.qos.logback.core.joran.spi.JoranException;
public abstract class SiftingJoranConfiguratorBase<E> extends
GenericConfigurator {
@@ -57,6 +60,9 @@ public abstract class SiftingJoranConfiguratorBase<E> extends
if (errMsg != null && errorEmmissionCount < CoreConstants.MAX_ERROR_COUNT) {
addError(errMsg);
}
+ }
+ public void doConfigure(final List<SaxEvent> eventList) throws JoranException {
+ super.doConfigure(eventList);
}
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/status/StatusChecker.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
similarity index 64%
rename from logback-core/src/test/java/ch/qos/logback/core/status/StatusChecker.java
rename to logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
index 2d023ab..207db5d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/status/StatusChecker.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusChecker.java
@@ -1,93 +1,113 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.status;
-
-import java.util.Iterator;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import ch.qos.logback.core.Context;
-
-public class StatusChecker {
-
- StatusManager sm;
-
- public StatusChecker(StatusManager sm) {
- this.sm = sm;
- }
-
- public StatusChecker(Context context) {
- this.sm = context.getStatusManager();
- }
-
- public boolean isErrorFree() {
- int level = sm.getLevel();
- return level < Status.ERROR;
- }
-
- public boolean containsMatch(int level, String regex) {
- Pattern p = Pattern.compile(regex);
-
- for(Status status: sm.getCopyOfStatusList()) {
- if(level != status.getLevel()) {
- continue;
- }
- String msg = status.getMessage();
- Matcher matcher = p.matcher(msg);
- if (matcher.lookingAt()) {
- return true;
- }
- }
- return false;
-
- }
-
- public boolean containsMatch(String regex) {
- Pattern p = Pattern.compile(regex);
- for(Status status: sm.getCopyOfStatusList()) {
- String msg = status.getMessage();
- Matcher matcher = p.matcher(msg);
- if (matcher.lookingAt()) {
- return true;
- }
- }
- return false;
- }
-
- public int matchCount(String regex) {
- int count = 0;
- Pattern p = Pattern.compile(regex);
- for(Status status: sm.getCopyOfStatusList()) {
- String msg = status.getMessage();
- Matcher matcher = p.matcher(msg);
- if (matcher.lookingAt()) {
- count++;
- }
- }
- return count;
- }
-
- public boolean containsException(Class exceptionType) {
- Iterator stati = sm.getCopyOfStatusList().iterator();
- while (stati.hasNext()) {
- Status status = (Status) stati.next();
- Throwable t = status.getThrowable();
- if (t != null && t.getClass().getName().equals(exceptionType.getName())) {
- return true;
- }
- }
- return false;
- }
-
-}
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.status;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import ch.qos.logback.core.Context;
+
+public class StatusChecker {
+
+ StatusManager sm;
+
+ public StatusChecker(StatusManager sm) {
+ this.sm = sm;
+ }
+
+ public StatusChecker(Context context) {
+ this.sm = context.getStatusManager();
+ }
+
+ private List<Status> filterStatusListByTimeThreshold(List<Status> rawList, long threshold) {
+ List<Status> filteredList = new ArrayList<Status>();
+ for (Status s : rawList) {
+ if (s.getDate() >= threshold)
+ filteredList.add(s);
+ }
+ return filteredList;
+ }
+
+ public int getHighestLevel(long threshold) {
+ List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
+ int maxLevel = Status.INFO;
+ for (Status s : filteredList) {
+ if(s.getLevel() > maxLevel)
+ maxLevel = s.getLevel();
+ }
+ return maxLevel;
+ }
+
+ public boolean isErrorFree(long threshold) {
+ return Status.ERROR > getHighestLevel(threshold);
+ }
+
+ public boolean containsMatch(int level, String regex) {
+ Pattern p = Pattern.compile(regex);
+
+ for (Status status : sm.getCopyOfStatusList()) {
+ if (level != status.getLevel()) {
+ continue;
+ }
+ String msg = status.getMessage();
+ Matcher matcher = p.matcher(msg);
+ if (matcher.lookingAt()) {
+ return true;
+ }
+ }
+ return false;
+
+ }
+
+ public boolean containsMatch(String regex) {
+ Pattern p = Pattern.compile(regex);
+ for (Status status : sm.getCopyOfStatusList()) {
+ String msg = status.getMessage();
+ Matcher matcher = p.matcher(msg);
+ if (matcher.lookingAt()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public int matchCount(String regex) {
+ int count = 0;
+ Pattern p = Pattern.compile(regex);
+ for (Status status : sm.getCopyOfStatusList()) {
+ String msg = status.getMessage();
+ Matcher matcher = p.matcher(msg);
+ if (matcher.lookingAt()) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ public boolean containsException(Class exceptionType) {
+ Iterator stati = sm.getCopyOfStatusList().iterator();
+ while (stati.hasNext()) {
+ Status status = (Status) stati.next();
+ Throwable t = status.getThrowable();
+ if (t != null && t.getClass().getName().equals(exceptionType.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusManager.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusManager.java
index 46410cd..f64fa7c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusManager.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusManager.java
@@ -41,7 +41,7 @@ public interface StatusManager {
*
* @return
*/
- public int getLevel();
+ //public int getLevel();
/**
* Return the number of status entries.
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java b/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
index 4f60696..40394cd 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
@@ -22,6 +22,7 @@ import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.helpers.ThrowableToStringArray;
import ch.qos.logback.core.status.ErrorStatus;
import ch.qos.logback.core.status.Status;
+import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.status.StatusManager;
public class StatusPrinter {
@@ -51,7 +52,8 @@ public class StatusPrinter {
ps.println("WARN: Context named \"" + context.getName()
+ "\" has no status manager");
} else {
- if (sm.getLevel() == ErrorStatus.WARN || (sm.getLevel() == ErrorStatus.ERROR) ) {
+ StatusChecker sc = new StatusChecker(context);
+ if (sc.getHighestLevel(0) >= ErrorStatus.WARN) {
print(sm);
}
}
@@ -73,7 +75,8 @@ public class StatusPrinter {
ps.println("WARN: Context named \"" + context.getName()
+ "\" has no status manager");
} else {
- if (sm.getLevel() == ErrorStatus.ERROR) {
+ StatusChecker sc = new StatusChecker(context);
+ if (sc.getHighestLevel(0) == ErrorStatus.ERROR) {
print(sm);
}
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
index 3a9616a..0250640 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.List;
+import ch.qos.logback.core.status.StatusChecker;
import org.junit.Test;
import ch.qos.logback.core.Appender;
@@ -110,8 +111,9 @@ public class FileAppenderTest extends AbstractAppenderTest<Object> {
assertTrue(appender.isAppend());
StatusManager sm = context.getStatusManager();
- StatusPrinter.print(context);
- assertEquals(Status.WARN, sm.getLevel());
+ //StatusPrinter.print(context);
+ StatusChecker statusChecker = new StatusChecker(context);
+ assertEquals(Status.WARN, statusChecker.getHighestLevel(0));
List<Status> statusList = sm.getCopyOfStatusList();
assertTrue("Expecting status list size to be 2 or larger, but was "
+ statusList.size(), statusList.size() >= 2);
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
index a09fedc..f8ce354 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
@@ -27,6 +27,7 @@ import java.util.HashMap;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
+import ch.qos.logback.core.CoreConstants;
import org.junit.Test;
import ch.qos.logback.core.Context;
@@ -99,8 +100,7 @@ public class TrivialConfiguratorTest {
Status s1 = tsl.list.get(1);
assertTrue(s1
.getMessage()
- .startsWith(
- "Problem parsing XML document. See previously reported errors. Abandoning all further processing."));
+ .startsWith(CoreConstants.XML_PARSING_ERROR));
}
@Test
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
index 9c26831..379a804 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
@@ -51,6 +51,7 @@ public class IncludeActionTest {
final static String SECOND_FILE_KEY = "secondFileKey";
Context context = new ContextBase();
+ StatusChecker statusChecker = new StatusChecker(context);
TrivialConfigurator tc;
static final String INCLUSION_DIR_PREFIX = CoreTestConstants.JORAN_INPUT_PREFIX
@@ -130,9 +131,8 @@ public class IncludeActionTest {
public void noFileFound() throws JoranException {
System.setProperty(INCLUDE_KEY, "toto");
tc.doConfigure(TOP_BY_FILE);
- assertEquals(Status.ERROR, context.getStatusManager().getLevel());
- StatusChecker sc = new StatusChecker(context.getStatusManager());
- assertTrue(sc.containsException(FileNotFoundException.class));
+ assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
+ assertTrue(statusChecker.containsException(FileNotFoundException.class));
}
@Test
@@ -140,9 +140,8 @@ public class IncludeActionTest {
String tmpOut = copyToTemp(INVALID);
System.setProperty(INCLUDE_KEY, tmpOut);
tc.doConfigure(TOP_BY_FILE);
- assertEquals(Status.ERROR, context.getStatusManager().getLevel());
- StatusChecker sc = new StatusChecker(context.getStatusManager());
- assertTrue(sc.containsException(SAXParseException.class));
+ assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
+ assertTrue(statusChecker.containsException(SAXParseException.class));
// we like to erase the temp file in order to see
// if http://jira.qos.ch/browse/LBCORE-122 was fixed
@@ -169,23 +168,20 @@ public class IncludeActionTest {
public void malformedURL() throws JoranException {
System.setProperty(INCLUDE_KEY, "htp://logback.qos.ch");
tc.doConfigure(TOP_BY_URL);
- assertEquals(Status.ERROR, context.getStatusManager().getLevel());
- StatusChecker sc = new StatusChecker(context.getStatusManager());
- assertTrue(sc.containsException(MalformedURLException.class));
+ assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
+ assertTrue(statusChecker.containsException(MalformedURLException.class));
}
@Test
public void unknownURL() throws JoranException {
System.setProperty(INCLUDE_KEY, "http://logback2345.qos.ch");
tc.doConfigure(TOP_BY_URL);
- assertEquals(Status.ERROR, context.getStatusManager().getLevel());
- StatusChecker sc = new StatusChecker(context.getStatusManager());
-
+ assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
// OS X throws IOException instead of UnknownHostException
// http://jira.qos.ch/browse/LBCORE-129
// This behavior has been observed on Windows XP as well
- assertTrue(sc.containsException(UnknownHostException.class)
- || sc.containsException(IOException.class));
+ assertTrue(statusChecker.containsException(UnknownHostException.class)
+ || statusChecker.containsException(IOException.class));
}
@Test
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
index 30a042f..86acd87 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
@@ -95,7 +95,7 @@ public class IfThenElseTest {
tc.doConfigure(CONDITIONAL_DIR_PREFIX+"ifWithoutElse.xml");
verifyConfig(new String[] {"BEGIN", "END"});
StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/event/SaxEventRecorderTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/event/SaxEventRecorderTest.java
index c7f7552..9a68ef7 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/event/SaxEventRecorderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/event/SaxEventRecorderTest.java
@@ -21,6 +21,7 @@ import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
+import ch.qos.logback.core.status.StatusChecker;
import org.junit.Test;
import org.xml.sax.Attributes;
@@ -38,7 +39,7 @@ import ch.qos.logback.core.util.CoreTestConstants;
public class SaxEventRecorderTest {
Context context = new ContextBase();
-
+ StatusChecker statusChecker = new StatusChecker(context);
SAXParser createParser() throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
@@ -65,8 +66,7 @@ public class SaxEventRecorderTest {
@Test
public void test1() throws Exception {
List<SaxEvent> seList = doTest("event1.xml");
- StatusManager sm = context.getStatusManager();
- assertTrue(sm.getLevel() == Status.INFO);
+ assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
//dump(seList);
assertEquals(11, seList.size());
}
@@ -75,7 +75,7 @@ public class SaxEventRecorderTest {
public void test2() throws Exception {
List<SaxEvent> seList = doTest("ampEvent.xml");
StatusManager sm = context.getStatusManager();
- assertTrue(sm.getLevel() == Status.INFO);
+ assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
//dump(seList);
assertEquals(3, seList.size());
@@ -87,8 +87,8 @@ public class SaxEventRecorderTest {
public void test3() throws Exception {
List<SaxEvent> seList = doTest("inc.xml");
StatusManager sm = context.getStatusManager();
- assertTrue(sm.getLevel() == Status.INFO);
- //dump(seList);
+ assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
+ //dump(seList);
assertEquals(4, seList.size());
StartEvent se = (StartEvent) seList.get(1);
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java
index 3084601..8e056e2 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java
@@ -255,7 +255,7 @@ public class MultiThreadedRollingTest {
multiThreadedHarness.execute(runnableArray);
StatusChecker checker = new StatusChecker(context.getStatusManager());
- if (!checker.isErrorFree()) {
+ if (!checker.isErrorFree(0)) {
StatusPrinter.print(context);
fail("errors reported");
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/RenameUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/RenameUtilTest.java
index fd8888b..05f5891 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/RenameUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/RenameUtilTest.java
@@ -68,7 +68,7 @@ public class RenameUtilTest {
renameUtil.rename(fromFile.toString(), new File(randomTARGETDir + "/to.test").toString());
StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- assertTrue(statusChecker.isErrorFree());
+ assertTrue(statusChecker.isErrorFree(0));
}
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
index 718a66b..d1b2b06 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
@@ -107,9 +107,9 @@ public class RollingFileAppenderTest extends AbstractAppenderTest<Object> {
rfa.start();
- StatusManager sm = context.getStatusManager();
+ StatusChecker checker = new StatusChecker(context);
assertFalse(rfa.isStarted());
- assertEquals(Status.ERROR, sm.getLevel());
+ assertEquals(Status.ERROR, checker.getHighestLevel(0));
}
@Test
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/CompressTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/CompressTest.java
index 865a579..a08db12 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/CompressTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/CompressTest.java
@@ -87,7 +87,7 @@ public class CompressTest {
+ "compress1.txt.gz", null);
StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
assertTrue(Compare.gzCompare(CoreTestConstants.OUTPUT_DIR_PREFIX
+ "compress1.txt.gz", CoreTestConstants.TEST_DIR_PREFIX
+ "witness/compress1.txt.gz"));
@@ -102,7 +102,7 @@ public class CompressTest {
+ "compress2.txt", null);
StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
assertTrue(Compare.gzCompare(CoreTestConstants.OUTPUT_DIR_PREFIX
+ "compress2.txt.gz", CoreTestConstants.TEST_DIR_PREFIX
@@ -117,7 +117,7 @@ public class CompressTest {
+ "input/compress3.txt", CoreTestConstants.OUTPUT_DIR_PREFIX
+ "compress3.txt", "compress3.txt");
StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree());
+ assertTrue(checker.isErrorFree(0));
// we don't know how to compare .zip files
// assertTrue(Compare.compare(CoreTestConstants.OUTPUT_DIR_PREFIX
-----------------------------------------------------------------------
Summary of changes:
.../access/db/DBAppenderIntegrationTest.java | 4 +-
.../classic/boolex/GEventEvaluatorTest.java | 2 +-
.../classic/db/DBAppenderIntegrationTest.java | 2 +-
.../logback/classic/issue/lbcore211/Lbcore211.java | 34 ++++
.../classic/joran/JoranConfiguratorTest.java | 8 +-
.../classic/joran/conditional/ConditionalTest.java | 6 +-
.../TimeBasedRollingWithConfigFileTest.java | 4 +-
.../logback/classic/rolling/UniqueFileTest.java | 2 +-
.../classic/turbo/ReconfigureOnChangeTest.java | 2 +-
.../slf4j/impl/RecursiveInitializationTest.java | 5 +-
.../java/ch/qos/logback/core/CoreConstants.java | 1 +
.../logback/core/joran/GenericConfigurator.java | 4 +-
.../logback/core/joran/event/SaxEventRecorder.java | 39 ++--
.../core/sift/SiftingJoranConfiguratorBase.java | 6 +
.../ch/qos/logback/core/status/StatusChecker.java | 206 +++++++++++---------
.../ch/qos/logback/core/status/StatusManager.java | 2 +-
.../ch/qos/logback/core/util/StatusPrinter.java | 7 +-
.../logback/core/appender/FileAppenderTest.java | 6 +-
.../core/joran/TrivialConfiguratorTest.java | 4 +-
.../core/joran/action/IncludeActionTest.java | 24 +--
.../core/joran/conditional/IfThenElseTest.java | 2 +-
.../core/joran/event/SaxEventRecorderTest.java | 12 +-
.../core/rolling/MultiThreadedRollingTest.java | 2 +-
.../qos/logback/core/rolling/RenameUtilTest.java | 2 +-
.../core/rolling/RollingFileAppenderTest.java | 4 +-
.../logback/core/rolling/helper/CompressTest.java | 6 +-
26 files changed, 234 insertions(+), 162 deletions(-)
create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore211/Lbcore211.java
rename logback-core/src/{test => main}/java/ch/qos/logback/core/status/StatusChecker.java (64%)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0
[JIRA] Created: (LBCORE-211) HTMLLayout and LayoutWrappingEncoder produces invalid/unusuable output
by Jessica-Aileen Alten (JIRA) 20 Jun '11
by Jessica-Aileen Alten (JIRA) 20 Jun '11
20 Jun '11
HTMLLayout and LayoutWrappingEncoder produces invalid/unusuable output
----------------------------------------------------------------------
Key: LBCORE-211
URL: http://jira.qos.ch/browse/LBCORE-211
Project: logback-core
Issue Type: Bug
Affects Versions: 0.9.29
Environment: Windows Server 2008 R2 64 bit, JDK 1.6.0_26
Reporter: Jessica-Aileen Alten
Assignee: Logback dev list
HTMLLayout and LayoutWrappingEncoder are producing unusuable HTML output, the HTML file isn't closed by </table></body></html>. When you are using the append element, a new logging event produces the complete html header, headlines and table header.
Configuration:
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>../../logs/server_nodes.html</file>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%d{ISO8601}%msg</pattern>
</layout>
</encoder>
<append>true</append>
</appender>
<logger name="file.logger" additivity="false">
<level value="info" />
<appender-ref ref="FILE" />
</logger>
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
2
4