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

svn commit: r1774 - logback/trunk/logback-examples/src/main/java/chapter3
by noreply.ceki@qos.ch 23 Aug '08
by noreply.ceki@qos.ch 23 Aug '08
23 Aug '08
Author: ceki
Date: Sat Aug 23 23:18:06 2008
New Revision: 1774
Modified:
logback/trunk/logback-examples/src/main/java/chapter3/variableSubstitution1.xml
Log:
- simplifying the config file
Modified: logback/trunk/logback-examples/src/main/java/chapter3/variableSubstitution1.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/variableSubstitution1.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/variableSubstitution1.xml Sat Aug 23 23:18:06 2008
@@ -1,21 +1,11 @@
<configuration>
- <substitutionProperty name="user.home.dir"
- value="/Users/seb" />
+ <substitutionProperty name="user.home.dir" value="/home/sebastien" />
- <appender name="FILE"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${user.home.dir}/myApp.log</file>
- <rollingPolicy
- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern>
- myApp-%d{yyyy-MM-dd-HH}.log
- </FileNamePattern>
- </rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>
- %date %level [%thread] %logger{10} [%file : %line] %msg%n
- </Pattern>
+ <Pattern>%msg%n</Pattern>
</layout>
</appender>
1
0
Author: ceki
Date: Sat Aug 23 23:00:14 2008
New Revision: 1773
Modified:
logback/trunk/ (props changed)
Log:
- adding "sandbox" to ignored list
1
0
Author: ceki
Date: Sat Aug 23 22:57:50 2008
New Revision: 1772
Added:
logback/trunk/logback-site/src/site/resources/manual/images/chapter3/
logback/trunk/logback-site/src/site/resources/manual/images/chapter3/appenderSyntax.png (contents, props changed)
logback/trunk/logback-site/src/site/resources/manual/images/chapter3/basicSyntax.png (contents, props changed)
logback/trunk/logback-site/src/site/resources/manual/images/chapter3/sample.xml
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ContextPropertyAction.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/MatcherAction.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java
logback/trunk/logback-examples/src/main/java/chapter3/additivityFlag.xml
logback/trunk/logback-examples/src/main/java/chapter3/multiple.xml
logback/trunk/logback-examples/src/main/java/chapter3/restricted.xml
logback/trunk/logback-site/src/site/pages/manual/joran.html
Log:
- ExecutionContext class has been renamed as InterpretationContext a few months ago. Syncing the docs.
- ongoing work on the documentation
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java Sat Aug 23 22:57:50 2008
@@ -82,7 +82,7 @@
RuleStore rs = new SimpleRuleStore(context);
addInstanceRules(rs);
this.interpreter = new Interpreter(context, rs);
- InterpretationContext ec = interpreter.getExecutionContext();
+ InterpretationContext ec = interpreter.getInterpretationContext();
ec.setContext(context);
addImplicitRules(interpreter);
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java Sat Aug 23 22:57:50 2008
@@ -84,12 +84,12 @@
@Override
protected void buildInterpreter() {
super.buildInterpreter();
- Map<String, Object> omap = interpreter.getExecutionContext().getObjectMap();
+ Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
omap.put(ActionConst.APPENDER_BAG, new HashMap());
omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap());
}
public InterpretationContext getExecutionContext() {
- return interpreter.getExecutionContext();
+ return interpreter.getInterpretationContext();
}
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java Sat Aug 23 22:57:50 2008
@@ -9,7 +9,6 @@
*/
package ch.qos.logback.core.joran.action;
-
import java.util.HashMap;
import org.xml.sax.Attributes;
@@ -20,47 +19,44 @@
import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.util.OptionHelper;
-
-
public class AppenderAction<E> extends Action {
Appender appender;
private boolean inError = false;
/**
* Instantiates an appender of the given class and sets its name.
- *
- * The appender thus generated is placed in the ExecutionContext appender bag.
+ *
+ * The appender thus generated is placed in the {@link InterpretationContext}'s
+ * appender bag.
*/
@SuppressWarnings("unchecked")
- public void begin(
- InterpretationContext ec, String localName, Attributes attributes) throws ActionException {
+ public void begin(InterpretationContext ec, String localName,
+ Attributes attributes) throws ActionException {
// We are just beginning, reset variables
appender = null;
inError = false;
-
+
String className = attributes.getValue(CLASS_ATTRIBUTE);
- if(OptionHelper.isEmpty(className)) {
- addError(
- "Missing class name for appender. Near ["
- + localName + "] line " + getLineNumber(ec));
+ if (OptionHelper.isEmpty(className)) {
+ addError("Missing class name for appender. Near [" + localName
+ + "] line " + getLineNumber(ec));
inError = true;
return;
}
-
try {
- addInfo("About to instantiate appender of type ["+className+"]");
+ addInfo("About to instantiate appender of type [" + className + "]");
- appender = (Appender) OptionHelper.instantiateByClassName(
- className, ch.qos.logback.core.Appender.class, context);
+ appender = (Appender) OptionHelper.instantiateByClassName(className,
+ ch.qos.logback.core.Appender.class, context);
appender.setContext(context);
String appenderName = attributes.getValue(NAME_ATTRIBUTE);
if (OptionHelper.isEmpty(appenderName)) {
- addWarn(
- "No appender name given for appender of type " + className + "].");
+ addWarn("No appender name given for appender of type " + className
+ + "].");
} else {
appender.setName(appenderName);
addInfo("Naming appender as [" + appenderName + "]");
@@ -68,8 +64,8 @@
// The execution context contains a bag which contains the appenders
// created thus far.
- HashMap<String, Appender> appenderBag =
- (HashMap) ec.getObjectMap().get(ActionConst.APPENDER_BAG);
+ HashMap<String, Appender> appenderBag = (HashMap) ec.getObjectMap().get(
+ ActionConst.APPENDER_BAG);
// add the appender just created to the appender bag.
appenderBag.put(appenderName, appender);
@@ -77,15 +73,15 @@
ec.pushObject(appender);
} catch (Exception oops) {
inError = true;
- addError(
- "Could not create an Appender of type ["+className+"].", oops);
+ addError("Could not create an Appender of type [" + className + "].",
+ oops);
throw new ActionException(oops);
}
}
/**
- * Once the children elements are also parsed, now is the time to activate
- * the appender options.
+ * Once the children elements are also parsed, now is the time to activate the
+ * appender options.
*/
public void end(InterpretationContext ec, String name) {
if (inError) {
@@ -99,13 +95,11 @@
Object o = ec.peekObject();
if (o != appender) {
- addWarn(
- "The object at the of the stack is not the appender named ["
- + appender.getName() + "] pushed earlier.");
+ addWarn("The object at the of the stack is not the appender named ["
+ + appender.getName() + "] pushed earlier.");
} else {
- addInfo(
- "Popping appender named [" + appender.getName()
- + "] from the object stack");
+ addInfo("Popping appender named [" + appender.getName()
+ + "] from the object stack");
ec.popObject();
}
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ContextPropertyAction.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ContextPropertyAction.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ContextPropertyAction.java Sat Aug 23 22:57:50 2008
@@ -12,7 +12,7 @@
public class ContextPropertyAction extends PropertyAction {
/**
- * Add all the properties found in the argument named 'props' to an ExecutionContext.
+ * Add all the properties found in the argument named 'props' to an InterpretationContext.
*/
public void setProperties(InterpretationContext ec, Properties props) {
// TODO : test this method
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/MatcherAction.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/MatcherAction.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/MatcherAction.java Sat Aug 23 22:57:50 2008
@@ -1,7 +1,7 @@
/**
- * LOGBack: the generic, reliable, fast and flexible logging framework.
+ * Logback: the generic, reliable, fast and flexible logging framework.
*
- * Copyright (C) 1999-2006, QOS.ch
+ * Copyright (C) 2000-2008, QOS.ch
*
* This library is free software, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
@@ -23,11 +23,7 @@
final static String REGEX = "regex";
private boolean inError = false;
- /**
- * Instantiates an appender of the given class and sets its name.
- *
- * The appender thus generated is placed in the ExecutionContext appender bag.
- */
+
public void begin(InterpretationContext ec, String localName, Attributes attributes)
throws ActionException {
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java Sat Aug 23 22:57:50 2008
@@ -35,16 +35,16 @@
if(se instanceof StartEvent) {
interpreter.startElement((StartEvent) se);
// invoke fireInPlay after startElement processing
- interpreter.getExecutionContext().fireInPlay(se);
+ interpreter.getInterpretationContext().fireInPlay(se);
}
if(se instanceof BodyEvent) {
// invoke fireInPlay before characters processing
- interpreter.getExecutionContext().fireInPlay(se);
+ interpreter.getInterpretationContext().fireInPlay(se);
interpreter.characters((BodyEvent) se);
}
if(se instanceof EndEvent) {
// invoke fireInPlay before endElement processing
- interpreter.getExecutionContext().fireInPlay(se);
+ interpreter.getInterpretationContext().fireInPlay(se);
interpreter.endElement((EndEvent) se);
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java Sat Aug 23 22:57:50 2008
@@ -29,7 +29,7 @@
/**
*
- * The ExecutionContext contains the contextual state of a Joran parsing
+ * An InterpretationContext contains the contextual state of a Joran parsing
* session. {@link Action} objects depend on this context to exchange
* and store information.
*
@@ -135,8 +135,6 @@
}
}
-
-
public String getSubstitutionProperty(String key) {
return context.getProperty(key);
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java Sat Aug 23 22:57:50 2008
@@ -98,7 +98,15 @@
player = new EventPlayer(this);
}
+
+ /**
+ * @deprecated replaced by {@link #getInterpretationContext()}
+ */
public InterpretationContext getExecutionContext() {
+ return getInterpretationContext();
+ }
+
+ public InterpretationContext getInterpretationContext() {
return ec;
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java Sat Aug 23 22:57:50 2008
@@ -172,7 +172,7 @@
}
// if replacement is still null, use the defaultReplacement which
- // still be null
+ // can be null as well
if (replacement == null) {
replacement = defaultReplacement;
}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java Sat Aug 23 22:57:50 2008
@@ -33,7 +33,7 @@
final public void doConfigure(final List<SaxEvent> eventList)
throws JoranException {
buildInterpreter();
- interpreter.getExecutionContext().pushObject(ff);
+ interpreter.getInterpretationContext().pushObject(ff);
EventPlayer player = new EventPlayer(interpreter);
player.play(eventList);
}
Modified: logback/trunk/logback-examples/src/main/java/chapter3/additivityFlag.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/additivityFlag.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/additivityFlag.xml Sat Aug 23 22:57:50 2008
@@ -1,14 +1,7 @@
<configuration>
- <appender name="FILE"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <appender name="FILE"class="ch.qos.logback.core.FileAppender">
<file>foo.log</file>
- <rollingPolicy
- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern>
- foo-%d{yyyy-MM-dd-HH-mm-ss}.log
- </FileNamePattern>
- </rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%date %level [%thread] %logger{10} [%file : %line] %msg%n
@@ -16,8 +9,7 @@
</layout>
</appender>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%msg%n</Pattern>
</layout>
Modified: logback/trunk/logback-examples/src/main/java/chapter3/multiple.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/multiple.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/multiple.xml Sat Aug 23 22:57:50 2008
@@ -1,13 +1,8 @@
<configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
-
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern>myApp-%d{yyyy-MM-dd-HH-mm-ss}.log</FileNamePattern>
- </rollingPolicy>
-
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</Pattern>
+ <Pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</Pattern>
</layout>
</appender>
Modified: logback/trunk/logback-examples/src/main/java/chapter3/restricted.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/restricted.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/restricted.xml Sat Aug 23 22:57:50 2008
@@ -1,23 +1,13 @@
<configuration>
- <appender name="FILE"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
- <rollingPolicy
- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern>
- myApp-%d{yyyy-MM-dd-HH-mm-ss}.log
- </FileNamePattern>
- </rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>
- %date %level [%thread] %logger{10} [%file : %line] %msg%n
- </Pattern>
+ <Pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</Pattern>
</layout>
</appender>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%msg%n</Pattern>
</layout>
Modified: logback/trunk/logback-site/src/site/pages/manual/joran.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/joran.html (original)
+++ logback/trunk/logback-site/src/site/pages/manual/joran.html Sat Aug 23 22:57:50 2008
@@ -284,7 +284,7 @@
data. It does <em>not</em> affect logback's configuration
otherwise, in particuler with respect to logger levels. (Put
differently, no, the root logger will <em>not</em> be set to
- DEBUG.)
+ <code>DEBUG</code>.)
</p>
@@ -353,8 +353,8 @@
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;
-public class MyApp2 {
- final static Logger logger = LoggerFactory.getLogger(MyApp2.class);
+public class MyApp3 {
+ final static Logger logger = LoggerFactory.getLogger(MyApp3.class);
public static void main(String[] args) {
// assume logback is in use
@@ -386,10 +386,7 @@
then finally asks the configurator to configure the context using
configuration file passed as parameter to the application. Internal
status data is printed in case errors occur.
- </p>
-
-
-
+ </p>
<h2>
<a name="syntax" href="#syntax">Configuration file Syntax</a>
@@ -420,15 +417,9 @@
<p align="left">
<img src="images/chapter3/basicSyntax.png"
- alt="basic Syntax" title="Basic configuration file structure"/>
+ alt="basic Syntax" title="Basic configuration file structure"/>
</p>
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
-
-
<h4>Configuring Loggers, or the <code><logger></code> element</h4>
<p>A logger is configured using the <code>logger</code> element. A
@@ -488,7 +479,7 @@
declaring it and setting its level, as the next example
illustrates. Suppose we are no longer interested in seeing any DEBUG
messages from any component belonging to the "chapter3" package. The
- following configuration file shows how.
+ following configuration file shows how to achieve that.
</p>
<em>Example 3.<span class="autoEx"/>: Setting the level of a logger (logback-examples/src/main/java/chapter3/sample2.xml)</em>
@@ -510,18 +501,18 @@
</configuration></pre></div>
-<p>This new configuration will yield the following output, when used
-with the same <code>chapter3.MyApp2</code> class.
-</p>
+ <p>This new configuration will yield the following output, when
+ invoked with the <em>MyApp3</em> application.
+ </p>
-<div class="source"><pre>17:34:07.578 [main] INFO chapter3.MyApp2 - Entering application.
-17:34:07.578 [main] INFO chapter3.MyApp2 - Exiting application.</pre></div>
+<div class="source"><pre>17:34:07.578 [main] INFO chapter3.MyApp3 - Entering application.
+17:34:07.578 [main] INFO chapter3.MyApp3 - Exiting application.</pre></div>
-<p>Obviously, you can configure the levels of as many loggers as you
-wish. In the next configuration file we set the level of the
-<em>chapter3</em> logger to <code>INFO</code> but at the same time set
-the level of the <em>chapter3.Foo</em> logger to <code>DEBUG</code>.
-</p>
+ <p>You can configure the levels of as many loggers as you wish. In
+ the next configuration file, we set the level of the
+ <em>chapter3</em> logger to INFO but at the same time set the level
+ of the <em>chapter3.Foo</em> logger to <code>DEBUG</code>.
+ </p>
<em>Example 3.<span class="autoEx"/>: Setting the level of multiple loggers (logback-examples/src/main/java/chapter3/sample3.xml)</em>
<div class="source"><pre><configuration>
@@ -544,57 +535,62 @@
</configuration></pre></div>
- <p>Running <code>MyApp2</code> with this configuration file will
+ <p>Running <code>MyApp3</code> with this configuration file will
result in the following output on the console:
</p>
-<div class="source"><pre>17:39:27.593 [main] INFO chapter3.MyApp2 - Entering application.
+<div class="source"><pre>17:39:27.593 [main] INFO chapter3.MyApp3 - Entering application.
17:39:27.593 [main] DEBUG chapter3.Foo - Did it again!
-17:39:27.593 [main] INFO chapter3.MyApp2 - Exiting application.</pre></div>
+17:39:27.593 [main] INFO chapter3.MyApp3 - Exiting application.</pre></div>
- <p>After <code>JoranConfigurator</code> configures logback using
- the <em>sample3.xml</em> file, the logger settings, more
- specifically their levels, are summarized in the following table.
+ <p>The table below list the loggers and their levels, after
+ <code>JoranConfigurator</code> has configured logback with the
+ <em>sample3.xml</em> configuration file.
</p>
-<table class="bodyTable">
- <tr>
- <th>Logger name</th>
- <th>Assigned Level</th>
- <th>Effective Level</th>
- </tr>
- <tr>
- <td>root</td>
- <td><code>DEBUG</code></td>
- <td><code>DEBUG</code></td>
- </tr>
- <tr class="alt">
- <td>chapter3</td>
- <td><code>INFO</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr>
- <td>chapter3.MyApp2</td>
- <td><code>null</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr class="alt">
- <td>chapter3.Foo</td>
- <td><code>DEBUG</code></td>
- <td><code>DEBUG</code></td>
- </tr>
-</table>
+ <table class="bodyTable">
+ <tr>
+ <th>Logger name</th>
+ <th>Assigned Level</th>
+ <th>Effective Level</th>
+ </tr>
+ <tr>
+ <td>root</td>
+ <td><code>DEBUG</code></td>
+ <td><code>DEBUG</code></td>
+ </tr>
+ <tr class="alt">
+ <td>chapter3</td>
+ <td><code>INFO</code></td>
+ <td><code>INFO</code></td>
+ </tr>
+ <tr>
+ <td>chapter3.MyApp3</td>
+ <td><code>null</code></td>
+ <td><code>INFO</code></td>
+ </tr>
+ <tr class="alt">
+ <td>chapter3.Foo</td>
+ <td><code>DEBUG</code></td>
+ <td><code>DEBUG</code></td>
+ </tr>
+ </table>
<p>It follows that the two logging statements of level
- <code>INFO</code> in the <code>MyApp2</code> class as well as the
+ <code>INFO</code> in the <code>MyApp3</code> class as well as the
DEBUG messages in <code>Foo.doIt()</code> are all enabled. Note that
the level of the root logger is always set to a non-null value,
- which is DEBUG by default. One rather important point to remember
- is that the <a
+ which is DEBUG by default.
+ </p>
+
+ <p>Let us note that the <a
href="architecture.html#basic_selection">basic-selection rule</a>
depends on the effective level of the logger being invoked, not the
- level of the logger where appenders are attached. The configuration
- file <em>sample4.xml</em> is a case in point:
+ level of the logger where appenders are attached. Loback will first
+ determine wheteher a logging statement is enabled or not, and if
+ enabled, it will invoke the appenders found in the logger hierarchy,
+ regardless of their level. The configuration file
+ <em>sample4.xml</em> is a case in point:
</p>
<em>Example 3.<span class="autoEx"/>: Logger level sample
@@ -612,14 +608,15 @@
<b><logger name="chapter3" level="INFO" /></b>
+ <!-- turn OFF all logging (children can override) -->
<root <b>level="OFF"</b>>
<appender-ref ref="STDOUT" />
</root>
</configuration></pre></div>
- <p>The following table lists the loggers and their level setting
- after applying the <em>sample4.xml</em> configuration file.
+ <p>The following table lists the loggers and their levels after
+ applying the <em>sample4.xml</em> configuration file.
</p>
<table class="bodyTable">
@@ -639,7 +636,7 @@
<td><code>INFO</code></td>
</tr>
<tr>
- <td>chapter3.MyApp2</td>
+ <td>chapter3.MyApp3</td>
<td><code>null</code></td>
<td><code>INFO</code></td>
</tr>
@@ -652,77 +649,73 @@
<p>The ConsoleAppender named <em>STDOUT</em>, the only configured
appender in <em>sample4.xml</em>, is attached to the root logger
- whose level is set to <code>OFF</code>. However, running MyApp2 with
- configuration script <em>sample4.xml</em> will output:
+ whose level is set to <code>OFF</code>. However, running
+ <em>MyApp3</em> with configuration script <em>sample4.xml</em> will
+ yield:
</p>
- <div class="source"><pre>17:52:23.609 [main] INFO chapter3.MyApp2 -
-Entering application. 17:52:23.609 [main] INFO chapter3.MyApp2 -
-Exiting application.</pre></div>
+ <div class="source"><pre>17:52:23.609 [main] INFO chapter3.MyApp3 - Entering application.
+17:52:23.609 [main] INFO chapter3.MyApp3 - Exiting application.</pre></div>
<p>Thus, the level of the root logger has no apparent effect because
- the loggers in <code>chapter3.MyApp2</code> and
- <code>chapter3.Foo</code> classes, namely <em>chapter3.MyApp2</em>
- and <em>chapter3.Foo</em>, inherit their level from the
- <em>chapter3</em> logger which has its level set to
- <code>INFO</code>. As noted previously, the <em>chapter3</em>
+ the loggers in <code>chapter3.MyApp3</code> and
+ <code>chapter3.Foo</code> classes are all enabled for the
+ <code>INFO</code> level. As a side note, the <em>chapter3</em>
logger exists by virtue of its declaration in the configuration file
- even if the Java source code does not directly refer to it.
</p>
<h4>Configuring Appenders</h4>
- <p>Appenders are configured using <em>appender</em> elements. These
- elements admit two attributes <em>name</em> and <em>class</em> both
- of which are mandatory. The <em>name</em> attribute specifies the
- name of the appender whereas the <em>class</em> attribute specifies
- the fully qualified name of the class of which the named appender
- will be an instance. The <em>appender</em> may contain zero or one
- <em>layout</em> elements and zero or more <em>filter</em>
- elements. Appart from these two basic elements, <em>appender</em>
- elements may contain any element that corresponds to a setter method
- of the appender class, to configure the appender's options.
-</p>
+ <p>Appenders are configured using <code><appender></code>
+ elements, taking two attributes <span class="attr">name</span> and
+ <span class="attr">class</span>, both of which are mandatory. The
+ <span class="attr">name</span> attribute specifies the name of the
+ appender whereas the <span class="attr">class</span> attribute
+ specifies the fully qualified name of the class of which the named
+ appender will be an instance. The <code><appender></code>
+ element may contain zero or one <code><layout></code> elements
+ and zero or more <code><filter></code> elements. Appart from
+ these two common elements, <code><appender></code> elements may
+ contain any number of element corresponding to javabean properties
+ of the appender class. Seamlessly supporting any property of a given
+ logback component is one of the major strengths of Joran. The
+ following diagram illustrates the common structure. Note that
+ support for properties is not visible.
+ </p>
-<p>
-The <em>layout</em> element takes a mandatory class attribute specifying
-the fully qualified name of the class of which the associated layout
-should be an instance. Like the <em>appender</em> element, it may contain
-other elements, referring to setter methods, to configure its options.
-</p>
+ <p align="left">
+ <img src="images/chapter3/appenderSyntax.png"
+ alt="Appender Syntax" title="Appender element syntax"/>
+ </p>
-<p>
-Logging to multiple appenders is as easy as defining the various appenders
-and referencing them in a logger, as the next configuration file illustrates:
-</p>
+ <p>The <code><layout></code> element takes a mandatory class
+ attribute specifying the fully qualified name of the class of which
+ the associated layout should be an instance. Like the
+ <code><appender></code> element, it may contain other elements
+ corresponding to properties of the layout class.
+ </p>
+
+ <p>Logging to multiple appenders is as easy as defining the various
+ appenders and referencing them in a logger, as the next
+ configuration file illustrates:
+ </p>
<em>Example 3.<span class="autoEx"/>: Multiple loggers (logback-examples/src/main/java/chapter3/multiple.xml)</em>
<div class="source"><pre><configuration>
- <appender name="<b>FILE</b>"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <appender name="<b>FILE</b>" class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
- <rollingPolicy
- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern>
- myApp-%d{yyyy-MM-dd-HH-mm-ss}.log
- </FileNamePattern>
- </rollingPolicy>
-
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>
- %date %level [%thread] %logger{10} [%file : %line] %msg%n
- </Pattern>
+ <Pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</Pattern>
</layout>
</appender>
<appender name="<b>STDOUT</b>"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>
- %msg%n
- </Pattern>
+ <Pattern>%msg%n</Pattern>
</layout>
</appender>
@@ -747,8 +740,8 @@
<p>The appenders are attached to the root logger by referencing them
by name within an <em>appender-ref</em> element. Note that each
appender has its own layout. Layouts are usually not designed to be
- shared by multiple appenders. XML configuration files do not provide
- any syntactical means for sharing layouts.
+ shared by multiple appenders. As such, logback configuration files
+ do not provide any syntactical means for sharing layouts.
</p>
<p>By default, <b>appenders are cumulative</b>: a logger will log to
@@ -762,12 +755,9 @@
(logback-examples/src/main/java/chapter3/duplicate.xml)</em>
<div class="source"><pre><configuration>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
- </Pattern>
+ <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
@@ -781,21 +771,21 @@
</root>
</configuration></pre></div>
- <p>Running <code>MyApp2</code> with <em>duplicate.xml</em> will
+ <p>Running <code>MyApp3</code> with <em>duplicate.xml</em> will
yield the following output:
</p>
-<div class="source"><pre>14:25:36.343 [main] INFO chapter3.MyApp2 - Entering application.
-14:25:36.343 [main] INFO chapter3.MyApp2 - Entering application.
+<div class="source"><pre>14:25:36.343 [main] INFO chapter3.MyApp3 - Entering application.
+14:25:36.343 [main] INFO chapter3.MyApp3 - Entering application.
14:25:36.359 [main] DEBUG chapter3.Foo - Did it again!
14:25:36.359 [main] DEBUG chapter3.Foo - Did it again!
-14:25:36.359 [main] INFO chapter3.MyApp2 - Exiting application.
-14:25:36.359 [main] INFO chapter3.MyApp2 - Exiting application.</pre></div>
+14:25:36.359 [main] INFO chapter3.MyApp3 - Exiting application.
+14:25:36.359 [main] INFO chapter3.MyApp3 - Exiting application.</pre></div>
<p>Notice the duplicated output. The appender named <em>STDOUT</em>
is attached to two loggers, to root and to <em>chapter3</em>. Since
the root logger is the ancestor of all loggers and <em>chapter3</em>
- is the parent of <em>chapter3.MyApp2</em> and <em>chapter3.Foo</em>,
+ is the parent of <em>chapter3.MyApp3</em> and <em>chapter3.Foo</em>,
logging request made with these two loggers will be output twice,
once because <em>STDOUT</em> is attached to <em>chapter3</em> and
once because it is attached to <em>root</em>.
@@ -812,24 +802,14 @@
(logback-examples/src/main/java/chapter3/restricted.xml)</em>
<div class="source"><pre><configuration>
- <appender name="FILE"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
- <rollingPolicy
- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern>
- myApp-%d{yyyy-MM-dd-HH-mm-ss}.log
- </FileNamePattern>
- </rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>
- %date %level [%thread] %logger{10} [%file : %line] %msg%n
- </Pattern>
+ <Pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</Pattern>
</layout>
</appender>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%msg%n</Pattern>
</layout>
@@ -846,14 +826,15 @@
</configuration></pre></div>
<p>In this example, the console appender will log all the messages
- (for all loggers in the system) whereas only logs under the
- <em>chapter3</em> tree go into the <em>myApp.log</em> file.
+ (for all loggers in the system) whereas only logging request
+ originating from loggers <em>chapter3</em> and below go into the
+ <em>myApp.log</em> file.
</p>
<h4>Overriding the default cumulative behaviour</h4>
<p>In case the default cumulative behavior turns out to be
- unsuitable for one's needs, one can override it by setting the
+ unsuitable for your needs, you can override it by setting the
additivity flag to false. Thus, a branch in your logger tree may
direct output to a set of appenders different than those of the rest
of the tree.
@@ -862,24 +843,14 @@
<em>Example 3.<span class="autoEx"/>: Additivity flag (logback-examples/src/main/java/chapter3/additivityFlag.xml)</em>
<div class="source"><pre><configuration>
- <appender name="FILE"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>foo.log</file>
- <rollingPolicy
- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern>
- foo-%d{yyyy-MM-dd-HH-mm-ss}.log
- </FileNamePattern>
- </rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>
- %date %level [%thread] %logger{10} [%file : %line] %msg%n
- </Pattern>
+ <Pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</Pattern>
</layout>
</appender>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%msg%n</Pattern>
</layout>
@@ -901,9 +872,9 @@
output will be sent to the appender named <em>FILE</em> but not to
any appender attached higher in the hierarchy. Other loggers remain
oblivious to the additivity setting of the <em>chapter3.Foo</em>
- logger. Running the <code>MyApp2</code> application with the
+ logger. Running the <code>MyApp3</code> application with the
<em>additivityFlag.xml</em> configuration file will output results
- on the console from the <em>chapter3.MyApp2</em> logger. However,
+ on the console from the <em>chapter3.MyApp3</em> logger. However,
output from the <em>chapter3.Foo</em> logger will appear in the
<em>foo.log</em> file and only in that file.
</p>
@@ -925,9 +896,9 @@
<em>/home/xyz</em>.
</p>
- <p>The first example shows a declared property at the beginning of the
- configuration file. It is then used further down the file to specify
- the place to create the output file.
+ <p>The first example shows a declared property at the beginning of
+ the configuration file. It is then used further down the file to
+ specify the place to create the output file.
</p>
<em>Example 3.<span class="autoEx"/>: Simple Variable substitution
Added: logback/trunk/logback-site/src/site/resources/manual/images/chapter3/appenderSyntax.png
==============================================================================
Binary file. No diff available.
Added: logback/trunk/logback-site/src/site/resources/manual/images/chapter3/basicSyntax.png
==============================================================================
Binary file. No diff available.
Added: logback/trunk/logback-site/src/site/resources/manual/images/chapter3/sample.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-site/src/site/resources/manual/images/chapter3/sample.xml Sat Aug 23 22:57:50 2008
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>myApp.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <FileNamePattern> myApp-%d{yyyy-MM-dd-HH-mm-ss}.log</FileNamePattern>
+ </rollingPolicy>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</Pattern>
+ </layout>
+ </appender>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="ch.qos.logback.classic.filter.LevelFilter">
+ <level>INFO</level>
+ <onMatch>ACCEPT</onMatch>
+ <onMismatch>DENY</onMismatch>
+ </filter>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%msg%n</Pattern>
+ </layout>
+ </appender>
+ <logger name="chapter3">
+ <appender-ref ref="FILE"/>
+ </logger>
+ <logger name="chapter4">
+ <appender-ref ref="FILE"/>
+ </logger>
+ <root>
+ <level value="debug"/>
+ <appender-ref ref="STDOUT"/>
+ </root>
+</configuration>
1
0

svn commit: r1771 - logback/trunk/logback-site/src/site/pages/manual
by noreply.ceki@qos.ch 22 Aug '08
by noreply.ceki@qos.ch 22 Aug '08
22 Aug '08
Author: ceki
Date: Fri Aug 22 20:06:27 2008
New Revision: 1771
Modified:
logback/trunk/logback-site/src/site/pages/manual/architecture.html
logback/trunk/logback-site/src/site/pages/manual/joran.html
Log:
- ongoing work on documentation
Modified: logback/trunk/logback-site/src/site/pages/manual/architecture.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/architecture.html (original)
+++ logback/trunk/logback-site/src/site/pages/manual/architecture.html Fri Aug 22 20:06:27 2008
@@ -317,9 +317,8 @@
parent <code>X</code>, which has an assigned level.
</p>
- <a name="PrintintMethods"></a>
- <a name="basic_selection"></a>
- <h3>Printing methods</h3>
+ <h3><a name="basic_selection" href="#basic_selection">Printing
+ methods and the basic selection rule</a></h3>
<p>By definition, the printing method determines the level of a
logging request. For example, if <code>L</code> is a logger
Modified: logback/trunk/logback-site/src/site/pages/manual/joran.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/joran.html (original)
+++ logback/trunk/logback-site/src/site/pages/manual/joran.html Fri Aug 22 20:06:27 2008
@@ -487,8 +487,8 @@
<p>Setting the level of a logger or root logger is as simple as
declaring it and setting its level, as the next example
illustrates. Suppose we are no longer interested in seeing any DEBUG
- level logs from any component belonging to the chapter3 package. The
- following configuration file shows how to achieve that.
+ messages from any component belonging to the "chapter3" package. The
+ following configuration file shows how.
</p>
<em>Example 3.<span class="autoEx"/>: Setting the level of a logger (logback-examples/src/main/java/chapter3/sample2.xml)</em>
@@ -500,13 +500,11 @@
</layout>
</appender>
- <b class="red"><logger name="chapter3" level="INFO"/></b>
+ <b><logger name="chapter3" level="INFO"/></b>
-
- <root>
- <!-- The following level element is not necessary since the -->
- <!-- level of the root level is set to DEBUG by default. -->
- <level value="DEBUG" />
+ <!-- Strictly speaking, the level attribute is not necessary since -->
+ <!-- the level of the root level is set to DEBUG by default. -->
+ <root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
@@ -537,48 +535,40 @@
</layout>
</appender>
- <b><logger name="chapter3">
- <level value="INFO" />
- </logger>
+ <b><logger name="chapter3" level="INFO" />
+ <logger name="chapter3.Foo" level="DEBUG" /></b>
- <logger name="chapter3.Foo">
- <level value="DEBUG" />
- </logger></b>
-
- <root>
- <!-- The following level element is not necessary since the -->
- <!-- level of the root level is set to DEBUG by default. -->
- <level value="DEBUG" />
+ <root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration></pre></div>
-<p>Running <code>MyApp2</code> with this configuration file will
-result in the following output on the console:
-</p>
+ <p>Running <code>MyApp2</code> with this configuration file will
+ result in the following output on the console:
+ </p>
<div class="source"><pre>17:39:27.593 [main] INFO chapter3.MyApp2 - Entering application.
17:39:27.593 [main] DEBUG chapter3.Foo - Did it again!
17:39:27.593 [main] INFO chapter3.MyApp2 - Exiting application.</pre></div>
-<p>
-After <code>JoranConfigurator</code> configures logback using the <em>sample3.xml</em>
-file, the logger settings, more specifically their levels, are summarized in the following table.
-</p>
+ <p>After <code>JoranConfigurator</code> configures logback using
+ the <em>sample3.xml</em> file, the logger settings, more
+ specifically their levels, are summarized in the following table.
+ </p>
-<table>
+<table class="bodyTable">
<tr>
<th>Logger name</th>
<th>Assigned Level</th>
<th>Effective Level</th>
</tr>
- <tr>
- <td>root</td>
- <td><code>DEBUG</code></td>
- <td><code>DEBUG</code></td>
- </tr>
- <tr>
+ <tr>
+ <td>root</td>
+ <td><code>DEBUG</code></td>
+ <td><code>DEBUG</code></td>
+ </tr>
+ <tr class="alt">
<td>chapter3</td>
<td><code>INFO</code></td>
<td><code>INFO</code></td>
@@ -588,25 +578,27 @@
<td><code>null</code></td>
<td><code>INFO</code></td>
</tr>
- <tr>
+ <tr class="alt">
<td>chapter3.Foo</td>
<td><code>DEBUG</code></td>
<td><code>DEBUG</code></td>
</tr>
</table>
-<p>It follows that the two logging statements of level
-<code>INFO</code> in the <code>MyApp2</code> class are enabled while
-the <code>debug</code> statement in <code>Foo.doIt()</code> method
-will also print without hindrance. Note that the level of the root
-logger is always set to a non-null value, which is <code>DEBUG</code>
-by default. One rather important point to remember is that the
-logger-level filter depends on the effective level of the logger being
-invoked, not the level of the logger where the appenders are
-attached. The configuration file <em>sample4.xml</em> is a case in
-point:
-</p>
-<em>Example 3.<span class="autoEx"/>: Logger level sample (logback-examples/src/main/java/chapter3/sample4.xml)</em>
+ <p>It follows that the two logging statements of level
+ <code>INFO</code> in the <code>MyApp2</code> class as well as the
+ DEBUG messages in <code>Foo.doIt()</code> are all enabled. Note that
+ the level of the root logger is always set to a non-null value,
+ which is DEBUG by default. One rather important point to remember
+ is that the <a
+ href="architecture.html#basic_selection">basic-selection rule</a>
+ depends on the effective level of the logger being invoked, not the
+ level of the logger where appenders are attached. The configuration
+ file <em>sample4.xml</em> is a case in point:
+ </p>
+
+ <em>Example 3.<span class="autoEx"/>: Logger level sample
+ (logback-examples/src/main/java/chapter3/sample4.xml)</em>
<div class="source"><pre><configuration>
<appender name="STDOUT"
@@ -618,81 +610,78 @@
</layout>
</appender>
- <b><logger name="chapter3">
- <level value="INFO" />
- </logger></b>
+ <b><logger name="chapter3" level="INFO" /></b>
- <root>
- <b><level value="OFF" /></b>
+ <root <b>level="OFF"</b>>
<appender-ref ref="STDOUT" />
</root>
</configuration></pre></div>
-<p>
-The following table lists the loggers and their level setting after applying the
-<em>sample4.xml</em> configuration file.
-</p>
-
-<table>
- <tr>
- <th>Logger name</th>
- <th>Assigned Level</th>
- <th>Effective Level</th>
- </tr>
- <tr>
- <td>root</td>
- <td><code>OFF</code></td>
- <td><code>OFF</code></td>
- </tr>
- <tr>
- <td>chapter3</td>
- <td><code>INFO</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr>
- <td>chapter3.MyApp2</td>
- <td><code>null</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr>
- <td>chapter3.Foo</td>
- <td><code>null</code></td>
- <td><code>INFO</code></td>
- </tr>
-</table>
-
-<p>The ConsoleAppender named <em>STDOUT</em>, the only configured
-appender in <em>sample4.xml</em>, is attached to the root logger whose
-level is set to <code>OFF</code>. However, running MyApp2 with
-configuration script <em>sample4.xml</em> will output:
-</p>
-
-<div class="source"><pre>17:52:23.609 [main] INFO chapter3.MyApp2 - Entering application.
-17:52:23.609 [main] INFO chapter3.MyApp2 - Exiting application.</pre></div>
-
-<p>Thus, the level of the root logger has no apparent effect because
-the loggers in <code>chapter3.MyApp2</code> and
-<code>chapter3.Foo</code> classes, namely <em>chapter3.MyApp2</em> and
-<em>chapter3.Foo</em>, inherit their level from the <em>chapter3</em>
-logger which has its level set to <code>INFO</code>. As noted
-previously, the <em>chapter3</em> logger exists by virtue of its
-declaration in the configuration file - even if the Java source code
-does not directly refer to it.
-</p>
-
-<h4>Configuring Appenders</h4>
+ <p>The following table lists the loggers and their level setting
+ after applying the <em>sample4.xml</em> configuration file.
+ </p>
-<p>
-Appenders are configured using <em>appender</em> elements. These elements admit
-two attributes <em>name</em> and <em>class</em> both of which are mandatory.
-The <em>name</em> attribute specifies the name of the appender whereas
-the <em>class</em> attribute specifies the fully qualified name of the class
-of which the named appender will be an instance.
-The <em>appender</em> may contain zero or one <em>layout</em> elements and
-zero or more <em>filter</em> elements. Appart from these two basic elements,
-<em>appender</em> elements may contain any element that corresponds to a setter
-method of the appender class, to configure the appender's options.
+ <table class="bodyTable">
+ <tr>
+ <th>Logger name</th>
+ <th>Assigned Level</th>
+ <th>Effective Level</th>
+ </tr>
+ <tr>
+ <td>root</td>
+ <td><code>OFF</code></td>
+ <td><code>OFF</code></td>
+ </tr>
+ <tr class="alt">
+ <td>chapter3</td>
+ <td><code>INFO</code></td>
+ <td><code>INFO</code></td>
+ </tr>
+ <tr>
+ <td>chapter3.MyApp2</td>
+ <td><code>null</code></td>
+ <td><code>INFO</code></td>
+ </tr>
+ <tr class="alt">
+ <td>chapter3.Foo</td>
+ <td><code>null</code></td>
+ <td><code>INFO</code></td>
+ </tr>
+ </table>
+
+ <p>The ConsoleAppender named <em>STDOUT</em>, the only configured
+ appender in <em>sample4.xml</em>, is attached to the root logger
+ whose level is set to <code>OFF</code>. However, running MyApp2 with
+ configuration script <em>sample4.xml</em> will output:
+ </p>
+
+ <div class="source"><pre>17:52:23.609 [main] INFO chapter3.MyApp2 -
+Entering application. 17:52:23.609 [main] INFO chapter3.MyApp2 -
+Exiting application.</pre></div>
+
+ <p>Thus, the level of the root logger has no apparent effect because
+ the loggers in <code>chapter3.MyApp2</code> and
+ <code>chapter3.Foo</code> classes, namely <em>chapter3.MyApp2</em>
+ and <em>chapter3.Foo</em>, inherit their level from the
+ <em>chapter3</em> logger which has its level set to
+ <code>INFO</code>. As noted previously, the <em>chapter3</em>
+ logger exists by virtue of its declaration in the configuration file
+ - even if the Java source code does not directly refer to it.
+ </p>
+
+ <h4>Configuring Appenders</h4>
+
+ <p>Appenders are configured using <em>appender</em> elements. These
+ elements admit two attributes <em>name</em> and <em>class</em> both
+ of which are mandatory. The <em>name</em> attribute specifies the
+ name of the appender whereas the <em>class</em> attribute specifies
+ the fully qualified name of the class of which the named appender
+ will be an instance. The <em>appender</em> may contain zero or one
+ <em>layout</em> elements and zero or more <em>filter</em>
+ elements. Appart from these two basic elements, <em>appender</em>
+ elements may contain any element that corresponds to a setter method
+ of the appender class, to configure the appender's options.
</p>
<p>
1
0

svn commit: r1770 - logback/trunk/logback-examples/src/main/java/chapter3
by noreply.ceki@qos.ch 22 Aug '08
by noreply.ceki@qos.ch 22 Aug '08
22 Aug '08
Author: ceki
Date: Fri Aug 22 20:05:49 2008
New Revision: 1770
Modified:
logback/trunk/logback-examples/src/main/java/chapter3/multiple.xml
Log:
- changes in indentation, level attribute instead of level element
Modified: logback/trunk/logback-examples/src/main/java/chapter3/multiple.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/multiple.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/multiple.xml Fri Aug 22 20:05:49 2008
@@ -1,34 +1,23 @@
<configuration>
-
- <appender name="FILE"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>myApp.log</file>
- <rollingPolicy
- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern>
- myApp-%d{yyyy-MM-dd-HH-mm-ss}.log
- </FileNamePattern>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <FileNamePattern>myApp-%d{yyyy-MM-dd-HH-mm-ss}.log</FileNamePattern>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>
- %date %level [%thread] %logger{10} [%file : %line] %msg%n
- </Pattern>
+ <Pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</Pattern>
</layout>
</appender>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>
- %msg%n
- </Pattern>
+ <Pattern>%msg%n</Pattern>
</layout>
</appender>
- <root>
- <level value="debug" />
+ <root level="debug">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
1
0
Author: ceki
Date: Thu Aug 21 19:18:27 2008
New Revision: 1769
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LevelAction.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerAction.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/RootLoggerAction.java
logback/trunk/logback-classic/src/test/input/joran/simple2.xml
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionConst.java
logback/trunk/logback-examples/src/main/java/chapter3/MyApp3.java
logback/trunk/logback-examples/src/main/java/chapter3/sample0.xml
logback/trunk/logback-examples/src/main/java/chapter3/sample1.xml
logback/trunk/logback-examples/src/main/java/chapter3/sample2.xml
logback/trunk/logback-examples/src/main/java/chapter3/sample3.xml
logback/trunk/logback-examples/src/main/java/chapter3/sample4.xml
logback/trunk/logback-site/src/site/pages/ghighlighter/Styles/SyntaxHighlighter.css
logback/trunk/logback-site/src/site/pages/ghighlighter/js/shBrushJava.js
logback/trunk/logback-site/src/site/pages/ghighlighter/js/shCore.js
logback/trunk/logback-site/src/site/pages/manual/joran.html
logback/trunk/logback-site/src/site/pages/news.html
logback/trunk/logback-site/src/site/pages/templates/right.js
Log:
- simplified the syntax for setting the level of a logger in config files.
The previous syntax is still honored but it will no longer be documented.
- ongoing work on the docs
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LevelAction.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LevelAction.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LevelAction.java Thu Aug 21 19:18:27 2008
@@ -1,13 +1,12 @@
/**
- * LOGBack: the generic, reliable, fast and flexible logging framework.
+ * Logback: the generic, reliable, fast and flexible logging framework.
*
- * Copyright (C) 1999-2006, QOS.ch
+ * Copyright (C) 2000-2008, QOS.ch
*
* This library is free software, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
-
package ch.qos.logback.classic.joran.action;
import org.xml.sax.Attributes;
@@ -15,18 +14,19 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.action.ActionConst;
import ch.qos.logback.core.joran.spi.InterpretationContext;
-
+/**
+ * Action to handle the <level> element nested within <logger> element.
+ *
+ * <p>This action is <b>deprecated</b>. Use the level attribute within the logger
+ * element.
+ *
+ * @author Ceki Gulcu
+ */
public class LevelAction extends Action {
- static final String VALUE_ATTR = "value";
- static final String CLASS_ATTR = "class";
- static final String INHERITED = "INHERITED";
- static final String NULL = "NULL";
- static final String EMPTY_STR = "";
- static final Class[] ONE_STRING_PARAM = new Class[] {String.class};
-
boolean inError = false;
public void begin(InterpretationContext ec, String name, Attributes attributes) {
@@ -42,11 +42,11 @@
String loggerName = l.getName();
- String levelStr = attributes.getValue(VALUE_ATTR);
+ String levelStr = attributes.getValue(ActionConst.VALUE_ATTR);
//addInfo("Encapsulating logger name is [" + loggerName
// + "], level value is [" + levelStr + "].");
- if (INHERITED.equalsIgnoreCase(levelStr) || NULL.equalsIgnoreCase(levelStr)) {
+ if (ActionConst.INHERITED.equalsIgnoreCase(levelStr) || ActionConst.NULL.equalsIgnoreCase(levelStr)) {
l.setLevel(null);
} else {
l.setLevel(Level.toLevel(levelStr, Level.DEBUG));
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerAction.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerAction.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerAction.java Thu Aug 21 19:18:27 2008
@@ -1,7 +1,7 @@
/**
- * LOGBack: the generic, reliable, fast and flexible logging framework.
+ * Logback: the generic, reliable, fast and flexible logging framework.
*
- * Copyright (C) 1999-2006, QOS.ch
+ * Copyright (C) 2000-2008, QOS.ch
*
* This library is free software, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
@@ -10,9 +10,9 @@
package ch.qos.logback.classic.joran.action;
-
import org.xml.sax.Attributes;
+import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.joran.action.Action;
@@ -20,51 +20,69 @@
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.util.OptionHelper;
-
-
+/**
+ * Action which handles <logger> elements in configuration files.
+ *
+ * @author Ceki Gulcu
+ */
public class LoggerAction extends Action {
+ public static final String LEVEL_ATTRIBUTE = "level";
+
boolean inError = false;
-
+ Logger logger;
public void begin(InterpretationContext ec, String name, Attributes attributes) {
// Let us forget about previous errors (in this object)
inError = false;
-
+ logger = null;
+
LoggerContext loggerContext = (LoggerContext) this.context;
- // Create a new org.apache.log4j.Category object from the <category> element.
String loggerName = attributes.getValue(NAME_ATTRIBUTE);
if (OptionHelper.isEmpty(loggerName)) {
inError = true;
-
- String line =
- ", around line " + getLineNumber(ec) + " column "
- + getColumnNumber(ec);
-
+ String line = ", around line " + getLineNumber(ec) + " column "
+ + getColumnNumber(ec);
String errorMsg = "No 'name' attribute in element " + name + line;
addError(errorMsg);
-
return;
}
- //getLogger().debug("Logger name is [" + loggerName + "].");
-
- Logger l = loggerContext.getLogger(loggerName);
-
+ logger = loggerContext.getLogger(loggerName);
- boolean additive =
- OptionHelper.toBoolean(
- attributes.getValue(ActionConst.ADDITIVITY_ATTRIBUTE), true);
- //getLogger().debug(
- // "Setting [" + l.getName() + "] additivity to [" + additivity + "].");
- l.setAdditive(additive);
+ String levelStr = attributes.getValue(LEVEL_ATTRIBUTE);
+ if (!OptionHelper.isEmpty(levelStr)) {
+ if (ActionConst.INHERITED.equalsIgnoreCase(levelStr)
+ || ActionConst.NULL.equalsIgnoreCase(levelStr)) {
+ addInfo("Setting level of logger [" + loggerName
+ + "] to null, i.e. INHERITED");
+ logger.setLevel(null);
+ } else {
+ Level level = Level.toLevel(levelStr);
+ addInfo("Setting level of logger [" + loggerName + "] to " + level);
+ logger.setLevel(level);
+ }
+ }
- //getLogger().debug("Pushing logger named [" + loggerName + "].");
- ec.pushObject(l);
+ if (!OptionHelper.isEmpty(ActionConst.ADDITIVITY_ATTRIBUTE)) {
+ boolean additive = OptionHelper.toBoolean(attributes
+ .getValue(ActionConst.ADDITIVITY_ATTRIBUTE), true);
+ addInfo("Setting additivity of logger [" + loggerName + "] to "
+ + additive);
+ logger.setAdditive(additive);
+ }
+ ec.pushObject(logger);
}
public void end(InterpretationContext ec, String e) {
- if (!inError) {
+ if (inError) {
+ return;
+ }
+ Object o = ec.peekObject();
+ if (o != logger) {
+ addWarn("The object on the top the of the stack is not "+logger+" pushed earlier");
+ addWarn("It is: " + o);
+ } else {
ec.popObject();
}
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/RootLoggerAction.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/RootLoggerAction.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/RootLoggerAction.java Thu Aug 21 19:18:27 2008
@@ -9,50 +9,46 @@
*/
package ch.qos.logback.classic.joran.action;
-
import org.xml.sax.Attributes;
+import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.action.ActionConst;
import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.util.OptionHelper;
public class RootLoggerAction extends Action {
- static final String NAME_ATTR = "name";
- static final String CLASS_ATTR = "class";
- static final String ADDITIVITY_ATTR = "additivity";
- static final String EMPTY_STR = "";
- static final Class[] ONE_STRING_PARAM = new Class[] { String.class };
Logger root;
boolean inError = false;
-
+
public void begin(InterpretationContext ec, String name, Attributes attributes) {
inError = false;
- //logger.debug("In begin method");
LoggerContext loggerContext = (LoggerContext) this.context;
root = loggerContext.getLogger(LoggerContext.ROOT_NAME);
- //getLogger().debug("Pushing root logger on stack");
+ String levelStr = attributes.getValue(ActionConst.LEVEL_ATTRIBUTE);
+ if (!OptionHelper.isEmpty(levelStr)) {
+ Level level = Level.toLevel(levelStr);
+ addInfo("Setting level of ROOT logger to " + level);
+ root.setLevel(level);
+ }
+
ec.pushObject(root);
}
public void end(InterpretationContext ec, String name) {
- //logger.debug("end() called.");
-
if (inError) {
return;
}
-
Object o = ec.peekObject();
-
if (o != root) {
- addWarn(
- "The object on the top the of the stack is not the root logger");
- addWarn("It is: "+o);
+ addWarn("The object on the top the of the stack is not the root logger");
+ addWarn("It is: " + o);
} else {
- //getLogger().debug("Removing root logger from top of stack.");
ec.popObject();
}
}
Modified: logback/trunk/logback-classic/src/test/input/joran/simple2.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/simple2.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/simple2.xml Thu Aug 21 19:18:27 2008
@@ -9,8 +9,7 @@
</layout>
</appender>
- <root>
- <level value="DEBUG" />
+ <root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java Thu Aug 21 19:18:27 2008
@@ -25,9 +25,9 @@
*
* Most of the work for configuring log4j is done by Actions.
*
- * Methods of an Action are invoked while an XML file is parsed through.
+ * <p>Methods of an Action are invoked while an XML file is parsed through.
*
- * This class is largely copied from the relevant class in the commons-digester
+ * <p>This class is largely inspired from the relevant class in the commons-digester
* project of the Apache Software Foundation.
*
* @author Craig McClanahan
@@ -42,6 +42,7 @@
public static final String FILE_ATTRIBUTE = "file";
public static final String CLASS_ATTRIBUTE = "class";
public static final String PATTERN_ATTRIBUTE = "pattern";
+
public static final String ACTION_CLASS_ATTRIBUTE = "actionClass";
/**
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionConst.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionConst.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionConst.java Thu Aug 21 19:18:27 2008
@@ -21,13 +21,15 @@
public static final String APPENDER_TAG = "appender";
public static final String REF_ATTRIBUTE = "ref";
public static final String ADDITIVITY_ATTRIBUTE = "additivity";
+ public static final String LEVEL_ATTRIBUTE = "level";
public static final String CONVERTER_CLASS_ATTRIBUTE = "converterClass";
public static final String CONVERSION_WORD_ATTRIBUTE = "conversionWord";
public static final String PATTERN_ATTRIBUTE = "pattern";
+ public static final String VALUE_ATTR = "value";
public static final String ACTION_CLASS_ATTRIBUTE = "actionClass";
- static final String INHERITED = "INHERITED";
- static final String NULL = "NULL";
+ public static final String INHERITED = "INHERITED";
+ public static final String NULL = "NULL";
static final Class[] ONE_STRING_PARAM = new Class[] { String.class };
public static final String APPENDER_BAG = "APPENDER_BAG";
Modified: logback/trunk/logback-examples/src/main/java/chapter3/MyApp3.java
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/MyApp3.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/MyApp3.java Thu Aug 21 19:18:27 2008
@@ -32,11 +32,14 @@
try {
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
+ // the context was probably already configured by default configuration
+ // rules
lc.shutdownAndReset();
configurator.doConfigure(args[0]);
} catch (JoranException je) {
- StatusPrinter.print(lc);
+ je.printStackTrace();
}
+ StatusPrinter.printIfErrorsOccured(lc);
logger.info("Entering application.");
Modified: logback/trunk/logback-examples/src/main/java/chapter3/sample0.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/sample0.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/sample0.xml Thu Aug 21 19:18:27 2008
@@ -8,8 +8,7 @@
</layout>
</appender>
- <root>
- <level value="debug" />
+ <root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Modified: logback/trunk/logback-examples/src/main/java/chapter3/sample1.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/sample1.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/sample1.xml Thu Aug 21 19:18:27 2008
@@ -8,8 +8,7 @@
</layout>
</appender>
- <root>
- <level value="debug" />
+ <root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Modified: logback/trunk/logback-examples/src/main/java/chapter3/sample2.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/sample2.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/sample2.xml Thu Aug 21 19:18:27 2008
@@ -10,14 +10,11 @@
</layout>
</appender>
- <logger name="chapter3">
- <level value="INFO" />
- </logger>
+ <logger name="chapter3" level="INFO" />
- <root>
- <!-- The following level element is not necessary since the -->
- <!-- level of the root level is set to DEBUG by default. -->
- <level value="DEBUG" />
+ <!-- Strictly speaking, the level attribute is not necessary since -->
+ <!-- the level of the root level is set to DEBUG by default. -->
+ <root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
Modified: logback/trunk/logback-examples/src/main/java/chapter3/sample3.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/sample3.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/sample3.xml Thu Aug 21 19:18:27 2008
@@ -10,18 +10,11 @@
</layout>
</appender>
- <logger name="chapter3">
- <level value="INFO" />
- </logger>
+ <logger name="chapter3" level="INFO" />
- <logger name="chapter3.Foo">
- <level value="DEBUG" />
- </logger>
+ <logger name="chapter3.Foo" level="DEBUG" />
- <root>
- <!-- The following level element is not necessary since the -->
- <!-- level of the root level is set to DEBUG by default. -->
- <level value="DEBUG" />
+ <root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
Modified: logback/trunk/logback-examples/src/main/java/chapter3/sample4.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter3/sample4.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter3/sample4.xml Thu Aug 21 19:18:27 2008
@@ -10,12 +10,9 @@
</layout>
</appender>
- <logger name="chapter3">
- <level value="INFO" />
- </logger>
+ <logger name="chapter3" level="INFO" />
- <root>
- <level value="OFF" />
+ <root level="OFF">
<appender-ref ref="STDOUT" />
</root>
Modified: logback/trunk/logback-site/src/site/pages/ghighlighter/Styles/SyntaxHighlighter.css
==============================================================================
--- logback/trunk/logback-site/src/site/pages/ghighlighter/Styles/SyntaxHighlighter.css (original)
+++ logback/trunk/logback-site/src/site/pages/ghighlighter/Styles/SyntaxHighlighter.css Thu Aug 21 19:18:27 2008
@@ -182,4 +182,6 @@
.dp-highlighter .comment, .dp-highlighter .comments { color: #008200; background-color: inherit; }
.dp-highlighter .string { color: blue; background-color: inherit; }
.dp-highlighter .keyword { color: #069; font-weight: bold; background-color: inherit; }
+.dp-highlighter .more { font-weight: bolder; }
+.dp-highlighter .less { font-weight: lighter; }
.dp-highlighter .preprocessor { color: gray; background-color: inherit; }
Modified: logback/trunk/logback-site/src/site/pages/ghighlighter/js/shBrushJava.js
==============================================================================
--- logback/trunk/logback-site/src/site/pages/ghighlighter/js/shBrushJava.js (original)
+++ logback/trunk/logback-site/src/site/pages/ghighlighter/js/shBrushJava.js Thu Aug 21 19:18:27 2008
@@ -1,10 +1,30 @@
-/*
- * JsMin
- * Javascript Compressor
- * http://www.crockford.com/
- * http://www.smallsharptools.com/
-*/
+dp.sh.Brushes.Java = function()
+{
+ var keywords = 'abstract assert boolean break byte case catch char class const ' +
+ 'continue default do double else enum extends ' +
+ 'false final finally float for goto if implements import ' +
+ 'instanceof int interface long native new null ' +
+ 'package private protected public return ' +
+ 'short static strictfp super switch synchronized this throw throws true ' +
+ 'transient try void volatile while';
-dp.sh.Brushes.Java=function()
-{var keywords='abstract assert boolean break byte case catch char class const '+'continue default do double else enum extends '+'false final finally float for goto if implements import '+'instanceof int interface long native new null '+'package private protected public return '+'short static strictfp super switch synchronized this throw throws true '+'transient try void volatile while';this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:'comment'},{regex:dp.sh.RegexLib.MultiLineCComments,css:'comment'},{regex:dp.sh.RegexLib.DoubleQuotedString,css:'string'},{regex:dp.sh.RegexLib.SingleQuotedString,css:'string'},{regex:new RegExp('\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b','gi'),css:'number'},{regex:new RegExp('(?!\\@interface\\b)\\@[\\$\\w]+\\b','g'),css:'annotation'},{regex:new RegExp('\\@interface\\b','g'),css:'keyword'},{regex:new RegExp(this.GetKeywords(keywords),'gm'),css:'keyword'}];this.CssClass='dp-j';this.Style='.dp-j .annotation { color: #646464; }'+'.dp-j .n
umber { color: #C00000; }';}
-dp.sh.Brushes.Java.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Java.Aliases=['java'];
+ this.regexList = [
+ { regex: dp.sh.RegexLib.SingleLineCComments, css: 'comment' }, // one line comments
+ { regex: dp.sh.RegexLib.MultiLineCComments, css: 'comment' }, // multiline comments
+ { regex: dp.sh.RegexLib.DoubleQuotedString, css: 'string' }, // strings
+ { regex: dp.sh.RegexLib.SingleQuotedString, css: 'string' }, // strings
+ { regex: new RegExp('\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b', 'gi'), css: 'number' }, // numbers
+ { regex: new RegExp('(?!\\@interface\\b)\\@[\\$\\w]+\\b', 'g'), css: 'annotation' }, // annotation @anno
+ { regex: new RegExp('\\@interface\\b', 'g'), css: 'keyword' }, // @interface keyword
+ { regex: new RegExp('<b>.*</b>', 'g'), css: 'more' }, // @interface keyword
+
+ { regex: new RegExp(this.GetKeywords(keywords), 'gm'), css: 'keyword' } // java keyword
+ ];
+
+ this.CssClass = 'dp-j';
+ this.Style = '.dp-j .annotation { color: #646464; }' +
+ '.dp-j .number { color: #C00000; }';
+}
+
+dp.sh.Brushes.Java.prototype = new dp.sh.Highlighter();
+dp.sh.Brushes.Java.Aliases = ['java'];
Modified: logback/trunk/logback-site/src/site/pages/ghighlighter/js/shCore.js
==============================================================================
--- logback/trunk/logback-site/src/site/pages/ghighlighter/js/shCore.js (original)
+++ logback/trunk/logback-site/src/site/pages/ghighlighter/js/shCore.js Thu Aug 21 19:18:27 2008
@@ -1,161 +1,705 @@
-/*
- * JsMin
- * Javascript Compressor
- * http://www.crockford.com/
- * http://www.smallsharptools.com/
-*/
-
-var dp={sh:{Toolbar:{},Utils:{},RegexLib:{},Brushes:{},Strings:{AboutDialog:'<html><head><title>About...</title></head><body class="dp-about"><table cellspacing="0"><tr><td class="copy"><p class="title">dp.SyntaxHighlighter</div><div class="para">Version: {V}</p><p><a href="http://www.dreamprojections.com/syntaxhighlighter/?ref=about" target="_blank">http://www.dreamprojections.com/syntaxhighlighter</a></p>©2004-2007 Alex Gorbatchev.</td></tr><tr><td class="footer"><input type="button" class="close" value="OK" onClick="window.close()"/></td></tr></table></body></html>'},ClipboardSwf:null,Version:'1.5.1'}};dp.SyntaxHighlighter=dp.sh;dp.sh.Toolbar.Commands={ExpandSource:{label:'+ expand source',check:function(highlighter){return highlighter.collapse;},func:function(sender,highlighter)
-{sender.parentNode.removeChild(sender);highlighter.div.className=highlighter.div.className.replace('collapsed','');}},ViewSource:{label:'view plain',func:function(sender,highlighter)
-{var code=dp.sh.Utils.FixForBlogger(highlighter.originalCode).replace(/</g,'<');var wnd=window.open('','_blank','width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=0');wnd.document.write('<textarea style="width:99%;height:99%">'+code+'</textarea>');wnd.document.close();}},CopyToClipboard:{label:'copy to clipboard',check:function(){return window.clipboardData!=null||dp.sh.ClipboardSwf!=null;},func:function(sender,highlighter)
-{var code=dp.sh.Utils.FixForBlogger(highlighter.originalCode).replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');if(window.clipboardData)
-{window.clipboardData.setData('text',code);}
-else if(dp.sh.ClipboardSwf!=null)
-{var flashcopier=highlighter.flashCopier;if(flashcopier==null)
-{flashcopier=document.createElement('div');highlighter.flashCopier=flashcopier;highlighter.div.appendChild(flashcopier);}
-flashcopier.innerHTML='<embed src="'+dp.sh.ClipboardSwf+'" FlashVars="clipboard='+encodeURIComponent(code)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';}
-alert('The code is in your clipboard now');}},PrintSource:{label:'print',func:function(sender,highlighter)
-{var iframe=document.createElement('IFRAME');var doc=null;iframe.style.cssText='position:absolute;width:0px;height:0px;left:-500px;top:-500px;';document.body.appendChild(iframe);doc=iframe.contentWindow.document;dp.sh.Utils.CopyStyles(doc,window.document);doc.write('<div class="'+highlighter.div.className.replace('collapsed','')+' printing">'+highlighter.div.innerHTML+'</div>');doc.close();iframe.contentWindow.focus();iframe.contentWindow.print();alert('Printing...');document.body.removeChild(iframe);}},About:{label:'?',func:function(highlighter)
-{var wnd=window.open('','_blank','dialog,width=300,height=150,scrollbars=0');var doc=wnd.document;dp.sh.Utils.CopyStyles(doc,window.document);doc.write(dp.sh.Strings.AboutDialog.replace('{V}',dp.sh.Version));doc.close();wnd.focus();}}};dp.sh.Toolbar.Create=function(highlighter)
-{var div=document.createElement('DIV');div.className='tools';for(var name in dp.sh.Toolbar.Commands)
-{var cmd=dp.sh.Toolbar.Commands[name];if(cmd.check!=null&&!cmd.check(highlighter))
-continue;div.innerHTML+='<a href="#" onclick="dp.sh.Toolbar.Command(\''+name+'\',this);return false;">'+cmd.label+'</a>';}
-return div;}
-dp.sh.Toolbar.Command=function(name,sender)
-{var n=sender;while(n!=null&&n.className.indexOf('dp-highlighter')==-1)
-n=n.parentNode;if(n!=null)
-dp.sh.Toolbar.Commands[name].func(sender,n.highlighter);}
-dp.sh.Utils.CopyStyles=function(destDoc,sourceDoc)
-{var links=sourceDoc.getElementsByTagName('link');for(var i=0;i<links.length;i++)
-if(links[i].rel.toLowerCase()=='stylesheet')
-destDoc.write('<link type="text/css" rel="stylesheet" href="'+links[i].href+'"></link>');}
-dp.sh.Utils.FixForBlogger=function(str)
-{return(dp.sh.isBloggerMode==true)?str.replace(/<br\s*\/?>|<br\s*\/?>/gi,'\n'):str;}
-dp.sh.RegexLib={MultiLineCComments:new RegExp('/\\*[\\s\\S]*?\\*/','gm'),SingleLineCComments:new RegExp('//.*$','gm'),SingleLinePerlComments:new RegExp('#.*$','gm'),DoubleQuotedString:new RegExp('"(?:\\.|(\\\\\\")|[^\\""\\n])*"','g'),SingleQuotedString:new RegExp("'(?:\\.|(\\\\\\')|[^\\''\\n])*'",'g')};dp.sh.Match=function(value,index,css)
-{this.value=value;this.index=index;this.length=value.length;this.css=css;}
-dp.sh.Highlighter=function()
-{this.noGutter=false;this.addControls=true;this.collapse=false;this.tabsToSpaces=true;this.wrapColumn=80;this.showColumns=true;}
-dp.sh.Highlighter.SortCallback=function(m1,m2)
-{if(m1.index<m2.index)
-return-1;else if(m1.index>m2.index)
-return 1;else
-{if(m1.length<m2.length)
-return-1;else if(m1.length>m2.length)
-return 1;}
-return 0;}
-dp.sh.Highlighter.prototype.CreateElement=function(name)
-{var result=document.createElement(name);result.highlighter=this;return result;}
-dp.sh.Highlighter.prototype.GetMatches=function(regex,css)
-{var index=0;var match=null;while((match=regex.exec(this.code))!=null)
-this.matches[this.matches.length]=new dp.sh.Match(match[0],match.index,css);}
-dp.sh.Highlighter.prototype.AddBit=function(str,css)
-{if(str==null||str.length==0)
-return;var span=this.CreateElement('SPAN');str=str.replace(/ /g,' ');str=str.replace(/</g,'<');str=str.replace(/\n/gm,' <br>');if(css!=null)
-{if((/br/gi).test(str))
-{var lines=str.split(' <br>');for(var i=0;i<lines.length;i++)
-{span=this.CreateElement('SPAN');span.className=css;span.innerHTML=lines[i];this.div.appendChild(span);if(i+1<lines.length)
-this.div.appendChild(this.CreateElement('BR'));}}
-else
-{span.className=css;span.innerHTML=str;this.div.appendChild(span);}}
-else
-{span.innerHTML=str;this.div.appendChild(span);}}
-dp.sh.Highlighter.prototype.IsInside=function(match)
-{if(match==null||match.length==0)
-return false;for(var i=0;i<this.matches.length;i++)
-{var c=this.matches[i];if(c==null)
-continue;if((match.index>c.index)&&(match.index<c.index+c.length))
-return true;}
-return false;}
-dp.sh.Highlighter.prototype.ProcessRegexList=function()
-{for(var i=0;i<this.regexList.length;i++)
-this.GetMatches(this.regexList[i].regex,this.regexList[i].css);}
-dp.sh.Highlighter.prototype.ProcessSmartTabs=function(code)
-{var lines=code.split('\n');var result='';var tabSize=4;var tab='\t';function InsertSpaces(line,pos,count)
-{var left=line.substr(0,pos);var right=line.substr(pos+1,line.length);var spaces='';for(var i=0;i<count;i++)
-spaces+=' ';return left+spaces+right;}
-function ProcessLine(line,tabSize)
-{if(line.indexOf(tab)==-1)
-return line;var pos=0;while((pos=line.indexOf(tab))!=-1)
-{var spaces=tabSize-pos%tabSize;line=InsertSpaces(line,pos,spaces);}
-return line;}
-for(var i=0;i<lines.length;i++)
-result+=ProcessLine(lines[i],tabSize)+'\n';return result;}
-dp.sh.Highlighter.prototype.SwitchToList=function()
-{var html=this.div.innerHTML.replace(/<(br)\/?>/gi,'\n');var lines=html.split('\n');if(this.addControls==true)
-this.bar.appendChild(dp.sh.Toolbar.Create(this));if(this.showColumns)
-{var div=this.CreateElement('div');var columns=this.CreateElement('div');var showEvery=10;var i=1;while(i<=150)
-{if(i%showEvery==0)
-{div.innerHTML+=i;i+=(i+'').length;}
-else
-{div.innerHTML+='·';i++;}}
-columns.className='columns';columns.appendChild(div);this.bar.appendChild(columns);}
-for(var i=0,lineIndex=this.firstLine;i<lines.length-1;i++,lineIndex++)
-{var li=this.CreateElement('LI');var span=this.CreateElement('SPAN');li.className=(i%2==0)?'alt':'';span.innerHTML=lines[i]+' ';li.appendChild(span);this.ol.appendChild(li);}
-this.div.innerHTML='';}
-dp.sh.Highlighter.prototype.Highlight=function(code)
-{function Trim(str)
-{return str.replace(/^\s*(.*?)[\s\n]*$/g,'$1');}
-function Chop(str)
-{return str.replace(/\n*$/,'').replace(/^\n*/,'');}
-function Unindent(str)
-{var lines=dp.sh.Utils.FixForBlogger(str).split('\n');var indents=new Array();var regex=new RegExp('^\\s*','g');var min=1000;for(var i=0;i<lines.length&&min>0;i++)
-{if(Trim(lines[i]).length==0)
-continue;var matches=regex.exec(lines[i]);if(matches!=null&&matches.length>0)
-min=Math.min(matches[0].length,min);}
-if(min>0)
-for(var i=0;i<lines.length;i++)
-lines[i]=lines[i].substr(min);return lines.join('\n');}
-function Copy(string,pos1,pos2)
-{return string.substr(pos1,pos2-pos1);}
-var pos=0;if(code==null)
-code='';this.originalCode=code;this.code=Chop(Unindent(code));this.div=this.CreateElement('DIV');this.bar=this.CreateElement('DIV');this.ol=this.CreateElement('OL');this.matches=new Array();this.div.className='dp-highlighter';this.div.highlighter=this;this.bar.className='bar';this.ol.start=this.firstLine;if(this.CssClass!=null)
-this.ol.className=this.CssClass;if(this.collapse)
-this.div.className+=' collapsed';if(this.noGutter)
-this.div.className+=' nogutter';if(this.tabsToSpaces==true)
-this.code=this.ProcessSmartTabs(this.code);this.ProcessRegexList();if(this.matches.length==0)
-{this.AddBit(this.code,null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol);return;}
-this.matches=this.matches.sort(dp.sh.Highlighter.SortCallback);for(var i=0;i<this.matches.length;i++)
-if(this.IsInside(this.matches[i]))
-this.matches[i]=null;for(var i=0;i<this.matches.length;i++)
-{var match=this.matches[i];if(match==null||match.length==0)
-continue;this.AddBit(Copy(this.code,pos,match.index),null);this.AddBit(match.value,match.css);pos=match.index+match.length;}
-this.AddBit(this.code.substr(pos),null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol);}
-dp.sh.Highlighter.prototype.GetKeywords=function(str)
-{return'\\b'+str.replace(/ /g,'\\b|\\b')+'\\b';}
-dp.sh.BloggerMode=function()
-{dp.sh.isBloggerMode=true;}
-dp.sh.HighlightAll=function(name,showGutter,showControls,collapseAll,firstLine,showColumns)
-{function FindValue()
-{var a=arguments;for(var i=0;i<a.length;i++)
-{if(a[i]==null)
-continue;if(typeof(a[i])=='string'&&a[i]!='')
-return a[i]+'';if(typeof(a[i])=='object'&&a[i].value!='')
-return a[i].value+'';}
-return null;}
-function IsOptionSet(value,list)
-{for(var i=0;i<list.length;i++)
-if(list[i]==value)
-return true;return false;}
-function GetOptionValue(name,list,defaultValue)
-{var regex=new RegExp('^'+name+'\\[(\\w+)\\]$','gi');var matches=null;for(var i=0;i<list.length;i++)
-if((matches=regex.exec(list[i]))!=null)
-return matches[1];return defaultValue;}
-function FindTagsByName(list,name,tagName)
-{var tags=document.getElementsByTagName(tagName);for(var i=0;i<tags.length;i++)
-if(tags[i].getAttribute('name')==name)
-list.push(tags[i]);}
-var elements=[];var highlighter=null;var registered={};var propertyName='innerHTML';FindTagsByName(elements,name,'pre');FindTagsByName(elements,name,'textarea');if(elements.length==0)
-return;for(var brush in dp.sh.Brushes)
-{var aliases=dp.sh.Brushes[brush].Aliases;if(aliases==null)
-continue;for(var i=0;i<aliases.length;i++)
-registered[aliases[i]]=brush;}
-for(var i=0;i<elements.length;i++)
-{var element=elements[i];var options=FindValue(element.attributes['class'],element.className,element.attributes['language'],element.language);var language='';if(options==null)
-continue;options=options.split(':');language=options[0].toLowerCase();if(registered[language]==null)
-continue;highlighter=new dp.sh.Brushes[registered[language]]();element.style.display='none';highlighter.noGutter=(showGutter==null)?IsOptionSet('nogutter',options):!showGutter;highlighter.addControls=(showControls==null)?!IsOptionSet('nocontrols',options):showControls;highlighter.collapse=(collapseAll==null)?IsOptionSet('collapse',options):collapseAll;highlighter.showColumns=(showColumns==null)?IsOptionSet('showcolumns',options):showColumns;var headNode=document.getElementsByTagName('head')[0];if(highlighter.Style&&headNode)
-{var styleNode=document.createElement('style');styleNode.setAttribute('type','text/css');if(styleNode.styleSheet)
-{styleNode.styleSheet.cssText=highlighter.Style;}
-else
-{var textNode=document.createTextNode(highlighter.Style);styleNode.appendChild(textNode);}
-headNode.appendChild(styleNode);}
-highlighter.firstLine=(firstLine==null)?parseInt(GetOptionValue('firstline',options,1)):firstLine;highlighter.Highlight(element[propertyName]);highlighter.source=element;element.parentNode.insertBefore(highlighter.div,element);}}
+/**
+ * Code Syntax Highlighter.
+ * Version 1.5.1
+ * Copyright (C) 2004-2007 Alex Gorbatchev.
+ * http://www.dreamprojections.com/syntaxhighlighter/
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+//
+// create namespaces
+//
+var dp = {
+ sh :
+ {
+ Toolbar : {},
+ Utils : {},
+ RegexLib: {},
+ Brushes : {},
+ Strings : {
+ AboutDialog : '<html><head><title>About...</title></head><body class="dp-about"><table cellspacing="0"><tr><td class="copy"><p class="title">dp.SyntaxHighlighter</div><div class="para">Version: {V}</p><p><a href="http://www.dreamprojections.com/syntaxhighlighter/?ref=about" target="_blank">http://www.dreamprojections.com/syntaxhighlighter</a></p>©2004-2007 Alex Gorbatchev.</td></tr><tr><td class="footer"><input type="button" class="close" value="OK" onClick="window.close()"/></td></tr></table></body></html>'
+ },
+ ClipboardSwf : null,
+ Version : '1.5.1'
+ }
+};
+
+// make an alias
+dp.SyntaxHighlighter = dp.sh;
+
+//
+// Toolbar functions
+//
+
+dp.sh.Toolbar.Commands = {
+ ExpandSource: {
+ label: '+ expand source',
+ check: function(highlighter) { return highlighter.collapse; },
+ func: function(sender, highlighter)
+ {
+ sender.parentNode.removeChild(sender);
+ highlighter.div.className = highlighter.div.className.replace('collapsed', '');
+ }
+ },
+
+ // opens a new windows and puts the original unformatted source code inside.
+ ViewSource: {
+ label: 'view plain',
+ func: function(sender, highlighter)
+ {
+ var code = dp.sh.Utils.FixForBlogger(highlighter.originalCode).replace(/</g, '<');
+ var wnd = window.open('', '_blank', 'width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=0');
+ wnd.document.write('<textarea style="width:99%;height:99%">' + code + '</textarea>');
+ wnd.document.close();
+ }
+ },
+
+ // Copies the original source code in to the clipboard. Uses either IE only method or Flash object if ClipboardSwf is set
+ CopyToClipboard: {
+ label: 'copy to clipboard',
+ check: function() { return window.clipboardData != null || dp.sh.ClipboardSwf != null; },
+ func: function(sender, highlighter)
+ {
+ var code = dp.sh.Utils.FixForBlogger(highlighter.originalCode)
+ .replace(/</g,'<')
+ .replace(/>/g,'>')
+ .replace(/&/g,'&')
+ ;
+
+ if(window.clipboardData)
+ {
+ window.clipboardData.setData('text', code);
+ }
+ else if(dp.sh.ClipboardSwf != null)
+ {
+ var flashcopier = highlighter.flashCopier;
+
+ if(flashcopier == null)
+ {
+ flashcopier = document.createElement('div');
+ highlighter.flashCopier = flashcopier;
+ highlighter.div.appendChild(flashcopier);
+ }
+
+ flashcopier.innerHTML = '<embed src="' + dp.sh.ClipboardSwf + '" FlashVars="clipboard='+encodeURIComponent(code)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
+ }
+
+ alert('The code is in your clipboard now');
+ }
+ },
+
+ // creates an invisible iframe, puts the original source code inside and prints it
+ PrintSource: {
+ label: 'print',
+ func: function(sender, highlighter)
+ {
+ var iframe = document.createElement('IFRAME');
+ var doc = null;
+
+ // this hides the iframe
+ iframe.style.cssText = 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;';
+
+ document.body.appendChild(iframe);
+ doc = iframe.contentWindow.document;
+
+ dp.sh.Utils.CopyStyles(doc, window.document);
+ doc.write('<div class="' + highlighter.div.className.replace('collapsed', '') + ' printing">' + highlighter.div.innerHTML + '</div>');
+ doc.close();
+
+ iframe.contentWindow.focus();
+ iframe.contentWindow.print();
+
+ alert('Printing...');
+
+ document.body.removeChild(iframe);
+ }
+ },
+
+ About: {
+ label: '?',
+ func: function(highlighter)
+ {
+ var wnd = window.open('', '_blank', 'dialog,width=300,height=150,scrollbars=0');
+ var doc = wnd.document;
+
+ dp.sh.Utils.CopyStyles(doc, window.document);
+
+ doc.write(dp.sh.Strings.AboutDialog.replace('{V}', dp.sh.Version));
+ doc.close();
+ wnd.focus();
+ }
+ }
+};
+
+// creates a <div /> with all toolbar links
+dp.sh.Toolbar.Create = function(highlighter)
+{
+ var div = document.createElement('DIV');
+
+ div.className = 'tools';
+
+ for(var name in dp.sh.Toolbar.Commands)
+ {
+ var cmd = dp.sh.Toolbar.Commands[name];
+
+ if(cmd.check != null && !cmd.check(highlighter))
+ continue;
+
+ div.innerHTML += '<a href="#" onclick="dp.sh.Toolbar.Command(\'' + name + '\',this);return false;">' + cmd.label + '</a>';
+ }
+
+ return div;
+}
+
+// executes toolbar command by name
+dp.sh.Toolbar.Command = function(name, sender)
+{
+ var n = sender;
+
+ while(n != null && n.className.indexOf('dp-highlighter') == -1)
+ n = n.parentNode;
+
+ if(n != null)
+ dp.sh.Toolbar.Commands[name].func(sender, n.highlighter);
+}
+
+// copies all <link rel="stylesheet" /> from 'target' window to 'dest'
+dp.sh.Utils.CopyStyles = function(destDoc, sourceDoc)
+{
+ var links = sourceDoc.getElementsByTagName('link');
+
+ for(var i = 0; i < links.length; i++)
+ if(links[i].rel.toLowerCase() == 'stylesheet')
+ destDoc.write('<link type="text/css" rel="stylesheet" href="' + links[i].href + '"></link>');
+}
+
+dp.sh.Utils.FixForBlogger = function(str)
+{
+ return (dp.sh.isBloggerMode == true) ? str.replace(/<br\s*\/?>|<br\s*\/?>/gi, '\n') : str;
+}
+
+//
+// Common reusable regular expressions
+//
+dp.sh.RegexLib = {
+ MultiLineCComments : new RegExp('/\\*[\\s\\S]*?\\*/', 'gm'),
+ SingleLineCComments : new RegExp('//.*$', 'gm'),
+ SingleLinePerlComments : new RegExp('#.*$', 'gm'),
+ DoubleQuotedString : new RegExp('"(?:\\.|(\\\\\\")|[^\\""\\n])*"','g'),
+ SingleQuotedString : new RegExp("'(?:\\.|(\\\\\\')|[^\\''\\n])*'", 'g')
+};
+
+//
+// Match object
+//
+dp.sh.Match = function(value, index, css)
+{
+ this.value = value;
+ this.index = index;
+ this.length = value.length;
+ this.css = css;
+}
+
+//
+// Highlighter object
+//
+dp.sh.Highlighter = function()
+{
+ this.noGutter = false;
+ this.addControls = true;
+ this.collapse = false;
+ this.tabsToSpaces = true;
+ this.wrapColumn = 80;
+ this.showColumns = true;
+}
+
+// static callback for the match sorting
+dp.sh.Highlighter.SortCallback = function(m1, m2)
+{
+ // sort matches by index first
+ if(m1.index < m2.index)
+ return -1;
+ else if(m1.index > m2.index)
+ return 1;
+ else
+ {
+ // if index is the same, sort by length
+ if(m1.length < m2.length)
+ return -1;
+ else if(m1.length > m2.length)
+ return 1;
+ }
+ return 0;
+}
+
+dp.sh.Highlighter.prototype.CreateElement = function(name)
+{
+ var result = document.createElement(name);
+ result.highlighter = this;
+ return result;
+}
+
+// gets a list of all matches for a given regular expression
+dp.sh.Highlighter.prototype.GetMatches = function(regex, css)
+{
+ var index = 0;
+ var match = null;
+
+ while((match = regex.exec(this.code)) != null)
+ this.matches[this.matches.length] = new dp.sh.Match(match[0], match.index, css);
+}
+
+dp.sh.Highlighter.prototype.AddBit = function(str, css)
+{
+ if(str == null || str.length == 0)
+ return;
+
+ var span = this.CreateElement('SPAN');
+
+// str = str.replace(/&/g, '&');
+ str = str.replace(/ /g, ' ');
+ str = str.replace(/</g, '<');
+// str = str.replace(/</g, '<');
+// str = str.replace(/>/g, '>');
+ str = str.replace(/\n/gm, ' <br>');
+
+ // when adding a piece of code, check to see if it has line breaks in it
+ // and if it does, wrap individual line breaks with span tags
+ if(css != null)
+ {
+ if((/br/gi).test(str))
+ {
+ var lines = str.split(' <br>');
+
+ for(var i = 0; i < lines.length; i++)
+ {
+ span = this.CreateElement('SPAN');
+ span.className = css;
+ span.innerHTML = lines[i];
+
+ this.div.appendChild(span);
+
+ // don't add a <BR> for the last line
+ if(i + 1 < lines.length)
+ this.div.appendChild(this.CreateElement('BR'));
+ }
+ }
+ else
+ {
+ span.className = css;
+ span.innerHTML = str;
+ this.div.appendChild(span);
+ }
+ }
+ else
+ {
+ span.innerHTML = str;
+ this.div.appendChild(span);
+ }
+}
+
+// checks if one match is inside any other match
+dp.sh.Highlighter.prototype.IsInside = function(match)
+{
+ if(match == null || match.length == 0)
+ return false;
+
+ for(var i = 0; i < this.matches.length; i++)
+ {
+ var c = this.matches[i];
+
+ if(c == null)
+ continue;
+
+ if((match.index > c.index) && (match.index < c.index + c.length))
+ return true;
+ }
+
+ return false;
+}
+
+dp.sh.Highlighter.prototype.ProcessRegexList = function()
+{
+ for(var i = 0; i < this.regexList.length; i++)
+ this.GetMatches(this.regexList[i].regex, this.regexList[i].css);
+}
+
+dp.sh.Highlighter.prototype.ProcessSmartTabs = function(code)
+{
+ var lines = code.split('\n');
+ var result = '';
+ var tabSize = 4;
+ var tab = '\t';
+
+ // This function inserts specified amount of spaces in the string
+ // where a tab is while removing that given tab.
+ function InsertSpaces(line, pos, count)
+ {
+ var left = line.substr(0, pos);
+ var right = line.substr(pos + 1, line.length); // pos + 1 will get rid of the tab
+ var spaces = '';
+
+ for(var i = 0; i < count; i++)
+ spaces += ' ';
+
+ return left + spaces + right;
+ }
+
+ // This function process one line for 'smart tabs'
+ function ProcessLine(line, tabSize)
+ {
+ if(line.indexOf(tab) == -1)
+ return line;
+
+ var pos = 0;
+
+ while((pos = line.indexOf(tab)) != -1)
+ {
+ // This is pretty much all there is to the 'smart tabs' logic.
+ // Based on the position within the line and size of a tab,
+ // calculate the amount of spaces we need to insert.
+ var spaces = tabSize - pos % tabSize;
+
+ line = InsertSpaces(line, pos, spaces);
+ }
+
+ return line;
+ }
+
+ // Go through all the lines and do the 'smart tabs' magic.
+ for(var i = 0; i < lines.length; i++)
+ result += ProcessLine(lines[i], tabSize) + '\n';
+
+ return result;
+}
+
+dp.sh.Highlighter.prototype.SwitchToList = function()
+{
+ // thanks to Lachlan Donald from SitePoint.com for this <br/> tag fix.
+ var html = this.div.innerHTML.replace(/<(br)\/?>/gi, '\n');
+ var lines = html.split('\n');
+
+ if(this.addControls == true)
+ this.bar.appendChild(dp.sh.Toolbar.Create(this));
+
+ // add columns ruler
+ if(this.showColumns)
+ {
+ var div = this.CreateElement('div');
+ var columns = this.CreateElement('div');
+ var showEvery = 10;
+ var i = 1;
+
+ while(i <= 150)
+ {
+ if(i % showEvery == 0)
+ {
+ div.innerHTML += i;
+ i += (i + '').length;
+ }
+ else
+ {
+ div.innerHTML += '·';
+ i++;
+ }
+ }
+
+ columns.className = 'columns';
+ columns.appendChild(div);
+ this.bar.appendChild(columns);
+ }
+
+ for(var i = 0, lineIndex = this.firstLine; i < lines.length - 1; i++, lineIndex++)
+ {
+ var li = this.CreateElement('LI');
+ var span = this.CreateElement('SPAN');
+
+ // uses .line1 and .line2 css styles for alternating lines
+ li.className = (i % 2 == 0) ? 'alt' : '';
+ span.innerHTML = lines[i] + ' ';
+
+ li.appendChild(span);
+ this.ol.appendChild(li);
+ }
+
+ this.div.innerHTML = '';
+}
+
+dp.sh.Highlighter.prototype.Highlight = function(code)
+{
+ function Trim(str)
+ {
+ return str.replace(/^\s*(.*?)[\s\n]*$/g, '$1');
+ }
+
+ function Chop(str)
+ {
+ return str.replace(/\n*$/, '').replace(/^\n*/, '');
+ }
+
+ function Unindent(str)
+ {
+ var lines = dp.sh.Utils.FixForBlogger(str).split('\n');
+ var indents = new Array();
+ var regex = new RegExp('^\\s*', 'g');
+ var min = 1000;
+
+ // go through every line and check for common number of indents
+ for(var i = 0; i < lines.length && min > 0; i++)
+ {
+ if(Trim(lines[i]).length == 0)
+ continue;
+
+ var matches = regex.exec(lines[i]);
+
+ if(matches != null && matches.length > 0)
+ min = Math.min(matches[0].length, min);
+ }
+
+ // trim minimum common number of white space from the begining of every line
+ if(min > 0)
+ for(var i = 0; i < lines.length; i++)
+ lines[i] = lines[i].substr(min);
+
+ return lines.join('\n');
+ }
+
+ // This function returns a portions of the string from pos1 to pos2 inclusive
+ function Copy(string, pos1, pos2)
+ {
+ return string.substr(pos1, pos2 - pos1);
+ }
+
+ var pos = 0;
+
+ if(code == null)
+ code = '';
+
+ this.originalCode = code;
+ this.code = Chop(Unindent(code));
+ this.div = this.CreateElement('DIV');
+ this.bar = this.CreateElement('DIV');
+ this.ol = this.CreateElement('OL');
+ this.matches = new Array();
+
+ this.div.className = 'dp-highlighter';
+ this.div.highlighter = this;
+
+ this.bar.className = 'bar';
+
+ // set the first line
+ this.ol.start = this.firstLine;
+
+ if(this.CssClass != null)
+ this.ol.className = this.CssClass;
+
+ if(this.collapse)
+ this.div.className += ' collapsed';
+
+ if(this.noGutter)
+ this.div.className += ' nogutter';
+
+ // replace tabs with spaces
+ if(this.tabsToSpaces == true)
+ this.code = this.ProcessSmartTabs(this.code);
+
+ this.ProcessRegexList();
+
+ // if no matches found, add entire code as plain text
+ if(this.matches.length == 0)
+ {
+ this.AddBit(this.code, null);
+ this.SwitchToList();
+ this.div.appendChild(this.bar);
+ this.div.appendChild(this.ol);
+ return;
+ }
+
+ // sort the matches
+ this.matches = this.matches.sort(dp.sh.Highlighter.SortCallback);
+
+ // The following loop checks to see if any of the matches are inside
+ // of other matches. This process would get rid of highligted strings
+ // inside comments, keywords inside strings and so on.
+ for(var i = 0; i < this.matches.length; i++)
+ if(this.IsInside(this.matches[i]))
+ this.matches[i] = null;
+
+ // Finally, go through the final list of matches and pull the all
+ // together adding everything in between that isn't a match.
+ for(var i = 0; i < this.matches.length; i++)
+ {
+ var match = this.matches[i];
+
+ if(match == null || match.length == 0)
+ continue;
+
+ this.AddBit(Copy(this.code, pos, match.index), null);
+ this.AddBit(match.value, match.css);
+
+ pos = match.index + match.length;
+ }
+
+ this.AddBit(this.code.substr(pos), null);
+
+ this.SwitchToList();
+ this.div.appendChild(this.bar);
+ this.div.appendChild(this.ol);
+}
+
+dp.sh.Highlighter.prototype.GetKeywords = function(str)
+{
+ return '\\b' + str.replace(/ /g, '\\b|\\b') + '\\b';
+}
+
+dp.sh.BloggerMode = function()
+{
+ dp.sh.isBloggerMode = true;
+}
+
+// highlightes all elements identified by name and gets source code from specified property
+dp.sh.HighlightAll = function(name, showGutter /* optional */, showControls /* optional */, collapseAll /* optional */, firstLine /* optional */, showColumns /* optional */)
+{
+ function FindValue()
+ {
+ var a = arguments;
+
+ for(var i = 0; i < a.length; i++)
+ {
+ if(a[i] == null)
+ continue;
+
+ if(typeof(a[i]) == 'string' && a[i] != '')
+ return a[i] + '';
+
+ if(typeof(a[i]) == 'object' && a[i].value != '')
+ return a[i].value + '';
+ }
+
+ return null;
+ }
+
+ function IsOptionSet(value, list)
+ {
+ for(var i = 0; i < list.length; i++)
+ if(list[i] == value)
+ return true;
+
+ return false;
+ }
+
+ function GetOptionValue(name, list, defaultValue)
+ {
+ var regex = new RegExp('^' + name + '\\[(\\w+)\\]$', 'gi');
+ var matches = null;
+
+ for(var i = 0; i < list.length; i++)
+ if((matches = regex.exec(list[i])) != null)
+ return matches[1];
+
+ return defaultValue;
+ }
+
+ function FindTagsByName(list, name, tagName)
+ {
+ var tags = document.getElementsByTagName(tagName);
+
+ for(var i = 0; i < tags.length; i++)
+ if(tags[i].getAttribute('name') == name)
+ list.push(tags[i]);
+ }
+
+ var elements = [];
+ var highlighter = null;
+ var registered = {};
+ var propertyName = 'innerHTML';
+
+ // for some reason IE doesn't find <pre/> by name, however it does see them just fine by tag name...
+ FindTagsByName(elements, name, 'pre');
+ FindTagsByName(elements, name, 'textarea');
+
+ if(elements.length == 0)
+ return;
+
+ // register all brushes
+ for(var brush in dp.sh.Brushes)
+ {
+ var aliases = dp.sh.Brushes[brush].Aliases;
+
+ if(aliases == null)
+ continue;
+
+ for(var i = 0; i < aliases.length; i++)
+ registered[aliases[i]] = brush;
+ }
+
+ for(var i = 0; i < elements.length; i++)
+ {
+ var element = elements[i];
+ var options = FindValue(
+ element.attributes['class'], element.className,
+ element.attributes['language'], element.language
+ );
+ var language = '';
+
+ if(options == null)
+ continue;
+
+ options = options.split(':');
+
+ language = options[0].toLowerCase();
+
+ if(registered[language] == null)
+ continue;
+
+ // instantiate a brush
+ highlighter = new dp.sh.Brushes[registered[language]]();
+
+ // hide the original element
+ element.style.display = 'none';
+
+ highlighter.noGutter = (showGutter == null) ? IsOptionSet('nogutter', options) : !showGutter;
+ highlighter.addControls = (showControls == null) ? !IsOptionSet('nocontrols', options) : showControls;
+ highlighter.collapse = (collapseAll == null) ? IsOptionSet('collapse', options) : collapseAll;
+ highlighter.showColumns = (showColumns == null) ? IsOptionSet('showcolumns', options) : showColumns;
+
+ // write out custom brush style
+ var headNode = document.getElementsByTagName('head')[0];
+ if(highlighter.Style && headNode)
+ {
+ var styleNode = document.createElement('style');
+ styleNode.setAttribute('type', 'text/css');
+
+ if(styleNode.styleSheet) // for IE
+ {
+ styleNode.styleSheet.cssText = highlighter.Style;
+ }
+ else // for everyone else
+ {
+ var textNode = document.createTextNode(highlighter.Style);
+ styleNode.appendChild(textNode);
+ }
+
+ headNode.appendChild(styleNode);
+ }
+
+ // first line idea comes from Andrew Collington, thanks!
+ highlighter.firstLine = (firstLine == null) ? parseInt(GetOptionValue('firstline', options, 1)) : firstLine;
+
+ highlighter.Highlight(element[propertyName]);
+
+ highlighter.source = element;
+
+ element.parentNode.insertBefore(highlighter.div, element);
+ }
+}
Modified: logback/trunk/logback-site/src/site/pages/manual/joran.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/joran.html (original)
+++ logback/trunk/logback-site/src/site/pages/manual/joran.html Thu Aug 21 19:18:27 2008
@@ -11,15 +11,6 @@
<body>
<script type="text/javascript">prefix='../'</script>
<script type="text/javascript" src="../templates/header.js"></script>
- <script type="text/javascript" language="javascript" src="../ghighlighter/js/shCore.js"></script>
- <script type="text/javascript" language="javascript" src="../ghighlighter/js/shBrushJava.js"></script>
- <script type="text/javascript" language="javascript" src="../ghighlighter/js/shBrushXml.js"></script>
- <script type="text/javascript" language="javascript">
- window.onload = function () {
- dp.SyntaxHighlighter.HighlightAll('code');
- }
- </script>
-
<div id="left">
<script type="text/javascript" src="../templates/left.js"></script>
</div>
@@ -42,23 +33,6 @@
</script>
- <pre name="code" class="java">
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MyApp1 {
- final static Logger logger = LoggerFactory.getLogger(MyApp1.class);
-
- public static void main(String[] args) {
- logger.info("Entering application.");
-
- Foo foo = new Foo();
- foo.doIt();
- logger.info("Exiting application.");
- }
-}
- </pre>
-
<p>Joran stands for a cold north-west wind which, every now and
then, blows forcefully on Lake Geneva. Located right in the middle
of Europe, the Geneva lake happens to be the continent's largest
@@ -146,7 +120,7 @@
<code>BasicConfigurator</code> usage <a
href="../xref/chapter3/MyApp1.html">(logback-examples/src/main/java/chapter3/MyApp1.java)</a></em>
- <div class="source"><pre>package chapter3;
+<div class="source"><pre>package chapter3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -237,43 +211,45 @@
<p><em>Example 3.<span class="autoEx"/>: Basic configuration file
(logback-examples/src/main/java/chapter3/sample0.xml)</em></p>
- <div class="source"><pre><configuration>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
+<div class="source"><pre><configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
- <root>
- <level value="debug" />
+ <root level="debug">
<appender-ref ref="STDOUT" />
</root>
-</configuration></pre></div>
+</configuration></pre></div>
<p>After you have renamed <em>sample0.xml</em> as
<em>logback.xml</em> (or <em>logback-test.xml</em>) place it into a
directory accesible from the classpath. Running the <em>MyApp1</em>
application should give identical results to its previous run.</p>
- <p>If you are having problems with this example, you might want to
- inspect logback's internal status. This is done invoking the
- <code>print()</code> of the <code>StatusPrinter</code> class. The
- <em>MyApp2</em> application shown below is identical to
- <em>MyApp1</em> except the addition of two lines of code for
- printing internal status data.</p>
+ <p>If and only if there are errors during the parsing of the
+ configuration file, logback will automatically print status data on
+ the console. In the absence of errors, if you still wish to inspect
+ logback's internal status, then you can instruct logback to print
+ status data by invoking the <code>print()</code> of the
+ <code>StatusPrinter</code> class. The <em>MyApp2</em> application
+ shown below is identical to <em>MyApp1</em> except the addition of
+ two lines of code for printing internal status data.</p>
<em>Example 3.<span class="autoEx"/>: Print logback's internal status information
<a
href="../xref/chapter3/MyApp2.html">(logback-examples/src/main/java/chapter3/MyApp2.java)</a></em>
- <div class="source"><pre>
+
+<div class="source"><pre>
public static void main(String[] args) {
logger.info("Entering application.");
- <b>// print logback's internal status
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- StatusPrinter.print(lc);</b>
+ // print logback's internal status
+ <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
+ <b>StatusPrinter.print(lc);</b>
...
}</pre></div>
@@ -300,35 +276,39 @@
<p>Instead of invoking <code>StatusPrinter</code> programmatically
from your code, you can instruct the configuration file to dump
- status data. To achieve this, you need to set the <span
- class="attr">debug</span> attribute of the <em>configuration</em>
- element, i.e. the top-most element in the configuration file, as
- shown below. Please note that this <span class="attr">debug</span>
- attribute relates only to the status data. It does <em>not</em>
- affect logback's configuration otherwise, in particuler with
- respect to logger levels. (Put differently, no, the root logger
- will <em>not</em> be set to DEBUG.)
+ status data, even in the absence of errors. To achieve this, you
+ need to set the <span class="attr">debug</span> attribute of the
+ <em>configuration</em> element, i.e. the top-most element in the
+ configuration file, as shown below. Please note that this <span
+ class="attr">debug</span> attribute relates only to the status
+ data. It does <em>not</em> affect logback's configuration
+ otherwise, in particuler with respect to logger levels. (Put
+ differently, no, the root logger will <em>not</em> be set to
+ DEBUG.)
</p>
-<em>Example 3.<span class="autoEx"/>: Basic configuration file using debug mode (logback-examples/src/main/java/chapter3/sample1.xml)</em>
-<div class="source"><pre><configuration <b>debug="true"</b>>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
+ <em>Example 3.<span class="autoEx"/>: Basic configuration file
+ using debug mode
+ (logback-examples/src/main/java/chapter3/sample1.xml)</em>
+
+<div class="source"><pre>
+<configuration <b>debug="true"</b>>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
- <root>
- <level value="debug" />
+ <root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration></pre></div>
<p>Setting the <code>debug</code> attribute within the
<configuration> element will output status information, under
- the assumption that
+ the assumption that
</p>
<ol>
<li>the configuration file is found</li>
@@ -337,32 +317,31 @@
<p>If any of these two conditions is not fulfilled, the Joran
cannot interpret <code>debug</code> attribute since the
- configuration file cannot be read. it follows that no status
- information will be printed. If you would like to ensure that
- status information is printed, then, as in <em>MyApp2</em>
- application above, programmatically invoking
- <code>StatusPrinter.print()</code> is your safest bet.
- </p>
-
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
-
- <h3>Invoking <code>JoranConfigurator</code> programmatically</h3>
-
- <p>The previous example outputs logging information always in the
- same fixed manner. How boring! It takes few simple steps to modify
- <code>MyApp1</code> so that the log output can be controlled at
- runtime. Here is a slightly modified application called
- <code>MyApp2</code>.
+ configuration file cannot be read. If the configuration file is
+ found but is ill-formed, then logback will detect the error
+ condition and automatically print its internal status on the
+ console. However, if the configration file cannot be found, since
+ this is not necessarily an error condition, logback will not
+ automatically print its status data. Programmatically invoking
+ <code>StatusPrinter.print()</code>, as as in <em>MyApp2</em>
+ application above, ensures that status information is always
+ printed.
</p>
+ <h3>Invoking <code>JoranConfigurator</code> directly</h3>
- <p><em>Example 3.<span class="autoEx"/>: Simple example of
- <code>BasicConfigurator</code> usage <a
- href="../xref/chapter3/MyApp2.html">(logback-examples/src/main/java/chapter3/MyApp2.java)</a></em></p>
+ <p>Logback relies on a configuration library called Joran which is
+ part of logback-core. Logback's default configuration mechanism
+ invokes JoranConfigurator on the default configuration files it
+ finds on the claspath. For whatever reason if you wish to override
+ logback's default configuration meachanism, you can do so by
+ invoking JoranConfigurator directly. The next application,
+ <em>MyApp3</em>, invokes JoranConfirator on a configuration file
+ passed as parameter.</p>
+
+ <p><em>Example 3.<span class="autoEx"/>: Invoking
+ <code>JoranConfigurator</code> directly <a
+ href="../xref/chapter3/MyApp3.html">(logback-examples/src/main/java/chapter3/MyApp3.java)</a></em></p>
<div class="source"><pre>package chapter3;
@@ -384,11 +363,14 @@
<b>try {
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
- lc.shutdownAndReset();
+ // the context was probably already configured by default configuration
+ // rules
+ lc.shutdownAndReset();
configurator.doConfigure(args[0]);
} catch (JoranException je) {
- StatusPrinter.print(lc);
- }</b>
+ je.printStackTrace();
+ }
+ StatusPrinter.printIfErrorsOccured(lc);</b>
logger.info("Entering application.");
@@ -398,189 +380,128 @@
}
}</pre></div>
- <p><code>MyApp2</code> fetches the <code>LoggerContext</code>
- currently in effect, creates a new <code>JoranConfigurator</code>,
- gives it the context and finally asks that the configurator parses a
- configuration file. A basic configuration file that creates the same
- logging environment as would the default configuration is listed
- below:
+ <p>This application fetches the <code>LoggerContext</code> currently
+ in effect, creates a new <code>JoranConfigurator</code>, sets the
+ context on which it will operate, resets the logger context, and
+ then finally asks the configurator to configure the context using
+ configuration file passed as parameter to the application. Internal
+ status data is printed in case errors occur.
</p>
- <p><em>Example 3.<span class="autoEx"/>: Basic configuration file
- (logback-examples/src/main/java/chapter3/sample0.xml)</em></p>
-
- <div class="source"><pre><configuration>
-
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
- </layout>
- </appender>
- <root>
- <level value="debug" />
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre></div>
+
+ <h2>
+ <a name="syntax" href="#syntax">Configuration file Syntax</a>
+ </h2>
- <p>The above configuration file directs logback to create an
- <code>ConsoleAppender</code> named <em>STDOUT</em> whose output is
- format is managed by a <code>PatternLayout</code>. The root logger
- is configued by setting its level to DEBUG and attaching it the
- previously created <code>ConsoleAppender</code>.
+ <p>To obtain these different logging behaviors we do not need to
+ recompile code. You can easily configure logback so as to disable
+ logging for certain parts of your application, or direct output to a
+ UNIX Syslog daemon, to a database, to a log visualizer, or forward
+ logging events to a remote logback server, which would log according
+ to local server policy, for example by forwarding the log event to a
+ second logback server.
</p>
-
- <p>Note we could have omitted setting the level of the root logger
- to DEBUG because that is its default value.
+
+ <p>The remainder of this section presents the syntax of
+ configuration files.
</p>
+ <p>As shall become clear, the syntax of logback configuration files
+ is extremely flexible. As such, it is not possible specify the
+ allowed syntax with a DTD file or an XML Schema. Nevertheles, the
+ very basic structure of configration can be desribed as,
+ <configuration> element, followed by zero or more <appender>
+ elements, followed by by zero or more <logger> elements, followed
+ by at most one <root> element. The following diagram illustrates
+ this basic structure.</p>
- <p>Assuming the current directory is <em>logback-examples</em>, try
- running the <code>MyApp2</code> class by issuing the following
- command:
+
+ <p align="left">
+ <img src="images/chapter3/basicSyntax.png"
+ alt="basic Syntax" title="Basic configuration file structure"/>
</p>
- <div class="source"><pre>java chapter3.MyApp2 src/main/java/chapter3/sample0.xml</pre>
- </div>
+ <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
+ <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
+ <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
+ <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
- <p>
- The ouput of this command is very similar to the output of the
- previous example, except that <code>MyApp2</code> retrieves a
- logger called <em>chapter3.MyApp2</em> instead of
- <code>chapter3.MyApp1</code>. The output will reflect the
- difference.
- </p>
- <div class="source"><pre>16:09:00.593 [main] INFO chapter3.MyApp2 - Entering application.
-16:09:00.593 [main] DEBUG chapter3.Foo - Did it again!
-16:09:00.593 [main] INFO chapter3.MyApp2 - Exiting application.</pre></div>
+ <h4>Configuring Loggers, or the <code><logger></code> element</h4>
- <p>It is often very useful to define the logback debug
- configuration property in order to instruct logback to output
- internal configuration messages on the console. To achieve this,
- one only needs to add an attribute to the main
- <em>configuration</em> element in the configuration file, as shown
- above:
- </p>
-
-<em>Example 3.<span class="autoEx"/>: Basic configuration file using debug mode (logback-examples/src/main/java/chapter3/sample1.xml)</em>
-<div class="source"><pre><configuration <b>debug="true"</b>>
+ <p>A logger is configured using the <code>logger</code> element. A
+ <em>logger</em> element takes exactly one mandatory <span
+ class="attr">name</span> atttribute, an optional <span
+ class="attr">level</span> attribute, and an optional <span
+ class="attr">aditivity</span> attribute, which admits the values
+ <em>true</em> or <em>false</em>. The value of the <span
+ class="attr">level</span> attribute can be one of the
+ case-insensitive strings TRACE, DEBUG, INFO, WARN, ERROR, ALL or
+ OFF. The special case-insensitive value <em>INHERITED</em>, or its
+ synonym <em>NULL</em>, will force the level of the logger to be
+ inherited from higher up in the hierarchy. This comes in handy in
+ case you set the level of a logger and later decide that it should
+ inherit its level.
+ </p>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
- </layout>
- </appender>
+ <p>The <em>logger</em> element may contain zero or more
+ <em>appender-ref</em> elements; each appender thus referenced is
+ added to the named logger. It is important to keep mind that each
+ named logger that is declared with a <logger element first has
+ all its appenders removed and only then are the referenced appenders
+ attached to it. In particular, if there are no appender references,
+ then the named logger will lose all its appenders.
+ </p>
- <root>
- <level value="debug" />
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre></div>
- <p>This should cause logback to print internal configuration
- messages in addition to the actual logs. Relaunching the
- <code>MyApp2</code> application with this new configuration file
- will ouput the following lines:
- </p>
-
-<div class="source"><pre>|-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch. \
-qos.logback.core.ConsoleAppender]
-|-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
-|-INFO in ch.qos.logback.core.joran.action.AppenderAction - Popping appender named [STDOUT] from the \
-object stack
-|-INFO in ch.qos.logback.classic.joran.action.LevelAction - root level set to DEBUG
-|-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to \
-Logger[root]
-|-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
-16:18:23.687 [main] INFO chapter3.MyApp2 - Entering application.
-16:18:23.687 [main] DEBUG chapter3.Foo - Did it again!
-16:18:23.687 [main] INFO chapter3.MyApp2 - Exiting application.</pre></div>
+ <h4>Configuring the roor logger, or the <code><root></code>
+ element</h4>
- <h2>
- <a name="xml_syntax" href="#xml_syntax">XML Syntax</a>
- </h2>
- <p>To obtain these different logging behaviors we do not need to
- recompile code. You can easily configure logging so that output is
- directed to a UNIX Syslog daemon, or to a log visualizer, or forward
- logging events to a remote logback server, which would log according
- to local server policy, for example by forwarding the log event to a
- second logback server.</p>
-
- <p>The remainder of this chapter presents the syntax of the
- directives allowing all these variations.
- </p>
-<h4>Configuring Loggers</h4>
+ <p>The <root> element configures the root logger. It admits a
+ single attribute, namely the <span class="attr">level</span>
+ attribute. It does not admit any other attributes because the
+ additivity flag does not apply to the root logger. Moreover, since
+ the root logger is already named, it does not admit a name attribute
+ either. The value of the level attribute can be set to one of the
+ case-insensitive strings TRACE, DEBUG, INFO, WARN, ERROR, ALL or
+ OFF. Note that the level of the root logger cannot be inherited.
+ </p>
-<p>Loggers are configured using <em>logger</em> elements. A
-<em>logger</em> element takes exactly one mandatory name atttribute
-and an optional additivity attribute, which takes values <em>true</em>
-or <em>false</em>. The <em>logger</em> element admits at most one
-<em>level</em> element which is discussed next. It may also contain
-zero or more <em>appender-ref</em> elements; each appender thus
-referenced is added to the named logger. It is important to keep mind
-that each named logger that is declared with a <em>logger</em> element
-first has all its appenders removed and only then are the referenced
-appenders attached to it. In particular, if there are no appender
-references, then the named logger will lose all its appenders.
-</p>
-<p>The <em>level</em> element is used to set logger levels. It admits
-two attributes <em>value</em> and <em>class</em>. The value attribute
-can be one of the strings <em>DEBUG</em>, <em>INFO</em>, <em>WARN</em>
-<em>ERROR</em>, <em>ALL</em> or <em>OFF</em>. The special
-case-insensitive value <em>INHERITED</em>, or its synonym
-<em>NULL</em>, will force the level of the logger to be inherited from
-higher up in the hierarchy. Note that the level of the root logger
-cannot be inherited. If you set the level of a logger and later
-decide that it should inherit its level, then you need to specify
-<em>INHERITED</em> or its synonym <em>NULL</em> as the level
-value. The class attribute allows you to specify a custom level where
-the value of the attribute is the fully qualified name of a custom
-level class. You may alternatively use the <em>level#classname</em>
-syntax within the value attribute. The <em>level</em> element has no
-children.
-</p>
+ <p>The <root> element admits zero or more <appender-ref>
+ elements. Similar to the <logger element, declaring a <root
+ element will have the effect of first closing and then detaching all
+ its current appenders and only subsequently will referenced
+ appenders, if any, will be added. In particular, if it has no
+ appender references, then the root logger will lose all its
+ appenders.
+ </p>
-<p>The <em>root</em> element configures the root logger. It does not
-admit any attributes because the additivity flag does not apply to the
-root logger. Moreover, since the root logger cannot be named, it does
-not admit a name attribute either. The <em>root</em> element admits at
-most one <em>level</em> element and zero or more <em>appender-ref</em>
-elements. Similar to the <em>logger</em> element, declaring a
-<em>root</em> element will have the effect of first closing and then
-detaching all its current appenders and only subsequently will
-referenced appenders, if any, will be added. In particular, if it has
-no appender references, then the root logger will lose all its
-appenders.
-</p>
+ <h4>Example</h4>
- <p>Setting the level of a logger is as simple as declaring it and
- setting its level, as the next example illustrates. Suppose we are
- no longer interested in seeing any <code>DEBUG</code> level logs
- from any component belonging to the chapter3 package. The following
- configuration file shows how to achieve that.
+ <p>Setting the level of a logger or root logger is as simple as
+ declaring it and setting its level, as the next example
+ illustrates. Suppose we are no longer interested in seeing any DEBUG
+ level logs from any component belonging to the chapter3 package. The
+ following configuration file shows how to achieve that.
</p>
<em>Example 3.<span class="autoEx"/>: Setting the level of a logger (logback-examples/src/main/java/chapter3/sample2.xml)</em>
<div class="source"><pre><configuration>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
- <b><logger name="chapter3">
- <level value="INFO" />
- </logger></b>
+ <b class="red"><logger name="chapter3" level="INFO"/></b>
+
<root>
<!-- The following level element is not necessary since the -->
Modified: logback/trunk/logback-site/src/site/pages/news.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/news.html (original)
+++ logback/trunk/logback-site/src/site/pages/news.html Thu Aug 21 19:18:27 2008
@@ -31,6 +31,10 @@
<h3>XXth of XXX 2008 - Release of version 0.9.10</h3>
+ <p>Logback-classic now prints its internal status in case of
+ errors. This has been a frequently requested feature.
+ </p>
+
<p>The LogbackValve in logback-access (ensuring integration with
Tomcat), will now systematically print its internal status upon
initialization, unless told to be quiet. This greatly helps
Modified: logback/trunk/logback-site/src/site/pages/templates/right.js
==============================================================================
--- logback/trunk/logback-site/src/site/pages/templates/right.js (original)
+++ logback/trunk/logback-site/src/site/pages/templates/right.js Thu Aug 21 19:18:27 2008
@@ -6,6 +6,9 @@
document.write('<p class="menu"><a href="http://wimpi.coalevo.net/2008/04/logger-name-based-filtering-in-logback.html">Filtering by logger name</a>')
+document.write('<p class="menu"><a href="http://out-println.blogspot.com/2007/09/slf4j-and-logback.html">SLF4J and Logback</a>')
+
+
document.write('<p class="menu"><a href="http://wizardforge.org/pc?action=showVersion&id=72">Configuration Wizard</a>')
document.write('<p class="menu"><a href="http://xhab.blogspot.com/2007/03/new-logging-experience.html">A new logging experience!</a>')
1
0

svn commit: r1768 - logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi
by noreply.ceki@qos.ch 20 Aug '08
by noreply.ceki@qos.ch 20 Aug '08
20 Aug '08
Author: ceki
Date: Wed Aug 20 17:45:39 2008
New Revision: 1768
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
Log:
really skip over children when an error occurs. In the previous version of the code,
we would skip over invoking the action but would still try to find actions for the event.
In this revision, we skip over the event as a whole, in particular we no longer look up
actions for it. In practical terms, this just avoids adding error statuses for not found
implicit actions.
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java Wed Aug 20 17:45:39 2008
@@ -114,24 +114,33 @@
String qName, Attributes atts) {
String tagName = getTagName(localName, qName);
-
- // System.out.println("startElement [" + tagName + "]");
-
pattern.push(tagName);
- List applicableActionList = getApplicableActionList(pattern, atts);
+ if (skip != null) {
+ // every startElement pushes an action list
+ pushEmptyActionList();
+ return;
+ }
+ List applicableActionList = getApplicableActionList(pattern, atts);
if (applicableActionList != null) {
actionListStack.add(applicableActionList);
callBeginAction(applicableActionList, tagName, atts);
} else {
- actionListStack.add(EMPTY_LIST);
-
+ // every startElement pushes an action list
+ pushEmptyActionList();
String errMsg = "no applicable action for [" + tagName
+ "], current pattern is [" + pattern + "]";
cai.addError(errMsg);
}
}
+
+ /**
+ * This method is used to
+ */
+ private void pushEmptyActionList() {
+ actionListStack.add(EMPTY_LIST);
+ }
public void characters(BodyEvent be) {
@@ -155,14 +164,13 @@
}
private void endElement(String namespaceURI, String localName, String qName) {
+ // given that an action list is always pushed for every startElement, we need
+ // to always pop for every endElement
List applicableActionList = (List) actionListStack.pop();
- // System.out.println("endElement ["+getTagName(localName, qName)+"]");
-
+
if (skip != null) {
if (skip.equals(pattern)) {
skip = null;
- // FIXME
- // callEndAction(applicableActionList, getTagName(localName, qName));
}
} else if (applicableActionList != EMPTY_LIST) {
callEndAction(applicableActionList, getTagName(localName, qName));
@@ -237,17 +245,9 @@
return;
}
- if (skip != null) {
- // getLogger().debug("Skipping invoking begin() method for [{}].",
- // pattern);
- return;
- }
-
Iterator i = applicableActionList.iterator();
-
while (i.hasNext()) {
Action action = (Action) i.next();
-
// now let us invoke the action. We catch and report any eventual
// exceptions
try {
1
0

svn commit: r1767 - in logback/trunk: logback-classic/src/main/java/org/slf4j/impl logback-core/src/main/java/ch/qos/logback/core/util
by noreply.ceki@qos.ch 19 Aug '08
by noreply.ceki@qos.ch 19 Aug '08
19 Aug '08
Author: ceki
Date: Tue Aug 19 22:04:30 2008
New Revision: 1767
Modified:
logback/trunk/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
Log:
- in logback-classic, print internal status if errors were encountered
Modified: logback/trunk/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java (original)
+++ logback/trunk/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java Tue Aug 19 22:04:30 2008
@@ -64,8 +64,9 @@
// TODO test me
Util.reportFailure("Failed to auto configure default logger context",
je);
- StatusPrinter.print(defaultLoggerContext);
}
+ StatusPrinter.printIfErrorsOccured(defaultLoggerContext);
+
// See if a special context selector is needed
String contextSelectorStr = OptionHelper.getSystemProperty(
ClassicGlobal.LOGBACK_CONTEXT_SELECTOR, null);
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java Tue Aug 19 22:04:30 2008
@@ -18,6 +18,7 @@
import ch.qos.logback.core.Context;
import ch.qos.logback.core.CoreGlobal;
import ch.qos.logback.core.Layout;
+import ch.qos.logback.core.status.ErrorStatus;
import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusManager;
import ch.qos.logback.core.helpers.ThrowableToStringArray;
@@ -33,6 +34,33 @@
ps = printStream;
}
+ /**
+ * Print the contents of the context statuses, but only if they
+ * contain errors.
+ *
+ * @param context
+ */
+ public static void printIfErrorsOccured(Context context) {
+ 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 {
+ if (sm.getLevel() == ErrorStatus.ERROR) {
+ print(sm);
+ }
+ }
+ }
+
+ /**
+ * Print the contents of the context's status data.
+ *
+ * @param context
+ */
public static void print(Context context) {
if (context == null) {
throw new IllegalArgumentException("Context argument cannot be null");
1
0

[JIRA] Created: (LBGENERAL-18) Attachments are lost during migration from bugzilla to JIRA
by JIRA Administrator (JIRA) 19 Aug '08
by JIRA Administrator (JIRA) 19 Aug '08
19 Aug '08
Attachments are lost during migration from bugzilla to JIRA
-----------------------------------------------------------
Key: LBGENERAL-18
URL: http://jira.qos.ch/browse/LBGENERAL-18
Project: logback-general
Issue Type: Bug
Reporter: Roland Klein
Assignee: Ceki Gulcu
Attachments are lost during migration from bugzilla to JIRA
The Attachments are lost during migration from bugzilla to JIRA.
e.g. bugzilla #107 -> JIRA #32 Patch is gone
--
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
2

[JIRA] Created: (LBCLASSIC-63) deal with exceptions thrown by actions during configuration
by Ceki Gulcu (JIRA) 19 Aug '08
by Ceki Gulcu (JIRA) 19 Aug '08
19 Aug '08
deal with exceptions thrown by actions during configuration
-----------------------------------------------------------
Key: LBCLASSIC-63
URL: http://jira.qos.ch/browse/LBCLASSIC-63
Project: logback-classic
Issue Type: Sub-task
Components: joran
Affects Versions: unspecified
Reporter: Ceki Gulcu
Assignee: Logback dev list
Fix For: 0.9.10
See http://jira.qos.ch/browse/LBCLASSIC-58 and in particular
http://jira.qos.ch/browse/LBCLASSIC-58?focusedCommentId=10636#action_10636
--
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