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
May 2010
- 3 participants
- 63 discussions

[JIRA] Created: (LBCORE-152) When your application is stopped and restarted, logging will not continue at the correct location, i.e. at the largest index number for the current period.
by David Gonzalez (JIRA) 30 Jun '10
by David Gonzalez (JIRA) 30 Jun '10
30 Jun '10
When your application is stopped and restarted, logging will not continue at the correct location, i.e. at the largest index number for the current period.
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Key: LBCORE-152
URL: http://jira.qos.ch/browse/LBCORE-152
Project: logback-core
Issue Type: Sub-task
Components: Rolling
Affects Versions: 0.9.20
Reporter: David Gonzalez
Assignee: Logback dev list
As the online manual says (http://logback.qos.ch/manual/appenders.html) :
"When your application is stopped and restarted, logging will continue at the correct location, i.e. at the largest index number for the current period.".
This mean that the following steps occured :
- You have a log.trc current log file
- When rolling, as the <fileNamePattern> defined is <fileNamePattern>log_%i.log.zip</fileNamePattern>, archived log filed are created with the index %i starting at Zero.
- If current index is 3 when application is stopped, then restarting index is 4 and next archived log file to be created is log_4.log.zip
But this does not occure. Unfortunately the new archived log file with index equals to 4 is not created and you see a file with a weird name log_tmp<nanosseconds>.log created.
The reason has to be linked to LBCORE-131, current period index is not properly managed then when system is restarted this index is newly set to Zero and not 4.
As system tries to create log_0.log.zip file, system does test that this file exists and stops.
Temporary file tmp<nanos> which has to be saved as archived log file stays created (should have been deleted after archived log file creation successed).
As LBCORE-131 gives a fix, this fix should be improve in order to test also if current index period has to be increase because archived lof file in COMPRESS MODE already exists.
--
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: (LBCORE-131) SizeAndTimeBasedFNATP will overwrite previous logging files when File property is set at RollingFileAppender
by tomliliu (JIRA) 30 Jun '10
by tomliliu (JIRA) 30 Jun '10
30 Jun '10
SizeAndTimeBasedFNATP will overwrite previous logging files when File property is set at RollingFileAppender
------------------------------------------------------------------------------------------------------------
Key: LBCORE-131
URL: http://jira.qos.ch/browse/LBCORE-131
Project: logback-core
Issue Type: Bug
Components: Rolling
Affects Versions: 0.9.18
Reporter: tomliliu
Assignee: Logback dev list
Here's the failure case:
Configuration:
<appender name="appender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>c:/var/tmp/base.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
c:/var/tmp/%d{yyyy-MM-dd_HH}.%i.log
</FileNamePattern>
<TimeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<MaxFileSize>1KB</MaxFileSize>
</TimeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
Steps to reproduce:
1. Start the application
2. base.log was created.
3. yyyy-MM-dd_HH.0.log was created on rollover
4. rebounce the application
5. log to base.log
6. yyyy-MM-dd_HH.0.log was created on rollover, overwrite the previous yyyy-MM-dd_HH.0.log. Logging messages are lost.
It looks like the root cause is that SizeAndtimeBasedFNATP does not update the currentPeriodsCounter when parentsRawFileProperty is set.
if (tbrp.getParentsRawFileProperty() == null) {
String regex = tbrp.fileNamePattern.toRegex(dateInCurrentPeriod);
String stemRegex = FileFilterUtil.afterLastSlash(regex);
computeCurrentPeriodsHighestCounterValue(stemRegex);
}
SizeAndTimeBasedFNATP should update currentPeriodsCounter regardless whether parentsRawFileProperty is set or not.
Here's a fix works for me.
SizeAndTimeBasedFNATP.java
@Override
public void start() {
// we depend on certain fields having been initialized
// in super.start()
super.start();
archiveRemover = new SizeAndTimeBasedArchiveRemover(tbrp.fileNamePattern, rc);
archiveRemover.setContext(context);
// we need to get the correct value of currentPeriodsCounter.
// usually the value is 0, unless the appender or the application
// is stopped and restarted within the same period
//if (tbrp.getParentsRawFileProperty() == null) {
String regex = tbrp.fileNamePattern.toRegex(dateInCurrentPeriod);
String stemRegex = FileFilterUtil.afterLastSlash(regex);
computeCurrentPeriodsHighestCounterValue(stemRegex);
//}
started = true;
}
void computeCurrentPeriodsHighestCounterValue(final String stemRegex) {
File file = new File(getCurrentPeriodsFileNameWithoutCompressionSuffix());
File parentDir = file.getParentFile();
File[] matchingFileArray = FileFilterUtil
.filesInFolderMatchingStemRegex(parentDir, stemRegex);
if (matchingFileArray == null || matchingFileArray.length == 0) {
return;
}
FileFilterUtil.reverseSortFileArrayByName(matchingFileArray);
currentPeriodsCounter = FileFilterUtil.extractCounter(matchingFileArray[0], stemRegex);
//If parentsRawFileProperty is set, we should increment currentPeriodsCounter by one in order to avoid overwrite the last archive file.
if(tbrp.getParentsRawFileProperty() != null) {
currentPeriodsCounter ++;
}
}
Thanks,
Tom
--
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
1

[JIRA] Created: (LBCORE-156) 3 similar errors Share this error Delete this error Error Message java.lang.NoClassDefFoundError: ch/qos/logback/core/recovery/RecoveryCoordinator
by Benjamin Darfler (JIRA) 11 Jun '10
by Benjamin Darfler (JIRA) 11 Jun '10
11 Jun '10
3 similar errors Share this error Delete this error Error Message java.lang.NoClassDefFoundError: ch/qos/logback/core/recovery/RecoveryCoordinator
----------------------------------------------------------------------------------------------------------------------------------------------------
Key: LBCORE-156
URL: http://jira.qos.ch/browse/LBCORE-156
Project: logback-core
Issue Type: Bug
Environment: Logback-Classic 0.9.20 SLF4J 1.5.11
Reporter: Benjamin Darfler
Assignee: Logback dev list
Error Message
java.lang.NoClassDefFoundError: ch/qos/logback/core/recovery/RecoveryCoordinator
Stack Trace
ch.qos.logback.core.recovery.ResilientOutputStreamBase.postIOFailure(ResilientOutputStreamBase.java:105)
ch.qos.logback.core.recovery.ResilientOutputStreamBase.write(ResilientOutputStreamBase.java:55)
java.io.OutputStream.write(OutputStream.java:58)
ch.qos.logback.core.encoder.LayoutWrappingEncoder.doEncode(LayoutWrappingEncoder.java:103)
ch.qos.logback.core.OutputStreamAppender.writeOut(OutputStreamAppender.java:193)
ch.qos.logback.core.FileAppender.writeOut(FileAppender.java:220)
ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:216)
ch.qos.logback.core.rolling.RollingFileAppender.subAppend(RollingFileAppender.java:148)
ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:108)
ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:91)
ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:64)
ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:275)
ch.qos.logback.classic.Logger.callAppenders(Logger.java:262)
ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:465)
ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:419)
ch.qos.logback.classic.Logger.info(Logger.java:635)
com.locamoda.service.user.UserNameHandler.updateIfNecessary(UserNameHandler.java:121)
com.locamoda.service.user.UserNameHandler.onHttpRequest(UserNameHandler.java:76)
sun.reflect.GeneratedMethodAccessor1325.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:168)
com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:67)
com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:259)
com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:83)
com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:133)
com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:71)
com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:990)
com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:941)
com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:932)
com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:384)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:451)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:632)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:574)
org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:1987)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:619)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
3
2

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.21-4-ga3d37a0
by git-noreplyï¼ pixie.qos.ch 27 May '10
by git-noreplyï¼ pixie.qos.ch 27 May '10
27 May '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via a3d37a0a47c061d7c8fa5185f2c1948ff9cf053d (commit)
from 2e841425b8fc704719db6d1f1e18af2215ea1fb5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=a3d37a0a47c061d7c8fa5185…
http://github.com/ceki/logback/commit/a3d37a0a47c061d7c8fa5185f2c1948ff9cf0…
commit a3d37a0a47c061d7c8fa5185f2c1948ff9cf053d
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Thu May 27 14:16:10 2010 +0200
ongoing work on the docs
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java
index 72a7bad..04687e2 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java
@@ -1,86 +1,86 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-
-package ch.qos.logback.classic.boolex;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.boolex.EvaluationException;
-import ch.qos.logback.core.boolex.EventEvaluator;
-import ch.qos.logback.core.boolex.EventEvaluatorBase;
-import ch.qos.logback.core.util.FileUtil;
-import groovy.lang.*;
-import org.codehaus.groovy.control.CompilationFailedException;
-
-/**
- * @author Ceki Gülcü
- */
-public class GEventEvaluator extends EventEvaluatorBase<ILoggingEvent> {
-
- String expression;
-
- IEvaluator delegateEvaluator;
- Script script;
-
- public String getExpression() {
- return expression;
- }
-
- public void setExpression(String expression) {
- this.expression = expression;
- }
-
- public void start() {
- if (expression == null || expression.length() == 0) {
- addError("Empty expression");
- return;
- } else {
- addInfo("Expression to evaluate [" + expression + "]");
- }
-
-
- ClassLoader classLoader = getClass().getClassLoader();
- String currentPackageName = this.getClass().getPackage().getName();
- currentPackageName = currentPackageName.replace('.', '/');
-
- String scriptText = FileUtil.resourceAsString(this, classLoader, currentPackageName + "/EvaluatorTemplate.groovy");
- if(scriptText == null) {
- return;
- }
-
- // insert the expression into script text
- scriptText = scriptText.replace("//EXPRESSION", expression);
-
- GroovyClassLoader gLoader = new GroovyClassLoader(classLoader);
- try {
- Class scriptClass = gLoader.parseClass(scriptText);
-
- GroovyObject goo = (GroovyObject) scriptClass.newInstance();
- delegateEvaluator = (IEvaluator) goo;
-
- } catch (CompilationFailedException cfe) {
- addError("Failed to compile expression [" + expression + "]", cfe);
- } catch (Exception e) {
- addError("Failed to compile expression [" + expression + "]", e);
- }
- }
-
- public boolean evaluate(ILoggingEvent event) throws NullPointerException, EvaluationException {
- if(delegateEvaluator == null) {
- return false;
- }
- return delegateEvaluator.doEvaluate(event);
- }
-
-
-}
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+
+package ch.qos.logback.classic.boolex;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.boolex.EvaluationException;
+import ch.qos.logback.core.boolex.EventEvaluator;
+import ch.qos.logback.core.boolex.EventEvaluatorBase;
+import ch.qos.logback.core.util.FileUtil;
+import groovy.lang.*;
+import org.codehaus.groovy.control.CompilationFailedException;
+
+/**
+ * @author Ceki Gülcü
+ */
+public class GEventEvaluator extends EventEvaluatorBase<ILoggingEvent> {
+
+ String expression;
+
+ IEvaluator delegateEvaluator;
+ Script script;
+
+ public String getExpression() {
+ return expression;
+ }
+
+ public void setExpression(String expression) {
+ this.expression = expression;
+ }
+
+ public void start() {
+ if (expression == null || expression.length() == 0) {
+ addError("Empty expression");
+ return;
+ } else {
+ addInfo("Expression to evaluate [" + expression + "]");
+ }
+
+
+ ClassLoader classLoader = getClass().getClassLoader();
+ String currentPackageName = this.getClass().getPackage().getName();
+ currentPackageName = currentPackageName.replace('.', '/');
+
+ String scriptText = FileUtil.resourceAsString(this, classLoader, currentPackageName + "/EvaluatorTemplate.groovy");
+ if(scriptText == null) {
+ return;
+ }
+
+ // insert the expression into script text
+ scriptText = scriptText.replace("//EXPRESSION", expression);
+
+ GroovyClassLoader gLoader = new GroovyClassLoader(classLoader);
+ try {
+ Class scriptClass = gLoader.parseClass(scriptText);
+
+ GroovyObject goo = (GroovyObject) scriptClass.newInstance();
+ delegateEvaluator = (IEvaluator) goo;
+
+ } catch (CompilationFailedException cfe) {
+ addError("Failed to compile expression [" + expression + "]", cfe);
+ } catch (Exception e) {
+ addError("Failed to compile expression [" + expression + "]", e);
+ }
+ }
+
+ public boolean evaluate(ILoggingEvent event) throws NullPointerException, EvaluationException {
+ if(delegateEvaluator == null) {
+ return false;
+ }
+ return delegateEvaluator.doEvaluate(event);
+ }
+
+
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicy.java
index cab4c4b..1847422 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicy.java
@@ -1,84 +1,84 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.rolling;
-
-import ch.qos.logback.core.rolling.helper.ArchiveRemover;
-import ch.qos.logback.core.spi.ContextAware;
-
-/**
- * This interface lists the set of methods that need to be implemented by
- * triggering policies which are nested within a {@link TimeBasedRollingPolicy}.
- *
- * @author Ceki Gülcü
- *
- * @param <E>
- */
-public interface TimeBasedFileNamingAndTriggeringPolicy<E> extends
- TriggeringPolicy<E>, ContextAware {
-
- /**
- * Set the host/parent {@link TimeBasedRollingPolicy}.
- *
- * @param tbrp
- * parent TimeBasedRollingPolicy
- */
- void setTimeBasedRollingPolicy(TimeBasedRollingPolicy<E> tbrp);
-
- /**
- * Return the file name for the elapsed periods file name.
- *
- * @return
- */
- String getElapsedPeriodsFileName();
-
- /**
- * Return the current periods file name without the compression suffix. This
- * value is equivalent to the active file name.
- *
- * @return current period's file name (without compression suffix)
- */
- String getCurrentPeriodsFileNameWithoutCompressionSuffix();
-
- /**
- * Return the archive remover appropriate for this instance.
- */
- public ArchiveRemover getArchiveRemover();
-
- /**
- * Return the current time which is usually the value returned by
- * System.currentMillis(). However, for <b>testing</b> purposed this value
- * may be different than the real time.
- *
- * @return current time value
- */
- long getCurrentTime();
-
- /**
- * Set the current time. Only unit tests should invoke this method.
- *
- * @param now
- */
- void setCurrentTime(long now);
-
- /**
- * Set some date in the current period. Only unit tests should invoke this
- * method.
- *
- * WARNING: method removed. A unit test should not set the
- * date in current period. It is the job of the FNATP to compute that.
- *
- * @param date
- */
- //void setDateInCurrentPeriod(Date date);
-}
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.rolling;
+
+import ch.qos.logback.core.rolling.helper.ArchiveRemover;
+import ch.qos.logback.core.spi.ContextAware;
+
+/**
+ * This interface lists the set of methods that need to be implemented by
+ * triggering policies which are nested within a {@link TimeBasedRollingPolicy}.
+ *
+ * @author Ceki Gülcü
+ *
+ * @param <E>
+ */
+public interface TimeBasedFileNamingAndTriggeringPolicy<E> extends
+ TriggeringPolicy<E>, ContextAware {
+
+ /**
+ * Set the host/parent {@link TimeBasedRollingPolicy}.
+ *
+ * @param tbrp
+ * parent TimeBasedRollingPolicy
+ */
+ void setTimeBasedRollingPolicy(TimeBasedRollingPolicy<E> tbrp);
+
+ /**
+ * Return the file name for the elapsed periods file name.
+ *
+ * @return
+ */
+ String getElapsedPeriodsFileName();
+
+ /**
+ * Return the current periods file name without the compression suffix. This
+ * value is equivalent to the active file name.
+ *
+ * @return current period's file name (without compression suffix)
+ */
+ String getCurrentPeriodsFileNameWithoutCompressionSuffix();
+
+ /**
+ * Return the archive remover appropriate for this instance.
+ */
+ public ArchiveRemover getArchiveRemover();
+
+ /**
+ * Return the current time which is usually the value returned by
+ * System.currentMillis(). However, for <b>testing</b> purposed this value
+ * may be different than the real time.
+ *
+ * @return current time value
+ */
+ long getCurrentTime();
+
+ /**
+ * Set the current time. Only unit tests should invoke this method.
+ *
+ * @param now
+ */
+ void setCurrentTime(long now);
+
+ /**
+ * Set some date in the current period. Only unit tests should invoke this
+ * method.
+ *
+ * WARNING: method removed. A unit test should not set the
+ * date in current period. It is the job of the FNATP to compute that.
+ *
+ * @param date
+ */
+ //void setDateInCurrentPeriod(Date date);
+}
diff --git a/logback-site/src/site/pages/css/common.css b/logback-site/src/site/pages/css/common.css
index bc6a4fa..1d3489b 100644
--- a/logback-site/src/site/pages/css/common.css
+++ b/logback-site/src/site/pages/css/common.css
@@ -76,7 +76,7 @@ h2 {
}
h3 {
- font-weight: normal;
+ font-weight: bold;
font-size: large;
}
diff --git a/logback-site/src/site/pages/manual/groovy.html b/logback-site/src/site/pages/manual/groovy.html
index 78d89b8..440aa78 100644
--- a/logback-site/src/site/pages/manual/groovy.html
+++ b/logback-site/src/site/pages/manual/groovy.html
@@ -42,23 +42,68 @@
<p>Domains-specific languages are rather pervasive. The XML-based
- logback configuration can be be viewed as an example of a DSL. By
- the very nature of XML, XML-based configuration files are quite
- verbose and bulky. Moreover, a relatively large body of code in
- logback, namely Joran, is dedicated to processes these XML-based
+ logback configuration can be viewed as an example DSL. By the very
+ nature of XML, XML-based configuration files are quite verbose and
+ bulky. Moreover, a relatively large body of code in logback,
+ namely Joran, is dedicated to processes these XML-based
configuration files. Joran supports nifty features such as
- variable subsitution, conditional processing and on-the-fly
- extensibility. Not only Joran is a complex beast, the
+ variable substitution, conditional processing and on-the-fly
+ extensibility. However, not only Joran is a complex beast, the
user-experience it provides can be described as unsatisfactory or
at the very least unintuitive.
</p>
<p>The Groovy-based DSL described in this chapter aims to be
consistent, intuitive, and powerful. Everything you can do XML in
- configuration files, you can do in Groovy in a much shorter
- syntax. There is even a tool to automatically migrate XML
+ configuration files, you can do in Groovy with a much shorter
+ syntax. To help you migrate to Groovy style configuration, we have
+ developped a <a
+ href="http://logback.qos.ch/translator/asGroovy.html">tool to
+ automatically migrate your <em>logback.xml</em> files to
+ <em>logback.groovy</em></a>.
+ </p>
+
+
+ <h2>General philosophy</h2>
+
+ <p>As a general rule, <em>logback.groovy</em> files are groovy
+ programs. And since groovy is a super-set of Java, whatever
+ configuration actions you can perform in Java, you can do the same
+ within a <em>logback.groovy</em> file. However, since configuring
+ logback progammatically using Java syntax can be very cumbersome,
+ we added a few logback-specific extensions to make your life
+ easier. We limited the number of such logback-specific extensions
+ to an absolute minimum. If you are already familiar with groovy,
+ you should be able to read, understand and even write your own
+ logback.groovy files with great ease. Those unfamiliar with Groovy
+ should still find logback.groovy syntax much more comfortable to
+ use than logback.xml.
+ </p>
+
+ <p>Logback.groovy syntax consists of 6 methods described next in
+ their customary order of appearance. Strictly speaking the order
+ of invocation of the methods does matter except that appenders
+ MUST be defined before they can be attached to a logger.</p>
+
+ <h3><code>scan(String scanPeriodStr = null)</code> method</h3>
+
+ <p>Invoking the scan() method instructs logback to periodically
+ scan the logback.groovy file for changes. Whenever a change is
+ detected, the logback.groovy file is reloaded.</p>
+
+ <h3>statusListener(Class listenerClass)</h3>
+
+ <h3>conversionRule(String conversionWord, Class converterClass)</h3>
+
+
+ <h3> root(Level level, List<String> appenderNames = [])</String>
+
+ <h3>logger(String name, Level level, List<String> appenderNames = [], Boolean additivity = null)</String>
+
+ <h3>appender(String name, Class clazz, Closure closure = null)</h3>
+ <script src="../templates/footer.js" type="text/javascript"></script>
</div>
</body>
-----------------------------------------------------------------------
Summary of changes:
.../logback/classic/boolex/GEventEvaluator.java | 172 ++++++++++----------
.../TimeBasedFileNamingAndTriggeringPolicy.java | 168 ++++++++++----------
logback-site/src/site/pages/css/common.css | 2 +-
logback-site/src/site/pages/manual/groovy.html | 61 ++++++-
4 files changed, 224 insertions(+), 179 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.21-3-g2e84142
by git-noreplyï¼ pixie.qos.ch 25 May '10
by git-noreplyï¼ pixie.qos.ch 25 May '10
25 May '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 2e841425b8fc704719db6d1f1e18af2215ea1fb5 (commit)
from 060efd8495dedc95fc0f6abb688b8e0a1eaa1628 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=2e841425b8fc704719db6d1f…
http://github.com/ceki/logback/commit/2e841425b8fc704719db6d1f1e18af2215ea1…
commit 2e841425b8fc704719db6d1f1e18af2215ea1fb5
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Tue May 25 10:08:11 2010 +0200
testing and documenting gafter
diff --git a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
index 49b909a..95ae870 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
@@ -36,10 +36,6 @@ public class SiftingAppender extends SiftingAppenderBase<AccessEvent> {
super.start();
}
- AppenderTracker<AccessEvent> getAppenderTracker() {
- return appenderTracker;
- }
-
@Override
protected long getTimestamp(AccessEvent event) {
return event.getTimeStamp();
diff --git a/logback-classic/osgi-build.xml b/logback-classic/osgi-build.xml
index 615452d..045578f 100644
--- a/logback-classic/osgi-build.xml
+++ b/logback-classic/osgi-build.xml
@@ -69,7 +69,7 @@
<copy file="lib/slf4j-api-${slf4j.version}.jar" todir="${bundlesDir}"/>
<copy file="../logback-core/target/logback-core-${currentVersion}.jar" todir="${bundlesDir}"/>
<copy file="target/logback-classic-${currentVersion}.jar" todir="${bundlesDir}"/>
- <echo>value of t = @{t}</echo>
+ <echo>value of binding = @{binding}</echo>
</sequential>
</macrodef>
diff --git a/logback-classic/pom.xml b/logback-classic/pom.xml
index d1a8691..884a78a 100644
--- a/logback-classic/pom.xml
+++ b/logback-classic/pom.xml
@@ -326,7 +326,7 @@ org.slf4j.test_osgi
sun.reflect;resolution:=optional,
javax.*;resolution:=optional,
org.xml.*;resolution:=optional,
- ch.qos.logback.core.rolling,
+ org.slf4j, ch.qos.logback.core.rolling,
ch.qos.logback.core.rolling.helper,
org.codehaus.groovy.*;resolution:=optional,
groovy.lang.*;resolution:=optional,
diff --git a/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF b/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF
index fe56e16..efcb272 100644
--- a/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF
+++ b/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF
@@ -12,4 +12,4 @@ Bundle-SymbolicName: iBundle
Bundle-Name: abundle
Bundle-RequiredExecutionEnvironment: J2SE-1.3
Export-Package: apack
-Import-Package: org.osgi.framework, org.slf4j;version=1.5, ch.qos.logback.core, ch.qos.logback.core.joran.spi, ch.qos.logback.core.util, ch.qos.logback.classic, ch.qos.logback.classic.joran
+Import-Package: org.osgi.framework, org.slf4j;version=1.6, ch.qos.logback.core, ch.qos.logback.core.joran.spi, ch.qos.logback.core.util, ch.qos.logback.classic, ch.qos.logback.classic.joran
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
index 1db63a6..471c148 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
@@ -13,60 +13,92 @@
*/
package ch.qos.logback.classic.gaffer
-import ch.qos.logback.core.Appender
import ch.qos.logback.core.spi.ContextAwareBase
import ch.qos.logback.core.spi.LifeCycle
import ch.qos.logback.core.spi.ContextAware
+import java.beans.Introspector
/**
* @author Ceki Gücü
*/
-
-@Mixin(ContextAwareBase)
-class ComponentDelegate {
+class ComponentDelegate extends ContextAwareBase {
final Object component;
+ final List fieldsToCaccade = [];
+
ComponentDelegate(Object component) {
this.component = component;
}
+ Object getDeclaredOrigin() {
+ return "ComponentDelegate"
+ }
+
String getLabel() { "component" }
String getLabelFistLetterInUpperCase() { getLabel()[0].toUpperCase() + getLabel().substring(1) }
void methodMissing(String name, def args) {
-
- if (component.hasProperty(name)) {
- String subComponentName
- Class clazz
- Closure closure
- (subComponentName, clazz, closure) = analyzeArgs(args)
- if (clazz != null) {
- Object subComponent = clazz.newInstance()
- if (subComponentName && subComponent.hasProperty(name)) {
- subComponent.name = subComponentName;
- }
- if (subComponent instanceof ContextAware) {
- subComponent.context = context;
- }
- if (closure) {
- ComponentDelegate subDelegate = new ComponentDelegate(subComponent)
- subDelegate.context = context
- closure.delegate = subDelegate
- closure.resolveStrategy = Closure.DELEGATE_FIRST
- closure()
- }
- if (subComponent instanceof LifeCycle) {
- subComponent.start();
+ NestingType nestingType = PropertyUtil.nestingType(component, name);
+ if (nestingType == NestingType.NA) {
+ addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no appplicable [${name}] property ")
+ return;
+ }
+
+ String subComponentName
+ Class clazz
+ Closure closure
+ (subComponentName, clazz, closure) = analyzeArgs(args)
+ if (clazz != null) {
+ Object subComponent = clazz.newInstance()
+ if (subComponentName && subComponent.hasProperty(name)) {
+ subComponent.name = subComponentName;
+ }
+ if (subComponent instanceof ContextAware) {
+ subComponent.context = context;
+ }
+ if (closure) {
+ ComponentDelegate subDelegate = new ComponentDelegate(subComponent)
+
+ cascadeFields(subDelegate);
+ for (String k: fieldsToCaccade) {
+ //println "caccading ${k} with value ${this."${k}"}"
+ //subDelegate.metaClass."${k}" = this."${k}"
}
- component."${name}" = subComponent;
+
+
+ subDelegate.context = context
+ closure.delegate = subDelegate
+ closure.resolveStrategy = Closure.DELEGATE_FIRST
+ closure()
}
+ if (subComponent instanceof LifeCycle) {
+ subComponent.start();
+ }
+ PropertyUtil.attach(nestingType, component, subComponent, name)
} else {
- addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no [${name}] property ")
+ addError("No 'class' argument specified for [${name}] in ${getLabel()} ${getComponentName()} of type [${component.getClass().canonicalName}]");
+ }
+ }
+
+ void cascadeFields(ComponentDelegate subDelegate) {
+ for (String k: fieldsToCaccade) {
+ println "cacsading ${k} with value ${this."${k}"}"
+ subDelegate.metaClass."${k}" = this."${k}"
+ }
+ }
+
+ void propertyMissing(String name, def value) {
+ NestingType nestingType = PropertyUtil.nestingType(component, name);
+ if (nestingType == NestingType.NA) {
+ addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no appplicable [${name}] property ")
+ return;
}
+ PropertyUtil.attach(nestingType, component, value, name)
}
+
def analyzeArgs(Object[] args) {
String name;
Class clazz;
@@ -121,26 +153,4 @@ class ComponentDelegate {
return ""
}
-
- void propertyMissing(String name, def value) {
- name = camelCasify(name);
- if (component.hasProperty(name)) {
- //println "-- component has property $name"
- component."${name}" = value;
- } else {
- // println "-- component does not have property [$name]"
- addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no [${name}] property ")
- }
- }
-
- String camelCasify(String name) {
- if(name == null || name.length() == 0)
- return name;
-
- String firstLetter = new String(name.getAt(0)).toLowerCase();
- if(name.length() == 1)
- return firstLetter
- else
- return firstLetter + name.substring(1);
- }
}
\ No newline at end of file
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy
new file mode 100644
index 0000000..e46b367
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy
@@ -0,0 +1,31 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+/**
+ * @author Ceki Gücü
+ */
+public interface ConfigurationContributor {
+
+ /**
+ * The list of method mapping from the contributor into the configuration mechanism,
+ * e.g. the ConfiguratorDelegate
+ *
+ * <p>The key in the map is the method being contributed and the value is the name of
+ * the method in the target class.
+ * @return
+ */
+ public Map<String, String> getMappings()
+
+}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
index e45b223..5bda299 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
@@ -122,6 +122,7 @@ public class ConfigurationDelegate extends ContextAwareBase {
appenderList.add(appender)
if (closure != null) {
AppenderDelegate ad = new AppenderDelegate(appender);
+ copyContributions(ad, appender)
ad.context = context;
closure.delegate = ad;
closure.resolveStrategy = Closure.DELEGATE_FIRST
@@ -130,6 +131,16 @@ public class ConfigurationDelegate extends ContextAwareBase {
appender.start();
}
+ private void copyContributions(AppenderDelegate appenderDelegate, Appender appender) {
+ if(appender instanceof ConfigurationContributor) {
+ ConfigurationContributor cc = (ConfigurationContributor) appender;
+ cc.getMappings().each() { oldName, newName ->
+ appenderDelegate.metaClass."${newName}" = appender.&"$oldName"
+ }
+ }
+
+ }
+
void turboFilter(Class clazz, Closure closure = null) {
addInfo("About to instantiate turboFilter of type [" + clazz.name + "]");
TurboFilter turboFilter = clazz.newInstance();
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy
new file mode 100644
index 0000000..b5d685a
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy
@@ -0,0 +1,23 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+/**
+ * @author Ceki Gücü
+ */
+
+enum NestingType {
+ NA, SINGLE, AS_COLLECTION;
+}
+
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy
new file mode 100644
index 0000000..7bc1811
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy
@@ -0,0 +1,72 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+import java.lang.reflect.Method
+import java.beans.Introspector
+
+/**
+ * @author Ceki Gücü
+ */
+class PropertyUtil {
+
+ static boolean hasAdderMethod(Object obj, String name) {
+ String addMethod = "add${upperCaseFirstLetter(name)}";
+ return obj.metaClass.respondsTo(obj, addMethod);
+ }
+
+ static NestingType nestingType(Object obj, String name) {
+ def decapitalizedName = Introspector.decapitalize(name)
+ if (obj.hasProperty(decapitalizedName)) {
+ return NestingType.SINGLE;
+ }
+ if (hasAdderMethod(obj, name)) {
+ return NestingType.AS_COLLECTION;
+ }
+ return NestingType.NA;
+ }
+
+ static void attach(NestingType nestingType, Object component, Object subComponent, String name) {
+ switch (nestingType) {
+ case NestingType.SINGLE:
+ name = Introspector.decapitalize(name)
+ component."${name}" = subComponent;
+ break;
+ case NestingType.AS_COLLECTION:
+ String firstUpperName = PropertyUtil.upperCaseFirstLetter(name)
+ component."add${firstUpperName}"(subComponent);
+ break;
+ }
+ }
+
+ static String transformFirstLetter(String s, Closure closure) {
+ if (s == null || s.length() == 0)
+ return s;
+
+ String firstLetter = new String(s.getAt(0));
+
+ String modifiedFistLetter = closure(firstLetter);
+
+ if (s.length() == 1)
+ return modifiedFistLetter
+ else
+ return modifiedFistLetter + s.substring(1);
+
+ }
+
+ static String upperCaseFirstLetter(String s) {
+ return transformFirstLetter(s, {String it -> it.toUpperCase()})
+ }
+
+}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/GSiftingAppender.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/GSiftingAppender.groovy
new file mode 100644
index 0000000..f2493e7
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/GSiftingAppender.groovy
@@ -0,0 +1,153 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.sift
+
+import ch.qos.logback.core.AppenderBase
+import ch.qos.logback.classic.spi.ILoggingEvent
+import ch.qos.logback.core.sift.AppenderTrackerImpl
+import ch.qos.logback.core.sift.Discriminator
+import ch.qos.logback.core.sift.AppenderTracker
+import ch.qos.logback.core.Appender
+
+import ch.qos.logback.classic.gaffer.ConfigurationContributor
+import ch.qos.logback.core.CoreConstants
+import ch.qos.logback.core.helpers.NOPAppender
+
+/**
+ * @author Ceki Gücü
+ */
+class GSiftingAppender extends AppenderBase<ILoggingEvent> implements ConfigurationContributor {
+
+
+ protected AppenderTracker<ILoggingEvent> appenderTracker = new AppenderTrackerImpl<ILoggingEvent>();
+ Discriminator<ILoggingEvent> discriminator;
+ Closure builderClosure;
+
+ def Map<String, String> getMappings() {
+ return [sift: "sift"]
+ }
+
+ @Override
+ public void start() {
+ int errors = 0;
+ if (discriminator == null) {
+ addError("Missing discriminator. Aborting");
+ errors++;
+ }
+ if (!discriminator?.isStarted()) {
+ addError("Discriminator has not started successfully. Aborting");
+ errors++;
+ }
+
+ if (builderClosure == null) {
+ addError("Missing builder closure. Aborting");
+ errors++;
+ }
+ if (errors == 0) {
+ super.start();
+ }
+ }
+
+ @Override
+ public void stop() {
+ for (Appender<ILoggingEvent> appender: appenderTracker.valueList()) {
+ appender.stop();
+ }
+ }
+
+ @Override
+ protected long getTimestamp(ILoggingEvent event) {
+ return event.getTimeStamp();
+ }
+
+
+ Appender buildAppender(String value) {
+ String key = getDiscriminatorKey()
+
+ ZSiftingDelegate zd = new ZSiftingDelegate(getDiscriminatorKey(), value)
+ zd.context = context
+ zd.metaClass."$key" = value
+
+ //Closure newBuilder = builderClosure.clone()
+ builderClosure.delegate = zd;
+ builderClosure.resolveStrategy = Closure.DELEGATE_FIRST
+ Appender a = builderClosure()
+ return a
+ }
+
+ @Override
+ protected void append(ILoggingEvent event) {
+ if (!isStarted()) {
+ return;
+ }
+
+ String discriminatingValue = discriminator.getDiscriminatingValue(event);
+ long timestamp = getTimestamp(event);
+
+ Appender<ILoggingEvent> appender = appenderTracker.get(discriminatingValue, timestamp);
+ if (appender == null) {
+ try {
+ appender = buildAppender(discriminatingValue);
+ if (appender == null) {
+ appender = buildNOPAppender(discriminatingValue);
+ }
+ appenderTracker.put(discriminatingValue, appender, timestamp);
+
+ } catch (Throwable e) {
+ addError("Failed to build appender for [" + discriminatingValue + "]",
+ e);
+ return;
+ }
+ }
+ appenderTracker.stopStaleAppenders(timestamp);
+
+ appender.doAppend(event);
+ }
+
+ int nopaWarningCount = 0;
+
+ NOPAppender<ILoggingEvent> buildNOPAppender(String discriminatingValue) {
+ if (nopaWarningCount < CoreConstants.MAX_ERROR_COUNT) {
+ nopaWarningCount++;
+ addError("Failed to build an appender for discriminating value [" + discriminatingValue + "]");
+ }
+ NOPAppender<ILoggingEvent> nopa = new NOPAppender<ILoggingEvent>();
+ nopa.setContext(context);
+ nopa.start();
+ return nopa;
+ }
+
+ void build() {
+ int r = builderClosure();
+ println "r=$r"
+
+ }
+
+ void sift(Closure clo) {
+ builderClosure = clo;
+ }
+
+
+ public AppenderTracker getAppenderTracker() {
+ return appenderTracker;
+ }
+
+ public String getDiscriminatorKey() {
+ if (discriminator != null) {
+ return discriminator.getKey();
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/ZSiftingDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/ZSiftingDelegate.groovy
new file mode 100644
index 0000000..8218e58
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/ZSiftingDelegate.groovy
@@ -0,0 +1,39 @@
+package ch.qos.logback.classic.sift
+
+import ch.qos.logback.core.spi.ContextAwareBase
+import ch.qos.logback.core.Appender
+import ch.qos.logback.classic.gaffer.AppenderDelegate
+import ch.qos.logback.core.util.StatusPrinter
+
+/**
+ * @author Ceki Gücü
+ */
+class ZSiftingDelegate extends ContextAwareBase {
+
+ String key
+ String value
+
+ ZSiftingDelegate(String key, String value) {
+ this.key = key
+ this.value = value
+ }
+
+ Appender appender(String name, Class clazz, Closure closure = null) {
+ addInfo("About to instantiate appender of type [" + clazz.name + "]");
+ Appender appender = clazz.newInstance();
+ addInfo("Naming appender as [" + name + "]");
+ appender.name = name
+ appender.context = context
+ if (closure != null) {
+ AppenderDelegate ad = new AppenderDelegate(appender);
+ ad.metaClass."${key}" = value
+ ad.fieldsToCaccade << "${key}"
+ ad.context = context;
+ closure.delegate = ad;
+ closure.resolveStrategy = Closure.DELEGATE_FIRST
+ closure();
+ }
+ appender.start();
+ return appender;
+ }
+}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
index 5245146..1e57794 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
@@ -31,10 +31,6 @@ import ch.qos.logback.core.sift.SiftingAppenderBase;
*/
public class SiftingAppender extends SiftingAppenderBase<ILoggingEvent> {
- AppenderTracker<ILoggingEvent> getAppenderTracker() {
- return appenderTracker;
- }
-
@Override
protected long getTimestamp(ILoggingEvent event) {
return event.getTimeStamp();
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
index 66d6b4d..7cc9a35 100644
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
@@ -15,6 +15,8 @@ import ch.qos.logback.core.helpers.NOPAppender
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.encoder.LayoutWrappingEncoder
import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.core.util.StatusPrinter
+import ch.qos.logback.classic.net.SMTPAppender
/**
* @author Ceki Gücü
@@ -162,4 +164,25 @@ class ConfigurationDelegateTest {
assertEquals("%m%n", layout.pattern)
}
+
+ @Test
+ void appenderSMTP() {
+ configurationDelegate.appender("SMTP", SMTPAppender) {
+ to = "a"
+ to = "b"
+ layout (PatternLayout) {
+ pattern = "%m%n"
+ }
+ }
+ StatusPrinter.print context
+ Appender back = configurationDelegate.appenderList.find {it.name = "SMTP"}
+ assertNotNull(back)
+ assertEquals("SMTP", back.name)
+ SMTPAppender sa = back
+ PatternLayout layout = sa.layout
+ assertEquals("%m%n", layout.pattern)
+
+ assertEquals(["a", "b"], sa.toList.sort());
+
+ }
}
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
index 53ee836..f35daf0 100644
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
@@ -29,6 +29,11 @@ import ch.qos.logback.core.testUtil.StringListAppender
import ch.qos.logback.classic.testUtil.SampleConverter
import ch.qos.logback.core.util.StatusPrinter
+import ch.qos.logback.classic.boolex.JaninoEventEvaluator
+import ch.qos.logback.core.filter.EvaluatorFilter
+import ch.qos.logback.core.boolex.Matcher
+import static org.junit.Assert.assertTrue
+
/**
* @author Ceki Gücü
*/
@@ -100,4 +105,55 @@ class ConfiguratorTest {
assertEquals(SampleConverter.SAMPLE_STR + " - " + msg, sla.strList.get(0));
}
+ @Test
+ void evaluatorWithMatcher() {
+ File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "evaluatorWithMatcher.groovy")
+ String dslText = file.text
+ configurator.run dslText
+
+ ConsoleAppender ca = (ConsoleAppender) root.getAppender("STDOUT");
+ assertTrue ca.isStarted()
+
+ EvaluatorFilter ef = ca.getCopyOfAttachedFiltersList()[0];
+ assertTrue ef.isStarted()
+
+ JaninoEventEvaluator jee = ef.evaluator
+ assertTrue jee.isStarted()
+ Matcher m = jee.matcherList[0]
+ assertTrue m.isStarted()
+ }
+
+ @Test
+ void propertyCascading0() {
+ File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "propertyCascading0.groovy")
+ String dslText = file.text
+ configurator.run dslText
+
+ ConsoleAppender ca = (ConsoleAppender) root.getAppender("STDOUT");
+ assertTrue ca.isStarted()
+
+ assertEquals("HELLO %m%n", ca.encoder.layout.pattern)
+ }
+ @Test
+ void propertyCascading1() {
+ File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "propertyCascading1.groovy")
+ String dslText = file.text
+ configurator.run dslText
+
+ ConsoleAppender ca = (ConsoleAppender) root.getAppender("STDOUT");
+ assertTrue ca.isStarted()
+ assertEquals("HELLO %m%n", ca.encoder.getLayout().pattern)
+ }
+
+ @Test
+ void propertyCascading2() {
+ context.putProperty("p", "HELLO");
+ File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "propertyCascading2.groovy")
+ String dslText = file.text
+ configurator.run dslText
+
+ ConsoleAppender ca = (ConsoleAppender) root.getAppender("STDOUT");
+ assertTrue ca.isStarted()
+ assertEquals("HELLO %m%n", ca.encoder.getLayout().pattern)
+ }
}
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy
new file mode 100644
index 0000000..d2f5e7d
--- /dev/null
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy
@@ -0,0 +1,26 @@
+package ch.qos.logback.classic.gaffer
+
+import org.junit.Test
+import static junit.framework.Assert.assertEquals
+
+/**
+ * @author Ceki Gücü
+ */
+class PropertyUtilTest {
+
+
+ @Test
+ void empty() {
+ assertEquals("", PropertyUtil.upperCaseFirstLetter(""));
+ assertEquals(null, PropertyUtil.upperCaseFirstLetter(null));
+ }
+
+
+
+ @Test
+ void smoke() {
+ assertEquals("Hello", PropertyUtil.upperCaseFirstLetter("hello"));
+ }
+
+
+}
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/sift/GSiftingAppenderTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/sift/GSiftingAppenderTest.groovy
new file mode 100644
index 0000000..f0441d0
--- /dev/null
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/sift/GSiftingAppenderTest.groovy
@@ -0,0 +1,110 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.sift
+
+import ch.qos.logback.classic.gaffer.Configurator
+
+import ch.qos.logback.classic.Logger
+import ch.qos.logback.classic.LoggerContext
+import ch.qos.logback.core.testUtil.RandomUtil
+import org.junit.Test
+import ch.qos.logback.classic.ClassicTestConstants
+import org.slf4j.MDC
+import static junit.framework.Assert.assertNotNull
+import ch.qos.logback.core.sift.AppenderTracker
+import ch.qos.logback.core.read.ListAppender
+import ch.qos.logback.core.util.StatusPrinter
+import static junit.framework.Assert.assertEquals
+import ch.qos.logback.core.FileAppender
+import ch.qos.logback.core.status.StatusChecker
+import ch.qos.logback.core.status.Status
+import static junit.framework.Assert.assertNull
+import org.junit.After
+
+/**
+ * @author Ceki Gücü
+ */
+class GSiftingAppenderTest {
+
+ LoggerContext context = new LoggerContext();
+ Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME)
+ Logger logger = context.getLogger(this.getClass())
+ int diff = RandomUtil.getPositiveInt();
+ Configurator configurator = new Configurator(context);
+ StatusChecker checker = new StatusChecker(context)
+
+ @After
+ public void tearDown() {
+ MDC.clear();
+ }
+
+ AppenderTracker execute(String path) {
+ File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + path)
+ String dslText = file.text
+ configurator.run dslText
+
+ GSiftingAppender sa = (GSiftingAppender) root.getAppender("SIFT");
+ assertNotNull(sa)
+ AppenderTracker tracker = sa.getAppenderTracker();
+ }
+
+ @Test
+ void noDiscriminator() {
+ AppenderTracker tracker = execute("sift/noDiscriminator.groovy")
+ logger.debug("x")
+ ListAppender unknownAppender = tracker.get("unknown", System.currentTimeMillis())
+ assertNull(unknownAppender)
+ checker.containsMatch(Status.ERROR, "Missing discriminator. Aborting")
+ }
+
+ @Test
+ void sample0() {
+ AppenderTracker tracker = execute("sift/sample0.groovy")
+ logger.debug("x")
+ ListAppender unknownAppender = tracker.get("unknown", System.currentTimeMillis())
+ assertNotNull(unknownAppender)
+
+ MDC.put("userid", "a");
+ logger.debug("y");
+ ListAppender aAppender = tracker.get("a", System.currentTimeMillis())
+ assertNotNull(aAppender)
+
+ assertEquals(1, unknownAppender.list.size);
+ assertEquals("x", unknownAppender.list[0].message)
+ assertEquals(1, aAppender.list.size);
+ assertEquals("y", aAppender.list[0].message)
+ }
+
+ @Test
+ void sample1() {
+ AppenderTracker tracker = execute("sift/sample1.groovy")
+ logger.debug("x")
+
+ StatusPrinter.print context
+ FileAppender unknownAppender = tracker.get("unknown", System.currentTimeMillis())
+ assertNotNull(unknownAppender)
+ assertEquals("FILE-unknown", unknownAppender.name)
+ assertEquals("test-unknown.log", unknownAppender.file)
+
+ MDC.put("userid", "a");
+ logger.debug("y");
+ FileAppender aAppender = tracker.get("a", System.currentTimeMillis())
+ assertNotNull(aAppender)
+ assertEquals("FILE-a", aAppender.name)
+ assertEquals("test-a.log", aAppender.file)
+ assertEquals("a - %msg%n", aAppender.encoder.pattern)
+ }
+
+
+}
diff --git a/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy b/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy
new file mode 100644
index 0000000..e73d6da
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy
@@ -0,0 +1,37 @@
+//
+// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
+// For more information on configuration files in Groovy
+// please see http://logback.qos.ch/manual/groovy.html
+//
+
+import ch.qos.logback.classic.boolex.JaninoEventEvaluator
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder
+import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.core.filter.EvaluatorFilter
+
+import static ch.qos.logback.classic.Level.DEBUG
+import static ch.qos.logback.core.spi.FilterReply.DENY
+import static ch.qos.logback.core.spi.FilterReply.NEUTRAL
+import ch.qos.logback.core.boolex.Matcher
+import ch.qos.logback.core.spi.LifeCycle
+
+appender("STDOUT", ConsoleAppender) {
+ filter(EvaluatorFilter) {
+ evaluator(JaninoEventEvaluator) {
+ Matcher aMatcher = new Matcher()
+ aMatcher.name = "odd"
+ aMatcher.regex = "statement [13579]"
+ if(aMatcher instanceof LifeCycle)
+ aMatcher.start();
+ aMatcher.start();
+ matcher = aMatcher
+ expression = "odd.matches(formattedMessage)"
+ }
+ OnMismatch = NEUTRAL
+ OnMatch = DENY
+ }
+ encoder(PatternLayoutEncoder) {
+ pattern = "%-4relative [%thread] %-5level %logger - %msg%n"
+ }
+}
+root(DEBUG, ["STDOUT"])
diff --git a/logback-classic/src/test/input/gaffer/propertyCascading0.groovy b/logback-classic/src/test/input/gaffer/propertyCascading0.groovy
new file mode 100644
index 0000000..761591a
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/propertyCascading0.groovy
@@ -0,0 +1,22 @@
+//
+// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
+// For more information on configuration files in Groovy
+// please see http://logback.qos.ch/manual/groovy.html
+//
+
+import ch.qos.logback.core.ConsoleAppender
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+
+
+def p = "HELLO"
+appender("STDOUT", ConsoleAppender) {
+ encoder(LayoutWrappingEncoder) {
+ layout(PatternLayout) {
+ pattern = "${p} %m%n"
+ }
+ }
+}
+root(DEBUG, ["STDOUT"])
diff --git a/logback-classic/src/test/input/gaffer/propertyCascading1.groovy b/logback-classic/src/test/input/gaffer/propertyCascading1.groovy
new file mode 100644
index 0000000..944ae3a
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/propertyCascading1.groovy
@@ -0,0 +1,24 @@
+//
+// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
+// For more information on configuration files in Groovy
+// please see http://logback.qos.ch/manual/groovy.html
+//
+
+import ch.qos.logback.core.ConsoleAppender
+
+import static ch.qos.logback.classic.Level.DEBUG
+
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+
+
+
+appender("STDOUT", ConsoleAppender) {
+ def p = "HELLO"
+ encoder(LayoutWrappingEncoder) {
+ layout(PatternLayout) {
+ pattern = "${p} %m%n"
+ }
+ }
+}
+root(DEBUG, ["STDOUT"])
diff --git a/logback-classic/src/test/input/gaffer/propertyCascading2.groovy b/logback-classic/src/test/input/gaffer/propertyCascading2.groovy
new file mode 100644
index 0000000..072ca88
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/propertyCascading2.groovy
@@ -0,0 +1,22 @@
+//
+// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
+// For more information on configuration files in Groovy
+// please see http://logback.qos.ch/manual/groovy.html
+//
+
+import ch.qos.logback.core.ConsoleAppender
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+
+
+
+appender("STDOUT", ConsoleAppender) {
+ encoder(LayoutWrappingEncoder) {
+ layout(PatternLayout) {
+ pattern = "${context.getProperty('p')} %m%n"
+ }
+ }
+}
+root(DEBUG, ["STDOUT"])
diff --git a/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy b/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy
new file mode 100644
index 0000000..5a40ba3
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy
@@ -0,0 +1,22 @@
+/**
+ * @author Ceki Gücü
+ */
+
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.classic.sift.GSiftingAppender
+import ch.qos.logback.classic.sift.MDCBasedDiscriminator
+import ch.qos.logback.core.FileAppender
+import ch.qos.logback.core.read.ListAppender
+
+
+appender("SIFT", GSiftingAppender) {
+ sift {
+ appender("FILE-${userid}", ListAppender) {
+ println "USERID=$userid"
+ }
+ }
+}
+
+root(DEBUG, ["SIFT"])
diff --git a/logback-classic/src/test/input/gaffer/sift/sample0.groovy b/logback-classic/src/test/input/gaffer/sift/sample0.groovy
new file mode 100644
index 0000000..34b4026
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/sift/sample0.groovy
@@ -0,0 +1,26 @@
+/**
+ * @author Ceki Gücü
+ */
+
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.classic.sift.GSiftingAppender
+import ch.qos.logback.classic.sift.MDCBasedDiscriminator
+import ch.qos.logback.core.FileAppender
+import ch.qos.logback.core.read.ListAppender
+
+
+appender("SIFT", GSiftingAppender) {
+ discriminator(MDCBasedDiscriminator) {
+ key = "userid"
+ defaultValue = "unknown"
+ }
+ sift {
+ appender("LIST-${userid}", ListAppender) {
+ println "USERID=$userid"
+ }
+ }
+}
+
+root(DEBUG, ["SIFT"])
diff --git a/logback-classic/src/test/input/gaffer/sift/sample1.groovy b/logback-classic/src/test/input/gaffer/sift/sample1.groovy
new file mode 100644
index 0000000..702d1c8
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/sift/sample1.groovy
@@ -0,0 +1,31 @@
+/**
+ * @author Ceki Gücü
+ */
+
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.classic.sift.GSiftingAppender
+import ch.qos.logback.classic.sift.MDCBasedDiscriminator
+import ch.qos.logback.core.FileAppender
+import ch.qos.logback.core.read.ListAppender
+
+
+appender("SIFT", GSiftingAppender) {
+ discriminator(MDCBasedDiscriminator) {
+ key = "userid"
+ defaultValue = "unknown"
+ }
+ sift {
+ appender("FILE-${userid}", FileAppender) {
+ file = "test-${userid}.log"
+ append = false
+ encoder(PatternLayoutEncoder) {
+ println "in encoder userid=${userid}"
+ pattern = "${userid} - %msg%n"
+ }
+ }
+ }
+}
+
+root(DEBUG, ["SIFT"])
diff --git a/logback-classic/src/test/input/gaffer/smoke.groovy b/logback-classic/src/test/input/gaffer/smoke.groovy
index 3f7a1c5..cb0fd92 100644
--- a/logback-classic/src/test/input/gaffer/smoke.groovy
+++ b/logback-classic/src/test/input/gaffer/smoke.groovy
@@ -5,18 +5,6 @@ import ch.qos.logback.classic.Level
import ch.qos.logback.core.status.OnConsoleStatusListener
import ch.qos.logback.classic.Logger
-
-context.name = "a"
-
-Logger xLogger = context.getLogger("x")
-xLogger.setLevel(Level.INFO)
-
-statusListener OnConsoleStatusListener
-
-println "hostname ${hostname}"
-
-addInfo("xxx")
-
appender("C", ConsoleAppender) {
encoder(LayoutWrappingEncoder) {
layout(PatternLayout) {
@@ -24,5 +12,4 @@ appender("C", ConsoleAppender) {
}
}
}
-
root Level.WARN, ["C"]
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
index 2b036b0..7ca6684 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
@@ -57,7 +57,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
protected Layout<E> layout;
- private List<String> to = new ArrayList<String>();
+ private List<String> toList = new ArrayList<String>();
private String from;
private String subjectStr = null;
private String smtpHost;
@@ -131,7 +131,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
mimeMsg.setFrom();
}
- mimeMsg.setRecipients(Message.RecipientType.TO, parseAddress(to));
+ mimeMsg.setRecipients(Message.RecipientType.TO, parseAddress(toList));
subjectLayout = makeSubjectLayout(subjectStr);
@@ -234,10 +234,10 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
}
/**
- * Returns value of the <b>To</b> option.
+ * Returns value of the <b>toList</b> option.
*/
- public List<String> getTo() {
- return to;
+ public List<String> getToList() {
+ return toList;
}
/**
@@ -364,7 +364,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
* of one of the recipients.
*/
public void addTo(String to) {
- this.to.add(to);
+ this.toList.add(to);
}
// for testing purpose only
@@ -395,7 +395,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
/**
* The <b>EventEvaluator</b> option takes a string value representing the name
- * of the class implementing the {@link EventEvaluators} interface. A
+ * of the class implementing the {@link EventEvaluator} interface. A
* corresponding object will be instantiated and assigned as the event
* evaluator for the SMTPAppender.
*/
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
index c87daf9..73b4d09 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
@@ -28,7 +28,6 @@ public abstract class AppenderFactoryBase<E> {
protected AppenderFactoryBase(List<SaxEvent> eventList) {
this.eventList = new ArrayList<SaxEvent>(eventList);
removeSiftElement();
-
}
void removeSiftElement() {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
index 87a62b8..3e82fed 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
@@ -124,7 +124,7 @@ public abstract class SiftingAppenderBase<E> extends
/**
* @since 0.9.19
*/
- public AppenderTracker getAppenderTracer() {
+ public AppenderTracker getAppenderTracker() {
return appenderTracker;
}
diff --git a/logback-site/src/site/pages/css/common.css b/logback-site/src/site/pages/css/common.css
index b3c76ad..bc6a4fa 100644
--- a/logback-site/src/site/pages/css/common.css
+++ b/logback-site/src/site/pages/css/common.css
@@ -14,6 +14,12 @@ a {
text-decoration: underline;
}
+.example {
+ width: 90%;
+ font-style: italic;
+}
+
+
div.source {
margin-top: 1em;
}
diff --git a/logback-site/src/site/pages/css/screen.css b/logback-site/src/site/pages/css/screen.css
index 303ba61..d2cc84b 100644
--- a/logback-site/src/site/pages/css/screen.css
+++ b/logback-site/src/site/pages/css/screen.css
@@ -28,6 +28,7 @@ p.menu {
padding-bottom: 0px;
margin-top: 0px;
margin-bottom: 0px;
+ font-size: smaller;
}
@@ -126,7 +127,7 @@ span.asGroovy {
border-right: 2px solid #888;
border-bottom: 2px solid #888;
padding: 0px 1em 0px 1em;
- margin: -1ex 0px 0px 0px;
+ margin: -4px 4px 0 4px;
float: right;
}
diff --git a/logback-site/src/site/pages/manual/appenders.html b/logback-site/src/site/pages/manual/appenders.html
index 5ad977a..232775b 100644
--- a/logback-site/src/site/pages/manual/appenders.html
+++ b/logback-site/src/site/pages/manual/appenders.html
@@ -335,7 +335,11 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<code>ConsoleAppender</code>.
</p>
- <em>Example: ConsoleAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</em>
+
+
+ <p class="example">Example: ConsoleAppender configuration
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</p>
+
<span class="asGroovy" onclick="return asGroovy('logback_Console');">View as .grovvy</span>
<pre id="logback_Console" class="prettyprint source"><configuration>
@@ -473,7 +477,9 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<code>FileAppender</code>:
</p>
- <em>Example: FileAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</em>
+ <p class="example">Example: FileAppender configuration
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</p>
+
<span class="asGroovy" onclick="return asGroovy('logback-fileAppender');">View as .grovvy</span>
<pre id="logback-fileAppender" class="prettyprint source"><configuration>
@@ -497,7 +503,8 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
following command:
</p>
- <p class="source">java chapters.appenders.ConfigurationTester src/main/java/chapters/appenders/conf/logback-fileAppender.xml</p>
+ <p class="source">java chapters.appenders.ConfigurationTester
+ src/main/java/chapters/appenders/conf/logback-fileAppender.xml</p>
<h3>
@@ -512,8 +519,11 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
element. Here's an example.</p>
- <em>Example: Uniquely named FileAppender configuration by timestamp (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</em>
- <span class="asGroovy" onclick="return asGroovy('logback-timestamp');">View as .grovvy</span>
+ <p class="example">Example: Uniquely named FileAppender
+ configuration by timestamp
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</p>
+
+ <span class="asGroovy" onclick="return asGroovy('logback-timestamp');">View as .grovvy</span>
<pre id="logback-timestamp" class="prettyprint source"><configuration>
<!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
@@ -853,8 +863,8 @@ public interface RollingPolicy extends LifeCycle {
class="option">fileNamePattern</span> option.
</p>
- <em>Example: Sample configuration of a <code>RollingFileAppender</code> using a
- <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml)</em>
+ <p class="example">Example: Sample configuration of a <code>RollingFileAppender</code> using a
+ <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-RollingFixedWindow');">View as .grovvy</span>
<pre id="logback-RollingFixedWindow" class="prettyprint source"><configuration>
@@ -1165,11 +1175,10 @@ public interface RollingPolicy extends LifeCycle {
<code>TimeBasedRollingPolicy</code>.
</p>
- <em>Example: Sample configuration of a
+ <p class="example">Example: Sample configuration of a
<code>RollingFileAppender</code> using a
-
<code>TimeBasedRollingPolicy</code>
- (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml)</em>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-RollingTimeBased');">View as .grovvy</span>
<pre id="logback-RollingTimeBased" class="prettyprint source"><configuration>
@@ -1199,10 +1208,10 @@ public interface RollingPolicy extends LifeCycle {
mode.
</p>
- <em>Example: Sample configuration of a
+ <p class="example">Example: Sample configuration of a
<code>RollingFileAppender</code> using a
<code>TimeBasedRollingPolicy</code>
- (logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</em>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-PrudentTimeBasedRolling');">View as .grovvy</span>
<pre id="logback-PrudentTimeBasedRolling" class="prettyprint source"><configuration>
@@ -1241,9 +1250,9 @@ public interface RollingPolicy extends LifeCycle {
<p>Here is a sample configuration file demonstrating time and size
based log file archiving.</p>
- <em>Example: Sample configuration for
+ <p class="example">Example: Sample configuration for
<code>SizeAndTimeBasedFNATP</code>
- (logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml)</em>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">View as .grovvy</span>
<pre id="logback-sizeAndTime" class="prettyprint source"><configuration>
@@ -1349,8 +1358,10 @@ public interface TriggeringPolicy<E> extends LifeCycle {
the log file reaches 5MB in size.
</p>
- <em>Example: Sample configuration of a <code>RollingFileAppender</code> using a
- <code>SizeBasedTriggeringPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml)</em>
+ <p class="example">Example: Sample configuration of a
+ <code>RollingFileAppender</code> using a
+ <code>SizeBasedTriggeringPolicy</code>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-RollingSizeBased');">View as .grovvy</span>
<pre id="logback-RollingSizeBased" class="prettyprint source"><configuration>
@@ -1570,7 +1581,8 @@ public interface TriggeringPolicy<E> extends LifeCycle {
and attaches it to the root logger.
</p>
- <em>Example: SocketAppender configuration (logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</em>
+ <p class="example">Example: SocketAppender configuration
+ (logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('client1');">View as .grovvy</span>
<pre id="client1" class="prettyprint source"><configuration>
@@ -2030,9 +2042,11 @@ Context ctx = new InitialContext(env);</pre>
<code>JMSTopicAppender</code> is rather straightforward to configure:
</p>
- <em>Example: JMSTopicAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml)</em>
+ <p class="example">Example: JMSTopicAppender configuration
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml)</p>
+
<span class="asGroovy" onclick="return asGroovy('logback-JMSTopic');">View as .grovvy</span>
-<pre id="logback-JMSTopic" class="prettyprint source"><configuration>
+ <pre id="logback-JMSTopic" class="prettyprint source"><configuration>
<appender name="Topic"
class="ch.qos.logback.classic.net.JMSTopicAppender">
@@ -2099,7 +2113,10 @@ Context ctx = new InitialContext(env);</pre>
A typical <code>JMSQueueAppender</code> configuration file looks very
similar to that of a <code>JMSTopicAppender</code>.
</p>
- <em>Example: JMSQueueAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml)</em>
+
+ <p class="example">Example: JMSQueueAppender configuration
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml)</p>
+
<span class="asGroovy" onclick="return asGroovy('logback-JMSQueue');">View as .grovvy</span>
<pre id="logback-JMSQueue" class="prettyprint source"><configuration>
@@ -2315,7 +2332,7 @@ Context ctx = new InitialContext(env);</pre>
<code>Email</code> application:
</p>
- <em>Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</em>
+ <p class="example">Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mail1');">View as .grovvy</span>
<pre id="mail1" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2431,8 +2448,8 @@ Context ctx = new InitialContext(env);</pre>
1024th event triggers an email message.
</p>
- <em>Example: A <code>EventEvaluator</code> implementation
-that evaluates to <code>true</code> every 1024th event (<a href="../xref/chapters/appenders/mail/CounterBasedEvaluator.html">logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java</a>)</em>
+ <p class="example">Example: A <code>EventEvaluator</code> implementation
+that evaluates to <code>true</code> every 1024th event (<a href="../xref/chapters/appenders/mail/CounterBasedEvaluator.html">logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java</a>)</p>
<pre class="prettyprint source">package chapters.appenders.mail;
@@ -2483,8 +2500,8 @@ public class CounterBasedEvaluator extends ContextAwareBase implements EventEval
evaluator.
</p>
- <em>Example: <code>SMTPAppender</code> with custom
- <code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</em>
+ <p class="example">Example: <code>SMTPAppender</code> with custom
+ <code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mail3');">View as .grovvy</span>
<pre id="mail3" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2532,8 +2549,8 @@ logger.error(<b>notifyAdminMarker</b>,
TRANSACTION_FAILURE marker.
</p>
- <em>Example: <code>SMTPAppender</code> with
- <code>OnMarkerEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml)</em>
+ <p class="example">Example: <code>SMTPAppender</code> with
+ <code>OnMarkerEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mailWithMarker');">View as .grovvy</span>
<pre id="mailWithMarker" class="prettyprint source"><configuration>
@@ -2581,7 +2598,9 @@ logger.error(<b>notifyAdminMarker</b>,
<p>The next example shows you how to configure
<code>SMTPAppender</code> for Gmail with the SSL protocol. </p>
- <em><code>SMTPAppender</code> to Gmail using SSL (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</em>
+ <p class="example">Example:: <code>SMTPAppender</code> to Gmail
+ using SSL
+ (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</p>
<span class="asGroovy" onclick="return asGroovy('gmailSSL');">View as .grovvy</span>
<pre id="gmailSSL" class="prettyprint source"><configuration>
@@ -2613,7 +2632,7 @@ logger.error(<b>notifyAdminMarker</b>,
<p>The next example shows you how to configure
<code>SMTPAppender</code> for Gmail for the STARTTLS protocol. </p>
- <em>Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</em>
+ <p class="example">Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</p>
<span class="asGroovy" onclick="return asGroovy('gmailSTARTTLS');">View as .grovvy</span>
<pre id="gmailSTARTTLS" class="prettyprint source"><configuration>
@@ -2933,7 +2952,7 @@ logger.error(<b>notifyAdminMarker</b>,
The following configuration file is what one would need.
</p>
- <em>Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</em>
+ <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-driverManager');">View as .grovvy</span>
<pre id="append-toMySQL-with-driverManager" class="prettyprint source"><configuration>
@@ -3012,7 +3031,7 @@ logger.error(<b>notifyAdminMarker</b>,
<code>javax.sql.DataSource</code>.
</p>
- <em>Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</em>
+ <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-with-datasource');">View as .grovvy</span>
@@ -3128,9 +3147,10 @@ logger.error(<b>notifyAdminMarker</b>,
without any pooling.
</p>
- <em>Example 4.<span class="autoEx"/> <code>DBAppender</code>
- configuration without pooling
- (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</em>
+ <p class="example">Example: <code>DBAppender</code> configuration
+ without pooling
+ (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</p>
+
<span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource');">View as .grovvy</span>
<pre id="append-toMySQL-with-datasource" class="prettyprint source"><configuration>
@@ -3164,7 +3184,9 @@ logger.error(<b>notifyAdminMarker</b>,
<em>c3p0-VERSION.jar</em> in the classpath.
</p>
- <em>Example: <code>DBAppender</code> configuration with pooling (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</em>
+ <p class="example">Example: <code>DBAppender</code> configuration
+ with pooling
+ (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource-and-pooling');">View as .grovvy</span>
<pre id="append-toMySQL-with-datasource-and-pooling" class="prettyprint source"><configuration>
@@ -3300,7 +3322,7 @@ logger.error(<b>notifyAdminMarker</b>,
Here is a sample configuration using a <code>SyslogAppender</code>.
</p>
- <em>Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</em>
+ <p class="example">Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-syslog');">View as .grovvy</span>
<pre id="logback-syslog" class="prettyprint source"><configuration>
@@ -3357,11 +3379,13 @@ logger.debug("Alice says hello"); </p>
<code>SiftingAppender</code>.</p>
- <em>Example: <code>SiftingAppender</code>
+ <p class="example">Example: <code>SiftingAppender</code>
configuration
- (logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml)</em>
+ (logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml)</p>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('byUserid');">View as .grovvy</span>
+
+ <pre id="byUserid" class="prettyprint source"><configuration>
<b><appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"></b>
<!-- in the absence of the class attribute, it is assumed that the
@@ -3567,7 +3591,10 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
<p>
Here is a sample configuration of a <code>SMTPAppender</code> in the access environment.
</p>
-<em>Example: <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</em>
+ <p class="example">Example: <code>SMTPAppender</code>
+ configuration
+ (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</p>
+
<pre class="prettyprint source"><appender name="SMTP"
class="ch.qos.logback.access.net.SMTPAppender">
<layout class="ch.qos.logback.access.html.HTMLLayout">
@@ -3737,7 +3764,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
Here is a sample configuration that uses <code>DBAppender</code>.
</p>
- <em>Example: DBAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em>
+ <p class="example">Example: DBAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="DB" class="ch.qos.logback.access.db.DBAppender">
@@ -3776,7 +3803,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
<p>Below is an example configuration file.</p>
- <em>Example: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</em>
+ <p class="example">Example: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
diff --git a/logback-site/src/site/pages/manual/configuration.html b/logback-site/src/site/pages/manual/configuration.html
index d73e024..ccf5099 100644
--- a/logback-site/src/site/pages/manual/configuration.html
+++ b/logback-site/src/site/pages/manual/configuration.html
@@ -17,7 +17,7 @@
<script type="text/javascript">prefix='../'</script>
<script type="text/javascript" src="../js/prettify.js"></script>
<script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
+ <script type="text/javascript" src="../js/dsl.js"></script>
<div id="left">
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="../templates/left.js" type="text/javascript"></script>
@@ -130,9 +130,9 @@
<code>MyApp1</code>.
</p>
- <em>Example: Simple example of <code>BasicConfigurator</code>
- usage <a
- href="../xref/chapters/configuration/MyApp1.html">(logback-examples/src/main/java/chapters/configuration/MyApp1.java)</a></em>
+ <p class="example">Example: Simple example of
+ <code>BasicConfigurator</code> usage <a
+ href="../xref/chapters/configuration/MyApp1.html">(logback-examples/src/main/java/chapters/configuration/MyApp1.java)</a></p>
<pre class="prettyprint source">package manual.configuration;
@@ -155,9 +155,9 @@ public class MyApp1 {
instantiates a Foo object. The Foo class is listed below:
</p>
- <em>Example: Small class doing logging
+ <p class="example">Example: Small class doing logging
<a href="../xref/chapters/configuration/Foo.html">(logback-examples/src/main/java/chapters/configuration/Foo.java)</a>
- </em>
+ </p>
<pre class="prettyprint source">package chapters.configuration;
@@ -232,9 +232,9 @@ public class Foo {
seen.
</p>
- <em>Example: Basic configuration file
- (logback-examples/src/main/java/chapters/configuration/sample0.xml)</em>
- <span class="asGroovy" onclick="return asGroovy('sample0');">View as .grovvy</span>
+ <p class="example">Example: Basic configuration file
+ (logback-examples/src/main/java/chapters/configuration/sample0.xml)</p>
+ <span class="asGroovy" onclick="return asGroovy('sample0');">View as .grovvy</span>
<pre id="sample0" class="prettyprint source"><configuration>
@@ -278,9 +278,9 @@ public class Foo {
addition of two lines of code for printing internal status
data.</p>
- <em>Example: Print logback's internal status information
- <a
- href="../xref/chapters/configuration/MyApp2.html">(logback-examples/src/main/java/chapters/configuration/MyApp2.java)</a></em>
+ <p class="example">Example: Print logback's internal status
+ information <a
+ href="../xref/chapters/configuration/MyApp2.html">(logback-examples/src/main/java/chapters/configuration/MyApp2.java)</a></p>
<pre class="prettyprint lang-java source">
@@ -327,9 +327,9 @@ public class Foo {
</p>
- <em>Example: Basic configuration file
- using debug mode
- (logback-examples/src/main/java/chapters/configuration/sample1.xml)</em>
+ <p class="example">Example: Basic configuration file using debug
+ mode
+ (logback-examples/src/main/java/chapters/configuration/sample1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample1');">View as .grovvy</span>
<pre id="sample1" class="prettyprint source">
@@ -402,9 +402,10 @@ public class Foo {
<code><configuration></code> element to true, as shown next.
</p>
- <em>Example: Scanning for changes in
- configuration file and automatic re-configuraion
- (logback-examples/src/main/java/chapters/configuration/scan1.xml)</em>
+
+ <p class="example">Example: Scanning for changes in configuration
+ file and automatic re-configuraion
+ (logback-examples/src/main/java/chapters/configuration/scan1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('scan1');">View as .grovvy</span>
<pre id="scan1" class="prettyprint source">
@@ -420,9 +421,8 @@ public class Foo {
units of milliseconds, seconds, minutes or hours. Here is an
example:</p>
- <em>Example: Specifying a different
- scanning period
- (logback-examples/src/main/java/chapters/configuration/scan2.xml)</em>
+ <p class="example">Example: Specifying a different scanning period
+ (logback-examples/src/main/java/chapters/configuration/scan2.xml)</p>
<span class="asGroovy" onclick="return asGroovy('scan2');">View as .grovvy</span>
<pre id="scan2" class="prettyprint source">
<configuration scan="true" <b>scanPeriod="30 seconds"</b> >
@@ -472,9 +472,9 @@ public class Foo {
application, <em>MyApp3</em>, invokes JoranConfigurator on a
configuration file passed as a parameter.</p>
- <p><em>Example: Invoking
- <code>JoranConfigurator</code> directly <a
- href="../xref/chapters/configuration/MyApp3.html">(logback-examples/src/main/java/chapters/configuration/MyApp3.java)</a></em></p>
+ <p class="example">Example: Invoking <code>JoranConfigurator</code>
+ directly <a
+ href="../xref/chapters/configuration/MyApp3.html">(logback-examples/src/main/java/chapters/configuration/MyApp3.java)</a></p>
<pre class="prettyprint source">package chapters.configuration;
@@ -609,8 +609,8 @@ public class MyApp3 {
<p>It is also possible to register one or more status listeners
within a configuration file. Here is an example.</p>
- <p><em>Example: Registering a status listener
- (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</em></p>
+ <p class="example">Example: Registering a status listener
+ (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</p>
<span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">View as .grovvy</span>
<pre id="onConsoleStatusListener" class="prettyprint source"><configuration>
@@ -767,8 +767,8 @@ public class MyApp3 {
shows how to achieve that.
</p>
- <em>Example: Setting the level of a logger
- (logback-examples/src/main/java/chapters/configuration/sample2.xml)</em>
+ <p class="example">Example: Setting the level of a logger
+ (logback-examples/src/main/java/chapters/configuration/sample2.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample2');">View as .grovvy</span>
<pre id="sample2" class="prettyprint source"><configuration>
@@ -808,8 +808,8 @@ public class MyApp3 {
of the <em>chapters.configuration.Foo</em> logger to <code>DEBUG</code>.
</p>
- <em>Example: Setting the level of multiple loggers
- (logback-examples/src/main/java/chapters/configuration/sample3.xml)</em>
+ <p class="example">Example: Setting the level of multiple loggers
+ (logback-examples/src/main/java/chapters/configuration/sample3.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample3');">View as .grovvy</span>
<pre id="sample3" class="source prettyprint"><configuration>
@@ -890,8 +890,8 @@ public class MyApp3 {
<em>sample4.xml</em> is a case in point:
</p>
- <em>Example: Logger level sample
- (logback-examples/src/main/java/chapters/configuration/sample4.xml)</em>
+ <p class="example">Example: Logger level sample
+ (logback-examples/src/main/java/chapters/configuration/sample4.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample4');">View as .grovvy</span>
<pre id="sample4" class="prettyprint source"><configuration>
@@ -1015,8 +1015,9 @@ public class MyApp3 {
configuration file illustrates:
</p>
- <em>Example: Multiple loggers
- (logback-examples/src/main/java/chapters/configuration/multiple.xml)</em>
+ <p class="example">Example: Multiple loggers
+ (logback-examples/src/main/java/chapters/configuration/multiple.xml)</p>
+
<span class="asGroovy" onclick="return asGroovy('multiple');">View as .grovvy</span>
<pre id="multiple" class="prettyprint source"><configuration>
@@ -1069,8 +1070,8 @@ public class MyApp3 {
duplicated.
</p>
- <em>Example: Duplicate appender
- (logback-examples/src/main/java/chapters/configuration/duplicate.xml)</em>
+ <p class="example">Example: Duplicate appender
+ (logback-examples/src/main/java/chapters/configuration/duplicate.xml)</p>
<span class="asGroovy" onclick="return asGroovy('duplicate');">View as .grovvy</span>
<pre id="duplicate" class="prettyprint source"><configuration>
@@ -1117,8 +1118,8 @@ public class MyApp3 {
set of loggers flow into a specific appender.
</p>
- <em>Example: Multiple appender
- (logback-examples/src/main/java/chapters/configuration/restricted.xml)</em>
+ <p class="example">Example: Multiple appender
+ (logback-examples/src/main/java/chapters/configuration/restricted.xml)</p>
<span class="asGroovy" onclick="return asGroovy('restricted');">View as .grovvy</span>
<pre id="restricted" class="prettyprint source"><configuration>
@@ -1163,8 +1164,8 @@ public class MyApp3 {
of the tree.
</p>
- <em>Example: Additivity flag
- (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</em>
+ <p class="example">Example: Additivity flag
+ (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</p>
<span class="asGroovy" onclick="return asGroovy('additivityFlag');">View as .grovvy</span>
<pre id="additivityFlag" class="prettyprint source"><configuration>
@@ -1219,8 +1220,8 @@ public class MyApp3 {
applications logging to the same target.
</p>
- <em>Example: Set the context name and display it
- (logback-examples/src/main/java/chapters/configuration/contextName.xml)</em>
+ <p class="example">Example: Set the context name and display it
+ (logback-examples/src/main/java/chapters/configuration/contextName.xml)</p>
<span class="asGroovy" onclick="return asGroovy('contextName');">View as .grovvy</span>
<pre id="contextName" class="prettyprint source"><configuration>
@@ -1274,11 +1275,12 @@ public class MyApp3 {
output file.
</p>
- <em>Example: Simple Variable substitution
+ <p class="example">Example: Simple Variable substitution
(logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml)
- </em>
+ </p>
- <span class="asGroovy" onclick="return asGroovy('variableSubstitution1');">View as .grovvy</span>
+ <span class="asGroovy" onclick="return
+ asGroovy('variableSubstitution1');">View as .grovvy</span>
<pre id="variableSubstitution1" class="prettyprint source"><configuration>
<b><property name="USER_HOME" value="/home/sebastien" /></b>
@@ -1304,9 +1306,9 @@ public class MyApp3 {
<p class="source">java -DUSER_HOME="/home/sebastien" MyApp2</p>
- <em>Example: System Variable substitution
+ <p class="example">Example: System Variable substitution
(logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml)
- </em>
+ </p>
<span class="asGroovy" onclick="return asGroovy('variableSubstitution2');">View as .grovvy</span>
<pre id="variableSubstitution2" class="prettyprint source"><configuration>
@@ -1328,10 +1330,10 @@ public class MyApp3 {
how one can do such a setup.
</p>
- <em>Example: Variable substitution using a
+ <p class="example">Example: Variable substitution using a
separate file
(logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml)
- </em>
+ </p>
<pre class="prettyprint source"><configuration>
@@ -1390,8 +1392,8 @@ public class MyApp3 {
properties file shown below gives an example.
</p>
- <em>Example: Nested variable references
- (logback-examples/src/main/java/chapters/configuration/variables2.properties)</em>
+ <p class="example">Example: Nested variable references
+ (logback-examples/src/main/java/chapters/configuration/variables2.properties)</p>
<pre class="source">USER_HOME=/home/sebastien
fileName=myApp.log
@@ -1590,8 +1592,10 @@ fileName=myApp.log
class="attr">as</span> attribute.
</p>
- <em>Example: Insert as properties env-entries obtained via JNDI
- (logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml)</em>
+ <p class="example">Example: Insert as properties env-entries
+ obtained via JNDI
+ (logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml)</p>
+
<pre class="prettyprint source"><configuration>
<b><insertFromJNDI env-entry-name="java:comp/env/appName" as="<span class="green">appName"</span> /></b>
<b><contextName><span class="green">${appName}</span></contextName></b>
@@ -1623,8 +1627,8 @@ fileName=myApp.log
element, as shown below:
</p>
- <em>Example: File include
- (logback-examples/src/main/java/chapters/configuration/containingConfig.xml)</em>
+ <p class="example">Example: File include
+ (logback-examples/src/main/java/chapters/configuration/containingConfig.xml)</p>
<pre class="prettyprint source"><configuration>
<b><include file="src/main/java/chapters/configuration/includedConfig.xml"/></b>
@@ -1640,8 +1644,8 @@ fileName=myApp.log
<code>ConsoleAppender</code> could be declared as:
</p>
- <em>Example: File include
- (logback-examples/src/main/java/chapters/configuration/includedConfig.xml)</em>
+ <p class="example">Example: File include
+ (logback-examples/src/main/java/chapters/configuration/includedConfig.xml)</p>
<pre class="source"><b class="green big"><included></b>
<appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
diff --git a/logback-site/src/site/pages/manual/groovy.html b/logback-site/src/site/pages/manual/groovy.html
new file mode 100644
index 0000000..78d89b8
--- /dev/null
+++ b/logback-site/src/site/pages/manual/groovy.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+ <title>Chapter3: Logback configuration</title>
+
+ <link rel="stylesheet" type="text/css" href="../css/common.css" />
+ <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
+ <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
+ <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen" />
+
+ </head>
+ <body onload="prettyPrint()">
+
+ <script type="text/javascript">prefix='../'</script>
+ <script type="text/javascript" src="../js/prettify.js"></script>
+ <script src="../templates/header.js" type="text/javascript"></script>
+ <script type="text/javascript" src="../js/dsl.js"></script>
+ <div id="left">
+ <noscript>Please turn on Javascript to view this menu</noscript>
+ <script src="../templates/left.js" type="text/javascript"></script>
+ </div>
+ <div id="right">
+ <script src="menu.js" type="text/javascript"></script>
+ </div>
+ <div id="content" class="chapter">
+
+ <h1>Chapter 12: Groovy Configuration</h1>
+
+ <div class="quote">
+ <p><em>It is better to be a human being dissatisfied than a pig
+ satisfied; better to be a Socrates dissatisfied than a fool
+ satisfied. And if the fool or the pig thinks otherwise, it is
+ because they have no experience of the better part.
+ </em>
+ </p>
+ <p>—JOHN STUART MILL, <em>Utilitarianism</em></p>
+ </div>
+ <script src="../templates/creative.js" type="text/javascript"></script>
+
+
+ <p>Domains-specific languages are rather pervasive. The XML-based
+ logback configuration can be be viewed as an example of a DSL. By
+ the very nature of XML, XML-based configuration files are quite
+ verbose and bulky. Moreover, a relatively large body of code in
+ logback, namely Joran, is dedicated to processes these XML-based
+ configuration files. Joran supports nifty features such as
+ variable subsitution, conditional processing and on-the-fly
+ extensibility. Not only Joran is a complex beast, the
+ user-experience it provides can be described as unsatisfactory or
+ at the very least unintuitive.
+ </p>
+
+ <p>The Groovy-based DSL described in this chapter aims to be
+ consistent, intuitive, and powerful. Everything you can do XML in
+ configuration files, you can do in Groovy in a much shorter
+ syntax. There is even a tool to automatically migrate XML
+
+
+
+ </div>
+ </body>
+</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/index.html b/logback-site/src/site/pages/manual/index.html
index 8b832d0..5d0599a 100644
--- a/logback-site/src/site/pages/manual/index.html
+++ b/logback-site/src/site/pages/manual/index.html
@@ -114,8 +114,11 @@
<a href="onJoran.html"><b>Chapter 11: Joran</b></a>
</p></li>
+ <li><p><a href="groovy.html"><b>Chapter 12: Groovy
+ Configuration</b></a></p></li>
+
<li><p>
- <a href="migrationFromLog4j.html"><b>Chapter 12: Migration from log4j</b></a>
+ <a href="migrationFromLog4j.html"><b>Chapter 13: Migration from log4j</b></a>
</p></li>
</ul>
diff --git a/logback-site/src/site/pages/manual/menu.js b/logback-site/src/site/pages/manual/menu.js
index d7679cb..cf0f7f8 100644
--- a/logback-site/src/site/pages/manual/menu.js
+++ b/logback-site/src/site/pages/manual/menu.js
@@ -11,4 +11,5 @@ document.write('<p class="menu"><a href="mdc.html"><b>Ch8: Mapped Diagnostic Con
document.write('<p class="menu"><a href="loggingSeparation.html"><b>Ch9: Logging Separation</b></a>');
document.write('<p class="menu"><a href="jmxConfig.html"><b>Ch10: JMX Configurator</b></a>');
document.write('<p class="menu"><a href="onJoran.html"><b>Ch11: Joran</b></a>');
-document.write('<p class="menu"><a href="migrationFromLog4j.html"><b>Ch12: Migration from log4j</b></a>');
+document.write('<p class="menu"><a href="groovy.html"><b>Ch12: Groovy Configuration</b></a>');
+document.write('<p class="menu"><a href="migrationFromLog4j.html"><b>Ch13: Migration from log4j</b></a>');
diff --git a/logback-site/src/site/pages/manual/migrationFromLog4j.html b/logback-site/src/site/pages/manual/migrationFromLog4j.html
index d34f043..dfc948d 100644
--- a/logback-site/src/site/pages/manual/migrationFromLog4j.html
+++ b/logback-site/src/site/pages/manual/migrationFromLog4j.html
@@ -23,7 +23,7 @@
</div>
<div id="content">
- <h1>Chapter 12: Migration from log4j</h1>
+ <h1>Chapter 13: Migration from log4j</h1>
<div class="quote">
<p><em>The more things change, the more they remain the
-----------------------------------------------------------------------
Summary of changes:
.../qos/logback/access/sift/SiftingAppender.java | 4 -
logback-classic/osgi-build.xml | 2 +-
logback-classic/pom.xml | 2 +-
logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF | 2 +-
.../classic/gaffer/ComponentDelegate.groovy | 112 ++++++++-------
...gate.groovy => ConfigurationContributor.groovy} | 21 ++--
.../classic/gaffer/ConfigurationDelegate.groovy | 11 ++
.../qos/logback/classic/gaffer/NestedType.groovy | 11 +-
.../qos/logback/classic/gaffer/PropertyUtil.groovy | 72 +++++++++
.../logback/classic/sift/GSiftingAppender.groovy | 153 ++++++++++++++++++++
.../logback/classic/sift/ZSiftingDelegate.groovy | 39 +++++
.../qos/logback/classic/sift/SiftingAppender.java | 4 -
.../gaffer/ConfigurationDelegateTest.groovy | 23 +++
.../logback/classic/gaffer/ConfiguratorTest.groovy | 56 +++++++
.../logback/classic/gaffer/PropertyUtilTest.groovy | 26 ++++
.../classic/sift/GSiftingAppenderTest.groovy | 110 ++++++++++++++
.../test/input/gaffer/evaluatorWithMatcher.groovy | 37 +++++
.../test/input/gaffer/propertyCascading0.groovy | 22 +++
.../test/input/gaffer/propertyCascading1.groovy | 24 +++
.../test/input/gaffer/propertyCascading2.groovy | 22 +++
.../test/input/gaffer/sift/noDiscriminator.groovy | 22 +++
.../src/test/input/gaffer/sift/sample0.groovy | 26 ++++
.../src/test/input/gaffer/sift/sample1.groovy | 31 ++++
logback-classic/src/test/input/gaffer/smoke.groovy | 13 --
.../ch/qos/logback/core/net/SMTPAppenderBase.java | 14 +-
.../qos/logback/core/sift/AppenderFactoryBase.java | 1 -
.../qos/logback/core/sift/SiftingAppenderBase.java | 2 +-
logback-site/src/site/pages/css/common.css | 6 +
logback-site/src/site/pages/css/screen.css | 3 +-
logback-site/src/site/pages/manual/appenders.html | 111 +++++++++------
.../src/site/pages/manual/configuration.html | 118 ++++++++--------
logback-site/src/site/pages/manual/groovy.html | 65 +++++++++
logback-site/src/site/pages/manual/index.html | 5 +-
logback-site/src/site/pages/manual/menu.js | 3 +-
.../src/site/pages/manual/migrationFromLog4j.html | 2 +-
35 files changed, 972 insertions(+), 203 deletions(-)
copy logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/{AppenderDelegate.groovy => ConfigurationContributor.groovy} (60%)
copy logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java => logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy (73%)
create mode 100644 logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy
create mode 100644 logback-classic/src/main/groovy/ch/qos/logback/classic/sift/GSiftingAppender.groovy
create mode 100644 logback-classic/src/main/groovy/ch/qos/logback/classic/sift/ZSiftingDelegate.groovy
create mode 100644 logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy
create mode 100644 logback-classic/src/test/groovy/ch/qos/logback/classic/sift/GSiftingAppenderTest.groovy
create mode 100644 logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy
create mode 100644 logback-classic/src/test/input/gaffer/propertyCascading0.groovy
create mode 100644 logback-classic/src/test/input/gaffer/propertyCascading1.groovy
create mode 100644 logback-classic/src/test/input/gaffer/propertyCascading2.groovy
create mode 100644 logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy
create mode 100644 logback-classic/src/test/input/gaffer/sift/sample0.groovy
create mode 100644 logback-classic/src/test/input/gaffer/sift/sample1.groovy
create mode 100644 logback-site/src/site/pages/manual/groovy.html
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[JIRA] Created: (LBCLASSIC-210) configuration: property: detect circular references
by Cristian Vasile Mocanu (JIRA) 23 May '10
by Cristian Vasile Mocanu (JIRA) 23 May '10
23 May '10
configuration: property: detect circular references
---------------------------------------------------
Key: LBCLASSIC-210
URL: http://jira.qos.ch/browse/LBCLASSIC-210
Project: logback-classic
Issue Type: Improvement
Components: joran
Affects Versions: 0.9.21
Reporter: Cristian Vasile Mocanu
Assignee: Logback dev list
In case I have cycles in properties, I get an unfriendly StackOverflowError in OptionHelper. I am referring to properties like this:
{code}
a=${b}
b=${a}
{code}
It would be nice to detect these cases and show a nice error message explaining the actual problem, instead of StackOverflowError.
For inspiration, you can take a look at Spring's PropertyPlaceholderConfigurer (the actual place where they detect this is org.springframework.util.PropertyPlaceholderHelper#parseStringValue in version 3.0.1.RELEASE).
--
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
0
Hello all,
As you probably know already, there is an ongoing survey about the
preferred language for the logback DSL. See [1].
Here are the results so far.
Do not care for either 25%
Groovy 25%
Scala 50%
Interestingly enough, most respondents express a strong preference for
Scala over Groovy even if Groovy seems to have a larger user base.
Cheers,
--
Ceki
[1] http://ceki.questionform.com/public/logbackDSL
1
1
Hello all,
This is just to inform you that I made real progress on the Groovy DSL
for logback. I'll be doing more testing in the next few
days. Documentation to follow.
There is a tool to translate logback.xml configuration files to
logback.groovy available at
http://logback.qos.ch/translator/asGroovy.html
Cheers,
--
Ceki
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.21-2-g060efd8
by git-noreplyï¼ pixie.qos.ch 18 May '10
by git-noreplyï¼ pixie.qos.ch 18 May '10
18 May '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 060efd8495dedc95fc0f6abb688b8e0a1eaa1628 (commit)
from 2cec26a3063cfa89133cc83e13e07f3c4a2d7746 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=060efd8495dedc95fc0f6abb…
http://github.com/ceki/logback/commit/060efd8495dedc95fc0f6abb688b8e0a1eaa1…
commit 060efd8495dedc95fc0f6abb688b8e0a1eaa1628
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Tue May 18 23:38:53 2010 +0200
- significant progress made with the groovy DSL
- logback-translator now supports XML to .groovy translations
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
new file mode 100644
index 0000000..ef2ed83
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
@@ -0,0 +1,32 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+import ch.qos.logback.core.Appender
+import ch.qos.logback.core.spi.ContextAwareBase
+
+/**
+ * @author Ceki Gücü
+ */
+class AppenderDelegate extends ComponentDelegate {
+
+ AppenderDelegate(Appender appender) {
+ super(appender)
+ }
+
+ String getLabel() {
+ "appender"
+ }
+
+}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
new file mode 100644
index 0000000..1db63a6
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
@@ -0,0 +1,146 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+import ch.qos.logback.core.Appender
+import ch.qos.logback.core.spi.ContextAwareBase
+import ch.qos.logback.core.spi.LifeCycle
+import ch.qos.logback.core.spi.ContextAware
+
+/**
+ * @author Ceki Gücü
+ */
+
+@Mixin(ContextAwareBase)
+class ComponentDelegate {
+
+ final Object component;
+
+ ComponentDelegate(Object component) {
+ this.component = component;
+ }
+
+ String getLabel() { "component" }
+
+ String getLabelFistLetterInUpperCase() { getLabel()[0].toUpperCase() + getLabel().substring(1) }
+
+ void methodMissing(String name, def args) {
+
+ if (component.hasProperty(name)) {
+ String subComponentName
+ Class clazz
+ Closure closure
+ (subComponentName, clazz, closure) = analyzeArgs(args)
+ if (clazz != null) {
+ Object subComponent = clazz.newInstance()
+ if (subComponentName && subComponent.hasProperty(name)) {
+ subComponent.name = subComponentName;
+ }
+ if (subComponent instanceof ContextAware) {
+ subComponent.context = context;
+ }
+ if (closure) {
+ ComponentDelegate subDelegate = new ComponentDelegate(subComponent)
+ subDelegate.context = context
+ closure.delegate = subDelegate
+ closure.resolveStrategy = Closure.DELEGATE_FIRST
+ closure()
+ }
+ if (subComponent instanceof LifeCycle) {
+ subComponent.start();
+ }
+ component."${name}" = subComponent;
+ }
+ } else {
+ addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no [${name}] property ")
+ }
+ }
+
+ def analyzeArgs(Object[] args) {
+ String name;
+ Class clazz;
+ Closure closure;
+
+ if (args.size() > 3) {
+ addError("At most 3 arguments allowed but you passed $args")
+ return [name, clazz, closure]
+ }
+
+ if (args[-1] instanceof Closure) {
+ closure = args[-1]
+ args -= args[-1]
+ }
+
+ if (args.size() == 1) {
+ clazz = parseClassArgument(args[0])
+ }
+
+ if (args.size() == 2) {
+ name = parseNameArgument(args[0])
+ clazz = parseClassArgument(args[1])
+ }
+
+ return [name, clazz, closure]
+ }
+
+ Class parseClassArgument(arg) {
+ if (arg instanceof Class) {
+ return arg
+ } else if (arg instanceof String) {
+ return Class.forName(arg)
+ } else {
+ addError("Unexpected argument type ${arg.getClass().canonicalName}")
+ return null;
+ }
+ }
+
+ String parseNameArgument(arg) {
+ if (arg instanceof String) {
+ return arg
+ } else {
+ addError("With 2 or 3 arguments, the first argument must be the component name, i.e of type string")
+ return null;
+ }
+ }
+
+ String getComponentName() {
+ if (component.hasProperty("name"))
+ return "[${component.name}]"
+ else
+ return ""
+
+ }
+
+ void propertyMissing(String name, def value) {
+ name = camelCasify(name);
+ if (component.hasProperty(name)) {
+ //println "-- component has property $name"
+ component."${name}" = value;
+ } else {
+ // println "-- component does not have property [$name]"
+ addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no [${name}] property ")
+ }
+ }
+
+ String camelCasify(String name) {
+ if(name == null || name.length() == 0)
+ return name;
+
+ String firstLetter = new String(name.getAt(0)).toLowerCase();
+ if(name.length() == 1)
+ return firstLetter
+ else
+ return firstLetter + name.substring(1);
+ }
+}
\ No newline at end of file
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
index 8ba018b..e45b223 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
@@ -1,3 +1,16 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
package ch.qos.logback.classic.gaffer;
import ch.qos.logback.core.util.Duration;
@@ -11,44 +24,61 @@ import ch.qos.logback.core.spi.ContextAwareImpl
import ch.qos.logback.core.spi.ContextAwareBase
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
-import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.Appender
+import ch.qos.logback.core.status.StatusListener
+import java.text.SimpleDateFormat
+import ch.qos.logback.classic.turbo.TurboFilter
+import ch.qos.logback.core.CoreConstants;
/**
* @author Ceki Gücü
*/
-@Mixin(ContextAwareBase)
-public class ConfigurationDelegate {
+public class ConfigurationDelegate extends ContextAwareBase {
List<Appender> appenderList = [];
- void configuration(Closure closure) {
- configuration([:], closure)
+
+ Object getDeclaredOrigin() {
+ //println "ConfigurationDelegate"
+ return "ConfigurationDelegate"
}
+ void scan(String scanPeriodStr = null) {
+ ReconfigureOnChangeFilter rocf = new ReconfigureOnChangeFilter();
+ rocf.setContext(context);
+ if (scanPeriodStr) {
+ try {
+ Duration duration = Duration.valueOf(scanPeriodStr);
+ rocf.setRefreshPeriod(duration.getMilliseconds());
+ addInfo("Setting ReconfigureOnChangeFilter scanning period to "
+ + duration);
+ } catch (NumberFormatException nfe) {
+ addError("Error while converting [" + scanAttrib + "] to long", nfe);
+ }
+ }
+ rocf.start();
+ addInfo("Adding ReconfigureOnChangeFilter as a turbo filter");
+ context.addTurboFilter(rocf);
+ }
- void configuration(Map map, Closure closure) {
- processScanAttributes(map.scan, map.scanPeriod);
+ void statusListener(Class listenerClass) {
+ StatusListener statusListener = listenerClass.newInstance()
+ context.statusManager.add(statusListener)
+ addInfo("Added status listener of type [${listenerClass.canonicalName}]");
}
- private void processScanAttributes(boolean scan, String scanPeriodStr) {
- if (scan) {
- ReconfigureOnChangeFilter rocf = new ReconfigureOnChangeFilter();
- rocf.setContext(context);
- if (scanPeriodStr) {
- try {
- Duration duration = Duration.valueOf(scanPeriodStr);
- rocf.setRefreshPeriod(duration.getMilliseconds());
- addInfo("Setting ReconfigureOnChangeFilter scanning period to "
- + duration);
- } catch (NumberFormatException nfe) {
- addError("Error while converting [" + scanAttrib + "] to long", nfe);
- }
- }
- rocf.start();
- addInfo("Adding ReconfigureOnChangeFilter as a turbo filter");
- context.addTurboFilter(rocf);
+ void conversionRule(String conversionWord, Class converterClass) {
+ String converterClassName = converterClass.getName();
+
+ Map<String, String> ruleRegistry = (Map) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY);
+ if (ruleRegistry == null) {
+ ruleRegistry = new HashMap<String, String>();
+ context.putObject(CoreConstants.PATTERN_RULE_REGISTRY, ruleRegistry);
}
+ // put the new rule into the rule registry
+ addInfo("registering conversion word " + conversionWord + " with class [" + converterClassName + "]");
+ ruleRegistry.put(conversionWord, converterClassName);
}
void root(Level level, List<String> appenderNames = []) {
@@ -66,11 +96,11 @@ public class ConfigurationDelegate {
if (appenderNames) {
appenderNames.each { aName ->
- Appender appender = appenderList.find { it.name == aName };
+ Appender appender = appenderList.find { it -> it.name == aName };
if (appender != null) {
logger.addAppender(appender);
} else {
- addError("Failed to find appender named [${it.name}]");
+ addError("Failed to find appender named [${aName}]");
}
}
}
@@ -84,7 +114,9 @@ public class ConfigurationDelegate {
}
void appender(String name, Class clazz, Closure closure = null) {
+ addInfo("About to instantiate appender of type [" + clazz.name + "]");
Appender appender = clazz.newInstance();
+ addInfo("Naming appender as [" + name + "]");
appender.name = name
appender.context = context
appenderList.add(appender)
@@ -97,5 +129,27 @@ public class ConfigurationDelegate {
}
appender.start();
}
+
+ void turboFilter(Class clazz, Closure closure = null) {
+ addInfo("About to instantiate turboFilter of type [" + clazz.name + "]");
+ TurboFilter turboFilter = clazz.newInstance();
+ turboFilter.context = context
+
+ if (closure != null) {
+ ComponentDelegate componentDelegate = new ComponentDelegate(turboFilter);
+ componentDelegate.context = context;
+ closure.delegate = componentDelegate;
+ closure.resolveStrategy = Closure.DELEGATE_FIRST
+ closure();
+ }
+ turboFilter.start();
+ addInfo("Adding aforementioned turbo filter to context");
+ context.addTurboFilter(turboFilter)
+ }
+
+ String timestamp(String datePattern) {
+ SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
+ sdf.format(new Date());
+ }
}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/Configurator.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/Configurator.groovy
index 9c18e68..09d6baf 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/Configurator.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/Configurator.groovy
@@ -13,35 +13,32 @@
*/
package ch.qos.logback.classic.gaffer
-class Configurator {
+import ch.qos.logback.classic.LoggerContext
+import ch.qos.logback.core.util.ContextUtil
- static void main(String[] args) {
- runArchitectureRules(new File("src/ch/test/toto.groovy"))
- }
+class Configurator {
- static void runArchitectureRules(File dsl) {
- //LoggerFactory loggerFactory = new LoggerFactory();
- ConfigurationDelegate configurationDelegate = new ConfigurationDelegate();
- //AppenderAction appenderAction = new AppenderAction();
+ LoggerContext context
+ //ConfigurationDelegate configurationDelegate = new ConfigurationDelegate();
+ Configurator(LoggerContext context) {
+ this.context = context
+ //configurationDelegate.context = context;
+ }
+ void run(String dslText) {
Binding binding = new Binding();
- binding.setProperty("DEBUG", new Integer(1));
- Script dslScript = new GroovyShell(binding).parse(dsl.text)
- ExpandoMetaClass emc = new ExpandoMetaClass(dslScript.class, false);
-
- //configurationDelegate.metaClass.logger = loggerFactory.&logger
- //configurationDelegate.metaClass.appender = appenderAction.&appender
-
- emc.configuration = {Closure cl ->
- println "executing configuration"
- cl.delegate = configuration
- cl();
- }
-
-
- emc.initialize();
- dslScript.metaClass = emc;
+ binding.setProperty("hostname", ContextUtil.getLocalHostName());
+ Script dslScript = new GroovyShell(binding).parse(dslText)
+
+ dslScript.metaClass.mixin(ConfigurationDelegate)
+ dslScript.setContext(context)
+ dslScript.metaClass.getDeclaredOrigin = { println "getDeclaredOrigin"; dslScript }
+// metaClass.statusListener = configurationDelegate.&statusListener
+// dslScript.metaClass.scan = configurationDelegate.&scan
+// dslScript.metaClass.appender = configurationDelegate.&appender
+// dslScript.metaClass.root = configurationDelegate.&root
+// dslScript.metaClass.logger = configurationDelegate.&logger
dslScript.run()
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java
index 5bc712f..451891d 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java
@@ -45,8 +45,8 @@ public class LevelFilter extends AbstractMatcherFilter<ILoggingEvent> {
}
}
- public void setLevel(String level) {
- this.level = Level.toLevel(level);
+ public void setLevel(Level level) {
+ this.level = level;
}
public void start() {
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
deleted file mode 100644
index 3898a41..0000000
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
+++ /dev/null
@@ -1,32 +0,0 @@
-package ch.qos.logback.classic.gaffer
-
-import ch.qos.logback.core.Appender
-import ch.qos.logback.core.spi.ContextAwareBase
-
-/**
- * @author Ceki Gücü
- */
-@Mixin(ContextAwareBase)
-class AppenderDelegate {
-
- Appender appender;
-
- AppenderDelegate(Appender appender) {
- this.appender = appender;
- }
-
- void methodMissing(String name, args) {
- println "method $name accessed"
- }
-
- void propertyMissing(String name, def value) {
- println "-- propertyMissing"
- if(appender.hasProperty(name)) {
- //println "-- appender has property $name"
- appender."${name}" = value;
- } else {
- //println "-- appender does not have property [$name]"
- addError("Appender [${appender.name}] of type [${appender.getClass().canonicalName}] has no [${name}] property " )
- }
- }
-}
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
index 7125a97..66d6b4d 100644
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
@@ -13,13 +13,14 @@ import ch.qos.logback.classic.Logger
import ch.qos.logback.core.Appender
import ch.qos.logback.core.helpers.NOPAppender
import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
/**
* @author Ceki Gücü
*/
class ConfigurationDelegateTest {
-
LoggerContext context = new LoggerContext()
ConfigurationDelegate configurationDelegate = new ConfigurationDelegate();
StatusChecker statusChecker = new StatusChecker(context)
@@ -39,7 +40,7 @@ class ConfigurationDelegateTest {
@Test
void scan() {
- configurationDelegate.configuration([scan: true, scanPeriod: "10seconds"]) {}
+ configurationDelegate.scan("10seconds")
assertTrue(statusChecker.containsMatch("Setting ReconfigureOnChangeFilter"))
assertTrue(statusChecker.containsMatch("Adding ReconfigureOnChangeFilter as a turbo filter"))
@@ -50,6 +51,14 @@ class ConfigurationDelegateTest {
}
@Test
+ void timestamp() {
+ String result = configurationDelegate.timestamp("yyyy")
+ long year = Calendar.getInstance().get(Calendar.YEAR);
+ assertEquals(year.toString(), result)
+ }
+
+
+ @Test
void loggerWithoutName() {
configurationDelegate.logger("", Level.DEBUG)
assertTrue(statusChecker.containsMatch("No name attribute for logger"))
@@ -132,4 +141,25 @@ class ConfigurationDelegateTest {
assertEquals("C", back.name)
assertEquals("System.err", back.target)
}
+
+
+ @Test
+ void appenderWithEncoder() {
+ configurationDelegate.appender("C", ConsoleAppender) {
+ encoder (LayoutWrappingEncoder) {
+ layout (PatternLayout) {
+ pattern = "%m%n"
+ }
+ }
+ }
+ Appender back = configurationDelegate.appenderList.find {it.name = "C"}
+ assertNotNull(back)
+ assertEquals("C", back.name)
+ ConsoleAppender ca = back
+ assertNotNull(ca.encoder)
+ assertNotNull(ca.encoder.layout)
+ PatternLayout layout = ca.encoder.layout
+ assertEquals("%m%n", layout.pattern)
+
+ }
}
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
new file mode 100644
index 0000000..53ee836
--- /dev/null
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
@@ -0,0 +1,103 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+import ch.qos.logback.classic.ClassicTestConstants
+import ch.qos.logback.classic.LoggerContext
+import org.junit.Before
+import ch.qos.logback.core.testUtil.RandomUtil
+import org.junit.Test
+import ch.qos.logback.classic.Logger
+import ch.qos.logback.classic.Level
+import static junit.framework.Assert.assertNotNull
+import static junit.framework.Assert.assertEquals
+import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.classic.spi.ILoggingEvent
+import ch.qos.logback.core.testUtil.StringListAppender
+import ch.qos.logback.classic.testUtil.SampleConverter
+import ch.qos.logback.core.util.StatusPrinter
+
+/**
+ * @author Ceki Gücü
+ */
+class ConfiguratorTest {
+
+ LoggerContext context = new LoggerContext();
+ Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME)
+ Logger logger = context.getLogger(this.getClass())
+ int diff = RandomUtil.getPositiveInt();
+ Configurator configurator = new Configurator(context);
+
+ @Before
+ void setUp() {
+
+ }
+
+ @Test
+ void smoke() {
+ File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "smoke.groovy")
+ String dslText = file.text
+ configurator.run dslText
+ Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME);
+ assertEquals(Level.WARN, root.level)
+ assertNotNull(root.getAppender("C"))
+ ConsoleAppender ca = root.getAppender("C")
+ assertNotNull(ca.encoder)
+ assertNotNull(ca.encoder.layout)
+ PatternLayout layout = ca.encoder.layout
+ assertEquals("%m%n", layout.pattern)
+ }
+
+ @Test
+ void onTheFly() {
+ File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "onTheFly.groovy")
+ String dslText = file.text
+ configurator.run dslText
+ }
+
+ @Test
+ void contextName() {
+ String dslText = "context.name = 'a'"
+ configurator.run dslText
+ assertEquals("a", context.name)
+ }
+
+ @Test
+ void contextProperty() {
+ String dslText = "context.putProperty('x', 'a')"
+ configurator.run dslText
+ assertEquals("a", context.getProperty("x"))
+ }
+
+ @Test
+ void conversionRule() {
+ File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "conversionRule.groovy")
+ String dslText = file.text
+ configurator.run dslText
+
+ StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root.getAppender("LIST");
+ assertNotNull(sla);
+ assertEquals(0, sla.strList.size());
+
+ assertEquals(Level.DEBUG, root.level);
+
+ String msg = "Simon says";
+ logger.debug(msg);
+ StatusPrinter.print context
+ assertEquals(1, sla.strList.size());
+ assertEquals(SampleConverter.SAMPLE_STR + " - " + msg, sla.strList.get(0));
+ }
+
+}
diff --git a/logback-classic/src/test/input/gaffer/conversionRule.groovy b/logback-classic/src/test/input/gaffer/conversionRule.groovy
new file mode 100644
index 0000000..c59fe09
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/conversionRule.groovy
@@ -0,0 +1,13 @@
+import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.classic.testUtil.SampleConverter
+import ch.qos.logback.core.testUtil.StringListAppender
+
+import static ch.qos.logback.classic.Level.DEBUG
+
+conversionRule("sample", SampleConverter)
+appender("LIST", StringListAppender) {
+ layout(PatternLayout) {
+ Pattern = "%sample - %msg"
+ }
+}
+root(DEBUG, ["LIST"])
diff --git a/logback-classic/src/test/input/gaffer/onTheFly.groovy b/logback-classic/src/test/input/gaffer/onTheFly.groovy
new file mode 100644
index 0000000..d4dda9f
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/onTheFly.groovy
@@ -0,0 +1,9 @@
+import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.classic.Level
+
+
+scan ()
+metaClass.xxx = { println "xxxxx"}
+xxx()
diff --git a/logback-classic/src/test/input/gaffer/smoke.groovy b/logback-classic/src/test/input/gaffer/smoke.groovy
new file mode 100644
index 0000000..3f7a1c5
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/smoke.groovy
@@ -0,0 +1,28 @@
+import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.classic.Level
+import ch.qos.logback.core.status.OnConsoleStatusListener
+import ch.qos.logback.classic.Logger
+
+
+context.name = "a"
+
+Logger xLogger = context.getLogger("x")
+xLogger.setLevel(Level.INFO)
+
+statusListener OnConsoleStatusListener
+
+println "hostname ${hostname}"
+
+addInfo("xxx")
+
+appender("C", ConsoleAppender) {
+ encoder(LayoutWrappingEncoder) {
+ layout(PatternLayout) {
+ pattern = "%m%n"
+ }
+ }
+}
+
+root Level.WARN, ["C"]
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java b/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java
index c9471fd..fab5c7e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java
@@ -14,10 +14,10 @@
package ch.qos.logback.classic;
public class ClassicTestConstants {
-
- final static public String ISO_REGEX = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}";
- final static public String NAKED_MAIN_REGEX = "[mM]ain(\\sThread)?";
- final static public String MAIN_REGEX = "\\["+NAKED_MAIN_REGEX+"\\]";
+ final static public String ISO_REGEX = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}";
+ final static public String NAKED_MAIN_REGEX = "[mM]ain(\\sThread)?";
+ final static public String MAIN_REGEX = "\\[" + NAKED_MAIN_REGEX + "\\]";
final static public String INPUT_PREFIX = "src/test/input/";
- final static public String JORAN_INPUT_PREFIX = INPUT_PREFIX+"joran/";
+ final static public String JORAN_INPUT_PREFIX = INPUT_PREFIX + "joran/";
+ final static public String GAFFER_INPUT_PREFIX = INPUT_PREFIX + "gaffer/";
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java
index f10afcb..3ea6b12 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java
@@ -1,13 +1,13 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2010, QOS.ch. All rights reserved.
- *
+ *
* This program and the accompanying materials are dual-licensed under either
* the terms of the Eclipse Public License v1.0 as published by the Eclipse
* Foundation
- *
+ *
* or (per the licensee's choosing)
- *
+ *
* under the terms of the GNU Lesser General Public License version 2.1 as
* published by the Free Software Foundation.
*/
@@ -25,14 +25,19 @@ public class ContextUtil extends ContextAwareBase {
public ContextUtil(Context context) {
setContext(context);
}
-
+
+ static String getLocalHostName() throws UnknownHostException {
+ InetAddress localhost = InetAddress.getLocalHost();
+ return localhost.getHostName();
+ }
+
/**
* Add the local host's name as a property
*/
public void addHostNameAsProperty() {
try {
- InetAddress localhost = InetAddress.getLocalHost();
- context.putProperty(CoreConstants.HOSTNAME_KEY, localhost.getHostName());
+ String localhostName = getLocalHostName();
+ context.putProperty(CoreConstants.HOSTNAME_KEY, localhostName);
} catch (UnknownHostException e) {
addError("Failed to get local hostname", e);
} catch (SecurityException e) {
diff --git a/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml b/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
index bcc3c14..b435900 100644
--- a/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
+++ b/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
@@ -6,7 +6,7 @@
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative [%thread] %sample - %msg%n</pattern>
- </encoder>>
+ </encoder>
</appender>
<root level="DEBUG">
diff --git a/logback-site/src/site/pages/css/_print.css b/logback-site/src/site/pages/css/_print.css
index b385779..84b45b0 100644
--- a/logback-site/src/site/pages/css/_print.css
+++ b/logback-site/src/site/pages/css/_print.css
@@ -6,7 +6,7 @@ body {
font-size: 12px;
}
-#left, #right {
+#left, #right, span.asGroovy {
width: 0px;
height: 0px;
display: none;
@@ -28,4 +28,3 @@ table.bodyTable th {
text-align:center;
}
-
diff --git a/logback-site/src/site/pages/css/common.css b/logback-site/src/site/pages/css/common.css
index d3a58aa..b3c76ad 100644
--- a/logback-site/src/site/pages/css/common.css
+++ b/logback-site/src/site/pages/css/common.css
@@ -25,7 +25,7 @@ div.source {
.source, .command, .console {
border-top: 1px solid #DDDDDD;
border-bottom: 1px solid #DDDDDD;
- background:#eee;
+ background: #eee;
font-family: Courier, "MS Courier New", Prestige, monospace;
padding-left: 1ex;
white-space: pre;
diff --git a/logback-site/src/site/pages/css/screen.css b/logback-site/src/site/pages/css/screen.css
index 5369a7a..303ba61 100644
--- a/logback-site/src/site/pages/css/screen.css
+++ b/logback-site/src/site/pages/css/screen.css
@@ -113,3 +113,25 @@ p.menu_header {
margin-right: auto;
display: block;
}
+
+span.asGroovy {
+ background: #fff;
+ color: #0079C5;
+ font-family: "Comic Sans MS", sans-serif;
+ white-space: nowrap;
+ font-size: 80%;
+
+ border-top: 2px solid #DDD;
+ border-left: 2px solid #DDD;
+ border-right: 2px solid #888;
+ border-bottom: 2px solid #888;
+ padding: 0px 1em 0px 1em;
+ margin: -1ex 0px 0px 0px;
+ float: right;
+}
+
+span.asGroovy:hover {
+ background: #E0E0EF;
+ cursor: pointer;
+}
+
diff --git a/logback-site/src/site/pages/js/dsl.js b/logback-site/src/site/pages/js/dsl.js
new file mode 100644
index 0000000..baeef73
--- /dev/null
+++ b/logback-site/src/site/pages/js/dsl.js
@@ -0,0 +1,39 @@
+
+var asGroovyURL='http://logback.qos.ch/translator/dsl/asGroovy';
+
+function asGroovy(id) {
+
+ var form = document.getElementById('aForm');
+ if(form == null) {
+ form = document.createElement("form");
+ document.body.appendChild(form);
+ }
+ var p = document.getElementById(id);
+
+ var inner = p.innerHTML;
+ //alert("==="+inner);
+ inner = inner.replace(/</gi, '<');
+ inner = inner.replace(/>/gi, '>');
+
+ inner = inner.replace(/<span class="?\w{3,5}"?>/gi, '');
+ inner = inner.replace(/<\/span>/gi, '');
+ inner = inner.replace(/<br>/gi, '');
+ inner = inner.replace(/ /gi, '');
+ inner = inner.replace(/<b>/gi, '');
+ inner = inner.replace(/<\/b>/gi, '');
+
+ form.setAttribute("method", "post");
+ form.setAttribute("action", asGroovyURL);
+
+ var hiddenField = document.createElement("input");
+ hiddenField.setAttribute("type", "hidden");
+ hiddenField.setAttribute("name", "val");
+ hiddenField.setAttribute("value", inner);
+ form.appendChild(hiddenField);
+
+ //alert("==="+inner);
+ form.submit();
+ return false;
+}
+
+
diff --git a/logback-site/src/site/pages/manual/appenders.html b/logback-site/src/site/pages/manual/appenders.html
index b6ab67e..5ad977a 100644
--- a/logback-site/src/site/pages/manual/appenders.html
+++ b/logback-site/src/site/pages/manual/appenders.html
@@ -7,12 +7,13 @@
<link rel="stylesheet" type="text/css" href="../css/common.css" />
<link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
<link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen" /
+ <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"/>
</head>
<body onload="prettyPrint()">
<script type="text/javascript">prefix='../';</script>
<script type="text/javascript" src="../js/prettify.js"></script>
<script src="../templates/header.js" type="text/javascript"></script>
+ <script type="text/javascript" src="../js/dsl.js"></script>
<div id="left">
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="../templates/left.js" type="text/javascript"></script>
@@ -334,8 +335,10 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<code>ConsoleAppender</code>.
</p>
- <em>Example 4.<span class="autoEx"/>: ConsoleAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <em>Example: ConsoleAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('logback_Console');">View as .grovvy</span>
+
+ <pre id="logback_Console" class="prettyprint source"><configuration>
<b><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
@@ -470,8 +473,9 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<code>FileAppender</code>:
</p>
- <em>Example 4.<span class="autoEx"/>: FileAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <em>Example: FileAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('logback-fileAppender');">View as .grovvy</span>
+ <pre id="logback-fileAppender" class="prettyprint source"><configuration>
<b><appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
@@ -508,8 +512,9 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
element. Here's an example.</p>
- <em>Example 4.<span class="autoEx"/>: Uniquely named FileAppender configuration by timestamp (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <em>Example: Uniquely named FileAppender configuration by timestamp (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('logback-timestamp');">View as .grovvy</span>
+ <pre id="logback-timestamp" class="prettyprint source"><configuration>
<!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
the key "bySecond" into the logger context. This value will be
@@ -848,10 +853,11 @@ public interface RollingPolicy extends LifeCycle {
class="option">fileNamePattern</span> option.
</p>
- <em>Example 4.<span class="autoEx"/>: Sample configuration of a <code>RollingFileAppender</code> using a
+ <em>Example: Sample configuration of a <code>RollingFileAppender</code> using a
<code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('logback-RollingFixedWindow');">View as .grovvy</span>
+ <pre id="logback-RollingFixedWindow" class="prettyprint source"><configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<b><file>test.log</file></b>
@@ -1159,13 +1165,14 @@ public interface RollingPolicy extends LifeCycle {
<code>TimeBasedRollingPolicy</code>.
</p>
- <em>Example 4.<span class="autoEx"/>: Sample configuration of a
+ <em>Example: Sample configuration of a
<code>RollingFileAppender</code> using a
<code>TimeBasedRollingPolicy</code>
(logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('logback-RollingTimeBased');">View as .grovvy</span>
+ <pre id="logback-RollingTimeBased" class="prettyprint source"><configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<b><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
@@ -1192,12 +1199,13 @@ public interface RollingPolicy extends LifeCycle {
mode.
</p>
- <em>Example 4.<span class="autoEx"/>: Sample configuration of a
+ <em>Example: Sample configuration of a
<code>RollingFileAppender</code> using a
<code>TimeBasedRollingPolicy</code>
(logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('logback-PrudentTimeBasedRolling');">View as .grovvy</span>
+ <pre id="logback-PrudentTimeBasedRolling" class="prettyprint source"><configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<b><!-- Support multiple-JVM writing to the same log file --></b>
<b><prudent>true</prudent></b>
@@ -1208,7 +1216,7 @@ public interface RollingPolicy extends LifeCycle {
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encocer>
+ </encoder>
</appender>
<root level="DEBUG">
@@ -1233,15 +1241,17 @@ public interface RollingPolicy extends LifeCycle {
<p>Here is a sample configuration file demonstrating time and size
based log file archiving.</p>
- <em>Example 4.<span class="autoEx"/>: Sample configuration for
+ <em>Example: Sample configuration for
<code>SizeAndTimeBasedFNATP</code>
(logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml)</em>
- <pre class="prettyprint source"><configuration>
+
+ <span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">View as .grovvy</span>
+ <pre id="logback-sizeAndTime" class="prettyprint source"><configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
- <fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big red">%i</span>.txt</b></fileNamePattern>
+ <fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big">%i</span>.txt</b></fileNamePattern>
<b><timeBasedFileNamingAndTriggeringPolicy</b>
<b>class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"></b>
<!-- or whenever the file size reaches 100MB -->
@@ -1339,9 +1349,11 @@ public interface TriggeringPolicy<E> extends LifeCycle {
the log file reaches 5MB in size.
</p>
- <em>Example 4.<span class="autoEx"/>: Sample configuration of a <code>RollingFileAppender</code> using a
+ <em>Example: Sample configuration of a <code>RollingFileAppender</code> using a
<code>SizeBasedTriggeringPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml)</em>
- <pre class="prettyprint source"><configuration>
+
+ <span class="asGroovy" onclick="return asGroovy('logback-RollingSizeBased');">View as .grovvy</span>
+ <pre id="logback-RollingSizeBased" class="prettyprint source"><configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
@@ -1353,7 +1365,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<b><triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy></b>
- <encoder
+ <encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
@@ -1558,8 +1570,9 @@ public interface TriggeringPolicy<E> extends LifeCycle {
and attaches it to the root logger.
</p>
- <em>Example 4.<span class="autoEx"/>: SocketAppender configuration (logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: SocketAppender configuration (logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('client1');">View as .grovvy</span>
+<pre id="client1" class="prettyprint source"><configuration>
<appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
<RemoteHost>${host}</RemoteHost>
@@ -2017,8 +2030,9 @@ Context ctx = new InitialContext(env);</pre>
<code>JMSTopicAppender</code> is rather straightforward to configure:
</p>
- <em>Example 4.<span class="autoEx"/>: JMSTopicAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: JMSTopicAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('logback-JMSTopic');">View as .grovvy</span>
+<pre id="logback-JMSTopic" class="prettyprint source"><configuration>
<appender name="Topic"
class="ch.qos.logback.classic.net.JMSTopicAppender">
@@ -2085,8 +2099,9 @@ Context ctx = new InitialContext(env);</pre>
A typical <code>JMSQueueAppender</code> configuration file looks very
similar to that of a <code>JMSTopicAppender</code>.
</p>
- <em>Example 4.<span class="autoEx"/>: JMSQueueAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: JMSQueueAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('logback-JMSQueue');">View as .grovvy</span>
+ <pre id="logback-JMSQueue" class="prettyprint source"><configuration>
<appender name="Queue"
class="ch.qos.logback.classic.net.JMSQueueAppender">
@@ -2300,8 +2315,9 @@ Context ctx = new InitialContext(env);</pre>
<code>Email</code> application:
</p>
- <em>Example 4.<span class="autoEx"/>: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <em>Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('mail1');">View as .grovvy</span>
+ <pre id="mail1" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<SMTPHost>ADDRESS-OF-YOUR-SMTP-HOST</SMTPHost>
<To>EMAIL-DESTINATION</To>
@@ -2415,9 +2431,10 @@ Context ctx = new InitialContext(env);</pre>
1024th event triggers an email message.
</p>
-<em>Example 4.<span class="autoEx"/>: A <code>EventEvaluator</code> implementation
+ <em>Example: A <code>EventEvaluator</code> implementation
that evaluates to <code>true</code> every 1024th event (<a href="../xref/chapters/appenders/mail/CounterBasedEvaluator.html">logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java</a>)</em>
-<pre class="prettyprint source">package chapters.appenders.mail;
+
+ <pre class="prettyprint source">package chapters.appenders.mail;
import ch.qos.logback.core.boolex.EvaluationException;
import ch.qos.logback.core.boolex.EventEvaluator;
@@ -2466,10 +2483,10 @@ public class CounterBasedEvaluator extends ContextAwareBase implements EventEval
evaluator.
</p>
-<em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> with custom
-<code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</em>
-
-<pre class="prettyprint source"><configuration>
+ <em>Example: <code>SMTPAppender</code> with custom
+ <code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('mail3');">View as .grovvy</span>
+ <pre id="mail3" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<b><Evaluator class="chapters.appenders.mail.CounterBasedEvaluator" /></b>
<BufferSize>1050</BufferSize>
@@ -2515,10 +2532,11 @@ logger.error(<b>notifyAdminMarker</b>,
TRANSACTION_FAILURE marker.
</p>
- <em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> with
+ <em>Example: <code>SMTPAppender</code> with
<code>OnMarkerEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('mailWithMarker');">View as .grovvy</span>
+ <pre id="mailWithMarker" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<b><evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>NOTIFY_ADMIN</marker>
@@ -2563,9 +2581,10 @@ logger.error(<b>notifyAdminMarker</b>,
<p>The next example shows you how to configure
<code>SMTPAppender</code> for Gmail with the SSL protocol. </p>
- <em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> to Gmail using SSL (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</em>
+ <em><code>SMTPAppender</code> to Gmail using SSL (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('gmailSSL');">View as .grovvy</span>
+ <pre id="gmailSSL" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<b><SMTPHost>smtp.gmail.com</SMTPHost></b>
<b><SMTPPort>465</SMTPPort></b>
@@ -2594,9 +2613,10 @@ logger.error(<b>notifyAdminMarker</b>,
<p>The next example shows you how to configure
<code>SMTPAppender</code> for Gmail for the STARTTLS protocol. </p>
- <em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</em>
+ <em>Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('gmailSTARTTLS');">View as .grovvy</span>
+ <pre id="gmailSTARTTLS" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<SMTPHost>smtp.gmail.com</SMTPHost>
<SMTPPort>587</SMTPPort>
@@ -2913,8 +2933,9 @@ logger.error(<b>notifyAdminMarker</b>,
The following configuration file is what one would need.
</p>
-<em>Example 4.<span class="autoEx"/>: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-driverManager');">View as .grovvy</span>
+ <pre id="append-toMySQL-with-driverManager" class="prettyprint source"><configuration>
<b><appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
@@ -2991,8 +3012,11 @@ logger.error(<b>notifyAdminMarker</b>,
<code>javax.sql.DataSource</code>.
</p>
-<em>Example 4.<span class="autoEx"/>: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</em>
+
+
+ <span class="asGroovy" onclick="return asGroovy('append-with-datasource');">View as .grovvy</span>
+ <pre id="append-with-datasource" class="prettyprint source"><configuration>
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
<b><connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
@@ -3104,8 +3128,11 @@ logger.error(<b>notifyAdminMarker</b>,
without any pooling.
</p>
- <em>Example 4.<span class="autoEx"/> <code>DBAppender</code> configuration without pooling (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <em>Example 4.<span class="autoEx"/> <code>DBAppender</code>
+ configuration without pooling
+ (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource');">View as .grovvy</span>
+ <pre id="append-toMySQL-with-datasource" class="prettyprint source"><configuration>
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
@@ -3122,7 +3149,7 @@ logger.error(<b>notifyAdminMarker</b>,
<root level="DEBUG">
<appender-ref ref="DB" />
</root>
-</configuration</pre>
+</configuration></pre>
<p>With this configuration file, sending 500 logging events to a
MySQL database takes a whopping 5 seconds, that is 10 milliseconds
@@ -3137,8 +3164,9 @@ logger.error(<b>notifyAdminMarker</b>,
<em>c3p0-VERSION.jar</em> in the classpath.
</p>
- <em>Example 4.<span class="autoEx"/>: <code>DBAppender</code> configuration with pooling (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <em>Example: <code>DBAppender</code> configuration with pooling (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource-and-pooling');">View as .grovvy</span>
+ <pre id="append-toMySQL-with-datasource-and-pooling" class="prettyprint source"><configuration>
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
<connectionSource
@@ -3272,8 +3300,9 @@ logger.error(<b>notifyAdminMarker</b>,
Here is a sample configuration using a <code>SyslogAppender</code>.
</p>
-<em>Example 4.<span class="autoEx"/>: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('logback-syslog');">View as .grovvy</span>
+ <pre id="logback-syslog" class="prettyprint source"><configuration>
<appender name="SYSLOG"
class="ch.qos.logback.classic.net.SyslogAppender">
@@ -3283,7 +3312,7 @@ logger.error(<b>notifyAdminMarker</b>,
</appender>
<root level="DEBUG">
- <appender-ref ref="STDOUT" />
+ <appender-ref ref="SYSLOG" />
</root>
</configuration></pre>
@@ -3328,7 +3357,7 @@ logger.debug("Alice says hello"); </p>
<code>SiftingAppender</code>.</p>
- <em>Example 4.<span class="autoEx"/>: <code>SiftingAppender</code>
+ <em>Example: <code>SiftingAppender</code>
configuration
(logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml)</em>
@@ -3538,7 +3567,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
<p>
Here is a sample configuration of a <code>SMTPAppender</code> in the access environment.
</p>
-<em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</em>
+<em>Example: <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</em>
<pre class="prettyprint source"><appender name="SMTP"
class="ch.qos.logback.access.net.SMTPAppender">
<layout class="ch.qos.logback.access.html.HTMLLayout">
@@ -3708,7 +3737,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
Here is a sample configuration that uses <code>DBAppender</code>.
</p>
- <em>Example 4.<span class="autoEx"/>: DBAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em>
+ <em>Example: DBAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="DB" class="ch.qos.logback.access.db.DBAppender">
@@ -3747,7 +3776,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
<p>Below is an example configuration file.</p>
- <em>Example 4.<span class="autoEx"/>: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</em>
+ <em>Example: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
diff --git a/logback-site/src/site/pages/manual/configuration.html b/logback-site/src/site/pages/manual/configuration.html
index f6de8cc..d73e024 100644
--- a/logback-site/src/site/pages/manual/configuration.html
+++ b/logback-site/src/site/pages/manual/configuration.html
@@ -17,6 +17,7 @@
<script type="text/javascript">prefix='../'</script>
<script type="text/javascript" src="../js/prettify.js"></script>
<script src="../templates/header.js" type="text/javascript"></script>
+ <script type="text/javascript" src="../js/dsl.js"></script>
<div id="left">
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="../templates/left.js" type="text/javascript"></script>
@@ -231,11 +232,12 @@ public class Foo {
seen.
</p>
- <p><em>Example: Basic configuration file
- (logback-examples/src/main/java/chapters/configuration/sample0.xml)</em></p>
+ <em>Example: Basic configuration file
+ (logback-examples/src/main/java/chapters/configuration/sample0.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('sample0');">View as .grovvy</span>
-<pre class="prettyprint source"><configuration>
+ <pre id="sample0" class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
@@ -328,8 +330,9 @@ public class Foo {
<em>Example: Basic configuration file
using debug mode
(logback-examples/src/main/java/chapters/configuration/sample1.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('sample1');">View as .grovvy</span>
-<pre class="prettyprint source">
+ <pre id="sample1" class="prettyprint source">
<configuration <b>debug="true"</b>>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
@@ -403,9 +406,10 @@ public class Foo {
configuration file and automatic re-configuraion
(logback-examples/src/main/java/chapters/configuration/scan1.xml)</em>
-<pre class="prettyprint source">
+ <span class="asGroovy" onclick="return asGroovy('scan1');">View as .grovvy</span>
+<pre id="scan1" class="prettyprint source">
<configuration <b>scan="true"</b>>
- ...
+ ...
</configuration> </pre>
@@ -419,8 +423,8 @@ public class Foo {
<em>Example: Specifying a different
scanning period
(logback-examples/src/main/java/chapters/configuration/scan2.xml)</em>
-
-<pre class="prettyprint source">
+ <span class="asGroovy" onclick="return asGroovy('scan2');">View as .grovvy</span>
+ <pre id="scan2" class="prettyprint source">
<configuration scan="true" <b>scanPeriod="30 seconds"</b> >
...
</configuration> </pre>
@@ -605,9 +609,11 @@ public class MyApp3 {
<p>It is also possible to register one or more status listeners
within a configuration file. Here is an example.</p>
- <p><em>Example: Registering a status listener (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</em></p>
+ <p><em>Example: Registering a status listener
+ (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</em></p>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">View as .grovvy</span>
+ <pre id="onConsoleStatusListener" class="prettyprint source"><configuration>
<b><statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /></b>
... the rest of the configuration file
@@ -761,8 +767,11 @@ public class MyApp3 {
shows how to achieve that.
</p>
-<em>Example: Setting the level of a logger (logback-examples/src/main/java/chapters/configuration/sample2.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: Setting the level of a logger
+ (logback-examples/src/main/java/chapters/configuration/sample2.xml)</em>
+
+ <span class="asGroovy" onclick="return asGroovy('sample2');">View as .grovvy</span>
+ <pre id="sample2" class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
@@ -799,8 +808,11 @@ public class MyApp3 {
of the <em>chapters.configuration.Foo</em> logger to <code>DEBUG</code>.
</p>
-<em>Example: Setting the level of multiple loggers (logback-examples/src/main/java/chapters/configuration/sample3.xml)</em>
-<pre class="source prettyprint"><configuration>
+ <em>Example: Setting the level of multiple loggers
+ (logback-examples/src/main/java/chapters/configuration/sample3.xml)</em>
+
+ <span class="asGroovy" onclick="return asGroovy('sample3');">View as .grovvy</span>
+ <pre id="sample3" class="source prettyprint"><configuration>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
@@ -880,7 +892,8 @@ public class MyApp3 {
<em>Example: Logger level sample
(logback-examples/src/main/java/chapters/configuration/sample4.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('sample4');">View as .grovvy</span>
+ <pre id="sample4" class="prettyprint source"><configuration>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
@@ -1002,8 +1015,10 @@ public class MyApp3 {
configuration file illustrates:
</p>
-<em>Example: Multiple loggers (logback-examples/src/main/java/chapters/configuration/multiple.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: Multiple loggers
+ (logback-examples/src/main/java/chapters/configuration/multiple.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('multiple');">View as .grovvy</span>
+ <pre id="multiple" class="prettyprint source"><configuration>
<appender name="<b>FILE</b>" class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
@@ -1056,7 +1071,9 @@ public class MyApp3 {
<em>Example: Duplicate appender
(logback-examples/src/main/java/chapters/configuration/duplicate.xml)</em>
-<pre class="prettyprint source"><configuration>
+
+ <span class="asGroovy" onclick="return asGroovy('duplicate');">View as .grovvy</span>
+ <pre id="duplicate" class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
@@ -1102,7 +1119,8 @@ public class MyApp3 {
<em>Example: Multiple appender
(logback-examples/src/main/java/chapters/configuration/restricted.xml)</em>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('restricted');">View as .grovvy</span>
+ <pre id="restricted" class="prettyprint source"><configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
@@ -1127,9 +1145,9 @@ public class MyApp3 {
</configuration></pre>
<p>In this example, the console appender will log all the messages
- (for all loggers in the system) whereas only logging request
- originating from loggers <em>chapters.configuration</em> and below go into the
- <em>myApp.log</em> file.
+ (for all loggers in the system) whereas only logging requests
+ originating from the <em>chapters.configuration</em> logger and its
+ children will go into the <em>myApp.log</em> file.
</p>
<h4>
@@ -1145,8 +1163,11 @@ public class MyApp3 {
of the tree.
</p>
-<em>Example: Additivity flag (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: Additivity flag
+ (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</em>
+
+ <span class="asGroovy" onclick="return asGroovy('additivityFlag');">View as .grovvy</span>
+ <pre id="additivityFlag" class="prettyprint source"><configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>foo.log</file>
@@ -1200,7 +1221,9 @@ public class MyApp3 {
<em>Example: Set the context name and display it
(logback-examples/src/main/java/chapters/configuration/contextName.xml)</em>
- <pre class="prettyprint source"><configuration>
+
+ <span class="asGroovy" onclick="return asGroovy('contextName');">View as .grovvy</span>
+ <pre id="contextName" class="prettyprint source"><configuration>
<b><contextName>myAppName</contextName></b>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
@@ -1255,7 +1278,8 @@ public class MyApp3 {
(logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml)
</em>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('variableSubstitution1');">View as .grovvy</span>
+ <pre id="variableSubstitution1" class="prettyprint source"><configuration>
<b><property name="USER_HOME" value="/home/sebastien" /></b>
@@ -1283,8 +1307,8 @@ public class MyApp3 {
<em>Example: System Variable substitution
(logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml)
</em>
-
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('variableSubstitution2');">View as .grovvy</span>
+ <pre id="variableSubstitution2" class="prettyprint source"><configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<b><file>${USER_HOME}/myApp.log</file></b>
diff --git a/logback-site/src/site/pages/manual/filters.html b/logback-site/src/site/pages/manual/filters.html
index 43d5e82..5e49139 100644
--- a/logback-site/src/site/pages/manual/filters.html
+++ b/logback-site/src/site/pages/manual/filters.html
@@ -15,6 +15,7 @@
<script type="text/javascript">prefix='../';</script>
<script type="text/javascript" src="../js/prettify.js"></script>
<script src="../templates/header.js" type="text/javascript"></script>
+ <script type="text/javascript" src="../js/dsl.js"></script>
<div id="left">
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="../templates/left.js" type="text/javascript"></script>
@@ -105,8 +106,9 @@
events, the value NEUTRAL is returned.
</p>
-<em>Example 6.<span class="autoEx"/>: Basic custom filter (<a href="../xref/chapters/filters/SampleFilter.html">logback-examples/src/main/java/chapters/filters/SampleFilter.java</a>)</em>
-<pre class="prettyprint source">package chapters.filters;
+ <em>Example: Basic custom filter (<a
+ href="../xref/chapters/filters/SampleFilter.html">logback-examples/src/main/java/chapters/filters/SampleFilter.java</a>)</em>
+ <pre class="prettyprint source">package chapters.filters;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
@@ -128,8 +130,10 @@ public class SampleFilter extends Filter>ILoggingEvent> {
<code>SampleFilter</code> to a <code>ConsoleAppener</code>.
</p>
-<em>Example 6.<span class="autoEx"/>: SampleFilter configuration (logback-examples/src/main/java/chapters/filters/SampleFilterConfig.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: SampleFilter configuration
+ (logback-examples/src/main/java/chapters/filters/SampleFilterConfig.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('SampleFilterConfig');">View as .grovvy</span>
+ <pre id="SampleFilterConfig" class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<b><filter class="chapters.filters.SampleFilter" /></b>
@@ -183,8 +187,10 @@ public class SampleFilter extends Filter>ILoggingEvent> {
configuration file.
</p>
-<em>Example 6.<span class="autoEx"/>: Sample LevelFilter configuration (logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: Sample LevelFilter configuration
+ (logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('levelFilterConfig');">View as .grovvy</span>
+ <pre id="levelFilterConfig" class="prettyprint source"><configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<b><filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
@@ -214,8 +220,10 @@ public class SampleFilter extends Filter>ILoggingEvent> {
configuration file.
</p>
-<em>Example 6.<span class="autoEx"/>: Sample ThresholdFilter configuration (logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: Sample ThresholdFilter configuration
+ (logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('thresholdFilterConfig');">View as .grovvy</span>
+ <pre id="thresholdFilterConfig" class="prettyprint source"><configuration>
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
<!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
@@ -294,8 +302,9 @@ public class SampleFilter extends Filter>ILoggingEvent> {
<p>Here is a more complete example.</p>
-<pre class="prettyprint source"><configuration>
-
+ <span class="asGroovy" onclick="return asGroovy('GEventEvaluator');">View as .grovvy</span>
+ <pre id="GEventEvaluator" class="prettyprint source"><configuration>
+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<b><filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
@@ -506,9 +515,11 @@ public class SampleFilter extends Filter>ILoggingEvent> {
<p>Here is a concrete example.</p>
-<em>Example 6.<span class="autoEx"/>: Basic event evaluator usage (logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml)</em>
+ <em>Example: Basic event evaluator usage
+ (logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml)</em>
-<pre class="prettyprint source longline"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('basicEventEvaluator');">View as .grovvy</span>
+ <pre id="basicEventEvaluator" class="prettyprint source longline"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<b><filter class="ch.qos.logback.core.filter.EvaluatorFilter">
@@ -614,9 +625,10 @@ java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfigura
<p>An example should clarify the point:</p>
-<em>Example 6.<span class="autoEx"/>: Defining matchers in an event evaluator (logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml)</em>
+ <em>Example: Defining matchers in an event evaluator (logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml)</em>
+ <span class="asGroovy" onclick="return asGroovy('evaluatorWithMatcher');">View as .grovvy</span>
- <pre class="prettyprint source"><configuration debug="true">
+ <pre id="evaluatorWithMatcher" class="prettyprint source"><configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
@@ -703,7 +715,7 @@ java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfigura
slightly more complex filter:
</p>
-<em>Example 6.<span class="autoEx"/>: Basic custom <code>TurboFilter</code> (<a href="../xref/chapters/filters/SampleTurboFilter.html">logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java</a>)</em>
+<em>Example: Basic custom <code>TurboFilter</code> (<a href="../xref/chapters/filters/SampleTurboFilter.html">logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java</a>)</em>
<pre class="prettyprint source">package chapters.filters;
import org.slf4j.Marker;
@@ -768,8 +780,12 @@ public class SampleTurboFilter extends TurboFilter {
created <code>TurboFilter</code>.
</p>
-<em>Example 6.<span class="autoEx"/>: Basic custom <code>TurboFilter</code> configuration (logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: Basic custom <code>TurboFilter</code> configuration
+ (logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml)</em>
+
+ <span class="asGroovy" onclick="return asGroovy('sampleTurboFilterConfig');">View as .grovvy</span>
+
+ <pre id="sampleTurboFilterConfig" class="prettyprint source"><configuration>
<b><turboFilter class="chapters.filters.SampleTurboFilter">
<Marker>sample</Marker>
</turboFilter></b>
@@ -803,9 +819,12 @@ public class SampleTurboFilter extends TurboFilter {
<code>MDCFilter</code> and <code>MarkerFilter</code>.
</p>
-<em>Example 6.<span class="autoEx"/>: <code>MDCFilter</code> and <code>MarkerFilter</code>
-configuration (logback-examples/src/main/java/chapters/filters/turboFilters.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: <code>MDCFilter</code> and <code>MarkerFilter</code>
+ configuration
+ (logback-examples/src/main/java/chapters/filters/turboFilters.xml)</em>
+
+ <span class="asGroovy" onclick="return asGroovy('turboFilters');">View as .grovvy</span>
+ <pre id="turboFilters" class="prettyprint source"><configuration>
<turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
<MDCKey>username</MDCKey>
@@ -930,9 +949,11 @@ logger.debug("Hello {}.", name1);</pre>
</p>
-<em>Example 6.<span class="autoEx"/>: <code>DuplicateMessageFilter</code>
-configuration (logback-examples/src/main/java/chapters/filters/duplicateMessage.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <em>Example: <code>DuplicateMessageFilter</code>
+ configuration (logback-examples/src/main/java/chapters/filters/duplicateMessage.xml)</em>
+
+ <span class="asGroovy" onclick="return asGroovy('duplicateMessage');">View as .grovvy</span>
+ <pre id="duplicateMessage" class="prettyprint source"><configuration>
<b><turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter"/></b>
@@ -1005,7 +1026,7 @@ configuration (logback-examples/src/main/java/chapters/filters/duplicateMessage.
error will be logged:
</p>
-<em>Example 6.<span class="autoEx"/>: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml)</em>
+<em>Example: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
diff --git a/logback-site/src/site/pages/manual/layouts.html b/logback-site/src/site/pages/manual/layouts.html
index ab07ec8..23e5bfc 100644
--- a/logback-site/src/site/pages/manual/layouts.html
+++ b/logback-site/src/site/pages/manual/layouts.html
@@ -14,6 +14,7 @@
<body onload="prettyPrint()">
<script type="text/javascript">prefix='../';</script>
<script type="text/javascript" src="../js/prettify.js"></script>
+ <script type="text/javascript" src="../js/dsl.js"></script>
<script src="../templates/header.js" type="text/javascript"></script>
<div id="left">
<noscript>Please turn on Javascript to view this menu</noscript>
@@ -159,7 +160,8 @@ public class MySampleLayout extends LayoutBase<ILoggingEvent> {
<em>Example: Configuration of MySampleLayout
(logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('sampleLayoutConfig');">View as .grovvy</span>
+<pre id="sampleLayoutConfig" class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<b><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"></b>
@@ -171,7 +173,7 @@ public class MySampleLayout extends LayoutBase<ILoggingEvent> {
<appender-ref ref="STDOUT" />
</root>
</configuration></pre>
-
+
<p>The sample application <a
href="../xref/chapters/layouts/SampleLogging.html">
<code>chapters.layouts.SampleLogging</code></a> configures logback
@@ -266,7 +268,8 @@ public class MySampleLayout2 extends LayoutBase<ILoggingEvent> {
</p>
- <pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('MySampleLayout2');">View as .grovvy</span>
+ <pre id="MySampleLayout2" class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
@@ -1291,7 +1294,11 @@ Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)</pre>
Example: Sample usage of EventEvaluators
(logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml)
</em>
- <pre class="prettyprint source"><configuration>
+
+ <span class="asGroovy" onclick="return asGroovy('callerEvaluatorConfig');">View as .grovvy</span>
+
+
+ <pre id="callerEvaluatorConfig" class="prettyprint source"><configuration>
<b><evaluator name="DISP_CALLER_EVAL">
<expression>logger.contains("chapters.layouts") &amp;&amp; \
message.contains("who calls thee")</expression>
@@ -1598,7 +1605,8 @@ public class MySampleConverter extends ClassicConverter {
new conversion word in the configuration file, as shown below:</p>
<em> Example: Sample Converter Example (src/main/java/chapters/layouts/mySampleConverterConfig.xml)</em>
-<pre class="prettyprint source"><configuration>
+ <span class="asGroovy" onclick="return asGroovy('mySampleConverterConfig');">View as .grovvy</span>
+<pre id="mySampleConverterConfig" class="prettyprint source"><configuration>
<b><conversionRule conversionWord="sample"
converterClass="chapters.layouts.MySampleConverter" /></b>
@@ -1606,7 +1614,7 @@ public class MySampleConverter extends ClassicConverter {
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative [%thread] <b>%sample</b> - %msg%n</pattern>
- </encoder
+ </encoder>
</appender>
<root level="DEBUG">
@@ -1681,7 +1689,8 @@ public class MySampleConverter extends ClassicConverter {
</p>
<em> Example: HTMLLayout Example (src/main/java/chapters/layouts/htmlLayoutConfig1.xml)</em>
-<pre class="prettyprint source"><configuration debug="true">
+<span class="asGroovy" onclick="return asGroovy('htmlLayoutConfig1');">View as .grovvy</span>
+<pre id="htmlLayoutConfig1" class="prettyprint source"><configuration debug="true">
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
@@ -1793,7 +1802,8 @@ public class MySampleConverter extends ClassicConverter {
<p>Here is a sample configuration</p>
<em> Example: Log4jXMLLayout Example (src/main/java/chapters/layouts/log4jXMLLayout.xml)</em>
- <pre class="prettyprint source"><configuration>
+<span class="asGroovy" onclick="return asGroovy('log4jXMLLayout');">View as .grovvy</span>
+ <pre id="log4jXMLLayout" class="prettyprint source"><configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>test.xml</file>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
diff --git a/logback-site/src/site/pages/templates/left.js b/logback-site/src/site/pages/templates/left.js
index b45f09c..dc1400b 100644
--- a/logback-site/src/site/pages/templates/left.js
+++ b/logback-site/src/site/pages/templates/left.js
@@ -16,6 +16,7 @@ document.write('<p class="menu"><a href="http://www.qos.ch/shop/products/trainin
document.write('<p class="menu_header">Online Tools</p>');
document.write('<p class="menu"><a href="http://logback.qos.ch/translator/">log4j.properties Translator</a>');
+document.write('<p class="menu"><a href="http://logback.qos.ch/translator/asGroovy.html">logback.XML to Groovy</a>');
document.write('</p>');
-----------------------------------------------------------------------
Summary of changes:
.../classic/gaffer/AppenderDelegate.groovy} | 20 ++-
.../classic/gaffer/ComponentDelegate.groovy | 146 ++++++++++++++++++++
.../classic/gaffer/ConfigurationDelegate.groovy | 106 +++++++++++----
.../qos/logback/classic/gaffer/Configurator.groovy | 45 +++----
.../ch/qos/logback/classic/filter/LevelFilter.java | 4 +-
.../logback/classic/gaffer/AppenderDelegate.groovy | 32 -----
.../gaffer/ConfigurationDelegateTest.groovy | 34 +++++-
.../logback/classic/gaffer/ConfiguratorTest.groovy | 103 ++++++++++++++
.../src/test/input/gaffer/conversionRule.groovy | 13 ++
.../src/test/input/gaffer/onTheFly.groovy | 9 ++
logback-classic/src/test/input/gaffer/smoke.groovy | 28 ++++
.../qos/logback/classic/ClassicTestConstants.java | 10 +-
.../java/ch/qos/logback/core/util/ContextUtil.java | 17 ++-
.../chapters/layouts/mySampleConverterConfig.xml | 2 +-
logback-site/src/site/pages/css/_print.css | 3 +-
logback-site/src/site/pages/css/common.css | 2 +-
logback-site/src/site/pages/css/screen.css | 22 +++
logback-site/src/site/pages/js/dsl.js | 39 +++++
logback-site/src/site/pages/manual/appenders.html | 141 ++++++++++++--------
.../src/site/pages/manual/configuration.html | 80 +++++++----
logback-site/src/site/pages/manual/filters.html | 69 ++++++----
logback-site/src/site/pages/manual/layouts.html | 26 +++-
logback-site/src/site/pages/templates/left.js | 1 +
23 files changed, 728 insertions(+), 224 deletions(-)
copy logback-classic/src/main/{java/ch/qos/logback/classic/boolex/IEvaluator.java => groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy} (64%)
create mode 100644 logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
delete mode 100644 logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
create mode 100644 logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
create mode 100644 logback-classic/src/test/input/gaffer/conversionRule.groovy
create mode 100644 logback-classic/src/test/input/gaffer/onTheFly.groovy
create mode 100644 logback-classic/src/test/input/gaffer/smoke.groovy
create mode 100644 logback-site/src/site/pages/js/dsl.js
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[JIRA] Created: (LBCORE-153) Replicated log entries with RollingFileAppender
by Silvano Maffeis (JIRA) 14 May '10
by Silvano Maffeis (JIRA) 14 May '10
14 May '10
Replicated log entries with RollingFileAppender
-----------------------------------------------
Key: LBCORE-153
URL: http://jira.qos.ch/browse/LBCORE-153
Project: logback-core
Issue Type: Bug
Components: Rolling
Affects Versions: 0.9.18
Environment: JDK 6, Windows 2008 Server
Reporter: Silvano Maffeis
Assignee: Logback dev list
Priority: Critical
Hi
We use logback 0.9.18 and SLF4J 1.5.10. After monthly log rotation we
noticed that
new log entries were being appended both to the newly created file and also
to the rotated file of the previous
month. Is this a known issue? Below is the config snippet.
Regards,
Silvano
<appender name="XML"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${viperats.logdir}txplugin.xml.log</File>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd
HH:mm:ss}%n%msg------------------------------------------------%n</pattern>
</layout>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${viperats.logdir}/txplugin.xml.log-%d{yyyy-MM}</FileNamePattern>
</rollingPolicy>
<Append>true</Append>
</appender>
--
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
1