From markward.schubert at gmail.com Thu Dec 2 17:17:46 2010
From: markward.schubert at gmail.com (Markward Schubert)
Date: Thu, 2 Dec 2010 17:17:46 +0100
Subject: [logback-dev] GEventEvaluator not started
Message-ID:
Hi!
I am experiencing a problem with the GEventEvaluator. After hours of trying
around with different configurations, I could not get this to work. The
Filter was simply ignored. I even tried 1 == 2 as an expression, but it was
happily logging.
Finally I started my project in debugmode and startet stepping around the
logback code.
Now my question:
Is it possible, that GEventEvaluator misses a call to super.start() in it's
start-method?
EvaluatorFilter in my case returns FilterReply.NEUTRAL in the code-passage
below, as evaluator.isStarted() returns false.
if (!isStarted() || !evaluator.isStarted()) {
return FilterReply.NEUTRAL;
}
Regards,
Markward
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From ceki at qos.ch Thu Dec 2 17:42:45 2010
From: ceki at qos.ch (Ceki Gulcu)
Date: Thu, 02 Dec 2010 17:42:45 +0100
Subject: [logback-dev] GEventEvaluator not started
In-Reply-To:
References:
Message-ID: <4CF7CC85.5020302@qos.ch>
Hi Markward,
The evaluator will refuse to start of it detects an error.
Add the following to the top of your logback-groovy.xml file and check
whether there are any reported errors.
import ch.qos.logback.core.status.OnConsoleStatusListener
// other imports....
statusListener(OnConsoleStatusListener)
// rest of config file...
On 02.12.2010 17:17, Markward Schubert wrote:
> Hi!
>
> I am experiencing a problem with the GEventEvaluator. After hours of
> trying around with different configurations, I could not get this to
> work. The Filter was simply ignored. I even tried 1 == 2 as an
> expression, but it was happily logging.
>
> Finally I started my project in debugmode and startet stepping around
> the logback code.
> Now my question:
>
> Is it possible, that GEventEvaluator misses a call to super.start() in
> it's start-method?
>
> EvaluatorFilter in my case returns FilterReply.NEUTRAL in the
> code-passage below, as evaluator.isStarted() returns false.
>
> if (!isStarted() || !evaluator.isStarted()) {
> return FilterReply.NEUTRAL;
> }
>
>
> Regards,
> Markward
>
>
>
> _______________________________________________
> logback-dev mailing list
> logback-dev at qos.ch
> http://qos.ch/mailman/listinfo/logback-dev
From noreply-jira at qos.ch Mon Dec 6 09:33:51 2010
From: noreply-jira at qos.ch (Denis Bazhenov (JIRA))
Date: Mon, 6 Dec 2010 09:33:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Created: (LBACCESS-18) NPE is case of
desrialized AccessEvent
Message-ID: <1017980597.1291624431265.JavaMail.ceki@pixie>
NPE is case of desrialized AccessEvent
--------------------------------------
Key: LBACCESS-18
URL: http://jira.qos.ch/browse/LBACCESS-18
Project: logback-access
Issue Type: Bug
Affects Versions: 0.9.26
Environment: Sun Java HotSpot(TM) 64-Bit Server VM (build 16.2-b04, mixed mode)
CentOS Linux 2.6.18-164.el5 #1 SMP Thu Sep 3 03:28:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
Reporter: Denis Bazhenov
Assignee: Logback dev list
I'm trying to use SimpleSocketServer (from logback-access) for remote logging of AccessEvent's. The problem I faced is following. When object get deserialized in SocketNode on line 64 it has no httpRequest (it's simply null). There is debugger dump of event:
event = instance of ch.qos.logback.access.spi.AccessEvent(id=932)
Thread-1[1] dump event
event = {
serialVersionUID: 866718993618836343
NA: "-"
NA_STRING_ARRAY: instance of java.lang.String[1] (id=914)
EMPTY: ""
SENTINEL: -1
httpRequest: null
httpResponse: null
requestURI: "/"
requestURL: "GET / HTTP/1.1"
remoteHost: "192.168.20.179"
remoteUser: null
remoteAddr: "192.168.20.179"
protocol: "HTTP/1.1"
method: "GET"
serverName: "jetty-test"
requestContent: ""
responseContent: ""
requestHeaderMap: instance of java.util.TreeMap(id=938)
requestParameterMap: instance of java.util.HashMap(id=939)
responseHeaderMap: instance of java.util.HashMap(id=940)
contentLength: 1288
statusCode: 503
localPort: 8080
serverAdapter: null
timeStamp: 1291621192027
}
So later this gives me NPE in AccessEvent.buildRequestHeaderMap().
I have following logback-access.xml for client
logs.vfarm.loc6000100true/var/log/jetty/access.logaccess.%d{yyyy-MM-dd}.log.zipcombined
So logs are written locally (sucessfully) and sent over network to logs.vfarm.loc. On logs.vfarm.loc I have running SimpleSocketServer:
java -cp jetty-6.1.24.jar:\
servlet-api-2.5.jar:\
logback-access-0.9.26.jar:\
slf4j-api-1.6.1.jar:\
logback-core-0.9.26.jar \
ch.qos.logback.access.net.SimpleSocketServer 6000 access.xml
with following access.xml
combined
I think this issue is closely related to LBACCESS-6, but it's still reproducible.
--
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
From noreply-jira at qos.ch Mon Dec 6 15:35:51 2010
From: noreply-jira at qos.ch (Eric Estievenart (JIRA))
Date: Mon, 6 Dec 2010 15:35:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Created: (LBACCESS-19) Cannot specify config
file relative to catalina home
Message-ID: <564216319.1291646151255.JavaMail.ceki@pixie>
Cannot specify config file relative to catalina home
----------------------------------------------------
Key: LBACCESS-19
URL: http://jira.qos.ch/browse/LBACCESS-19
Project: logback-access
Issue Type: Bug
Affects Versions: 0.9.26
Environment: all
Reporter: Eric Estievenart
Assignee: Logback dev list
Priority: Trivial
There is no way to refer to catalina home when specifying the filename of a logback valve.
What I would like to do is something like:
The only way for now is to specify an absolute path, which is not very convenient.
The system properties in the filename should be expanded in LogbackValve.start().
--
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
From noreply-jira at qos.ch Mon Dec 6 15:40:51 2010
From: noreply-jira at qos.ch (Eric Estievenart (JIRA))
Date: Mon, 6 Dec 2010 15:40:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Created: (LBACCESS-20) [DOC]
logback-access.html example uses obsolete in (in
access.html)
Message-ID: <276117259.1291646451273.JavaMail.ceki@pixie>
[DOC] logback-access.html example uses obsolete in (in access.html)
---------------------------------------------------------------------------------------
Key: LBACCESS-20
URL: http://jira.qos.ch/browse/LBACCESS-20
Project: logback-access
Issue Type: Bug
Affects Versions: 0.9.26
Environment: -
Reporter: Eric Estievenart
Assignee: Logback dev list
Priority: Trivial
http://logback.qos.ch/access.html, in example 1:
------ should be ----------
Cheers.
--
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
From noreply-jira at qos.ch Mon Dec 6 16:01:51 2010
From: noreply-jira at qos.ch (Eric Estievenart (JIRA))
Date: Mon, 6 Dec 2010 16:01:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Commented: (LBACCESS-19) Cannot specify config
file relative to catalina home
In-Reply-To: <564216319.1291646151255.JavaMail.ceki@pixie>
Message-ID: <481861944.1291647711341.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBACCESS-19?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11908#action_11908 ]
Eric Estievenart commented on LBACCESS-19:
------------------------------------------
In fact it seems to work if specifying a file relative to catalina home (at least in 0.9.26/linux/tomcat 6.0.29):
filename="conf/logback-access-test.xml".
Maybe a small line in the doc could say that ?
Thx.
> Cannot specify config file relative to catalina home
> ----------------------------------------------------
>
> Key: LBACCESS-19
> URL: http://jira.qos.ch/browse/LBACCESS-19
> Project: logback-access
> Issue Type: Bug
> Affects Versions: 0.9.26
> Environment: all
> Reporter: Eric Estievenart
> Assignee: Logback dev list
> Priority: Trivial
>
> There is no way to refer to catalina home when specifying the filename of a logback valve.
> What I would like to do is something like:
> filename="${catalina.home}/conf/logback-access-test.xml"
> />
> The only way for now is to specify an absolute path, which is not very convenient.
> The system properties in the filename should be expanded in LogbackValve.start().
--
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
From noreply-jira at qos.ch Mon Dec 6 16:42:51 2010
From: noreply-jira at qos.ch (Eric Estievenart (JIRA))
Date: Mon, 6 Dec 2010 16:42:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Created: (LBACCESS-21) Report the request
duration in logback-access
Message-ID: <651187727.1291650171252.JavaMail.ceki@pixie>
Report the request duration in logback-access
---------------------------------------------
Key: LBACCESS-21
URL: http://jira.qos.ch/browse/LBACCESS-21
Project: logback-access
Issue Type: Improvement
Affects Versions: 0.9.26
Environment: any
Reporter: Eric Estievenart
Assignee: Logback dev list
It would be great if the access valve (and corresponding in jetty/other) also stored the processing duration
of the request within the container.
For example add a %d field which would return this time in ms.
--
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
From noreply-jira at qos.ch Tue Dec 7 07:59:52 2010
From: noreply-jira at qos.ch (Denis Bazhenov (JIRA))
Date: Tue, 7 Dec 2010 07:59:52 +0100 (CET)
Subject: [logback-dev] [JIRA] Updated: (LBACCESS-18) NPE is case of
desrialized AccessEvent
In-Reply-To: <1017980597.1291624431265.JavaMail.ceki@pixie>
Message-ID: <2109604416.1291705192521.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBACCESS-18?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Denis Bazhenov updated LBACCESS-18:
-----------------------------------
Attachment: LBACCESS-18.patch
I created a simple patch. It's check for httpRequest == null and returns early. This patch makes SocketAppeder works in my installation
> NPE is case of desrialized AccessEvent
> --------------------------------------
>
> Key: LBACCESS-18
> URL: http://jira.qos.ch/browse/LBACCESS-18
> Project: logback-access
> Issue Type: Bug
> Affects Versions: 0.9.26
> Environment: Sun Java HotSpot(TM) 64-Bit Server VM (build 16.2-b04, mixed mode)
> CentOS Linux 2.6.18-164.el5 #1 SMP Thu Sep 3 03:28:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
> Reporter: Denis Bazhenov
> Assignee: Logback dev list
> Attachments: LBACCESS-18.patch
>
>
> I'm trying to use SimpleSocketServer (from logback-access) for remote logging of AccessEvent's. The problem I faced is following. When object get deserialized in SocketNode on line 64 it has no httpRequest (it's simply null). There is debugger dump of event:
> event = instance of ch.qos.logback.access.spi.AccessEvent(id=932)
> Thread-1[1] dump event
> event = {
> serialVersionUID: 866718993618836343
> NA: "-"
> NA_STRING_ARRAY: instance of java.lang.String[1] (id=914)
> EMPTY: ""
> SENTINEL: -1
> httpRequest: null
> httpResponse: null
> requestURI: "/"
> requestURL: "GET / HTTP/1.1"
> remoteHost: "192.168.20.179"
> remoteUser: null
> remoteAddr: "192.168.20.179"
> protocol: "HTTP/1.1"
> method: "GET"
> serverName: "jetty-test"
> requestContent: ""
> responseContent: ""
> requestHeaderMap: instance of java.util.TreeMap(id=938)
> requestParameterMap: instance of java.util.HashMap(id=939)
> responseHeaderMap: instance of java.util.HashMap(id=940)
> contentLength: 1288
> statusCode: 503
> localPort: 8080
> serverAdapter: null
> timeStamp: 1291621192027
> }
> So later this gives me NPE in AccessEvent.buildRequestHeaderMap().
> I have following logback-access.xml for client
>
>
> logs.vfarm.loc
> 6000
> 100
> true
>
> class="ch.qos.logback.core.rolling.RollingFileAppender">
> /var/log/jetty/access.log
> class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
> access.%d{yyyy-MM-dd}.log.zip
>
>
> combined
>
>
>
>
>
> So logs are written locally (sucessfully) and sent over network to logs.vfarm.loc. On logs.vfarm.loc I have running SimpleSocketServer:
> java -cp jetty-6.1.24.jar:\
> servlet-api-2.5.jar:\
> logback-access-0.9.26.jar:\
> slf4j-api-1.6.1.jar:\
> logback-core-0.9.26.jar \
> ch.qos.logback.access.net.SimpleSocketServer 6000 access.xml
> with following access.xml
>
>
> class="ch.qos.logback.core.ConsoleAppender">
>
> combined
>
>
>
>
>
> I think this issue is closely related to LBACCESS-6, but it's still reproducible.
--
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
From noreply-jira at qos.ch Wed Dec 8 01:43:51 2010
From: noreply-jira at qos.ch (Mats Henrikson (JIRA))
Date: Wed, 8 Dec 2010 01:43:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Created: (LBCORE-183) race condition when
creating log directory in multithreaded environment
Message-ID: <1880974034.1291769031316.JavaMail.ceki@pixie>
race condition when creating log directory in multithreaded environment
-----------------------------------------------------------------------
Key: LBCORE-183
URL: http://jira.qos.ch/browse/LBCORE-183
Project: logback-core
Issue Type: Bug
Components: Other
Affects Versions: 0.9.26
Reporter: Mats Henrikson
Assignee: Logback dev list
Attachments: parent_dirs.patch
There is a race condition when multiple threads are trying to create the same parent log directory in logback:
{noformat}
java.lang.IllegalStateException: /path/to/log/dir/2010/2010_12/2010_12_08/file.log should not have existing parent directory
at ch.qos.logback.core.util.FileUtil.createMissingParentDirectories(FileUtil.java:43) ~[logback-core-0.9.26.jar:na]
at ch.qos.logback.core.FileAppender.openFile(FileAppender.java:156) ~[logback-core-0.9.26.jar:na]
at ch.qos.logback.core.FileAppender.start(FileAppender.java:115) ~[logback-core-0.9.26.jar:na]
[...]
{noformat}
It is completely ok for the check to start if the directory is there and then have the directory appear when we actually come around to creating it. This is because you may have multiple threads wanting to log to the same directory, and if they try to create the dir at the same time one will succeed and one will have it already created. This happens for instance in the case above where a new dir is created at midnight every day, and two threads log at the same time.
Will attach a patch that fixes the problem.
--
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
From noreply-jira at qos.ch Wed Dec 8 01:43:51 2010
From: noreply-jira at qos.ch (Mats Henrikson (JIRA))
Date: Wed, 8 Dec 2010 01:43:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Updated: (LBCORE-183) race condition when
creating log directory in multithreaded environment
In-Reply-To: <1880974034.1291769031316.JavaMail.ceki@pixie>
Message-ID: <799003850.1291769031532.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBCORE-183?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Mats Henrikson updated LBCORE-183:
----------------------------------
Attachment: parent_dirs.patch
> race condition when creating log directory in multithreaded environment
> -----------------------------------------------------------------------
>
> Key: LBCORE-183
> URL: http://jira.qos.ch/browse/LBCORE-183
> Project: logback-core
> Issue Type: Bug
> Components: Other
> Affects Versions: 0.9.26
> Reporter: Mats Henrikson
> Assignee: Logback dev list
> Attachments: parent_dirs.patch
>
>
> There is a race condition when multiple threads are trying to create the same parent log directory in logback:
> {noformat}
> java.lang.IllegalStateException: /path/to/log/dir/2010/2010_12/2010_12_08/file.log should not have existing parent directory
> at ch.qos.logback.core.util.FileUtil.createMissingParentDirectories(FileUtil.java:43) ~[logback-core-0.9.26.jar:na]
> at ch.qos.logback.core.FileAppender.openFile(FileAppender.java:156) ~[logback-core-0.9.26.jar:na]
> at ch.qos.logback.core.FileAppender.start(FileAppender.java:115) ~[logback-core-0.9.26.jar:na]
> [...]
> {noformat}
> It is completely ok for the check to start if the directory is there and then have the directory appear when we actually come around to creating it. This is because you may have multiple threads wanting to log to the same directory, and if they try to create the dir at the same time one will succeed and one will have it already created. This happens for instance in the case above where a new dir is created at midnight every day, and two threads log at the same time.
> Will attach a patch that fixes the problem.
--
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
From noreply-jira at qos.ch Wed Dec 8 02:01:51 2010
From: noreply-jira at qos.ch (Denis Bazhenov (JIRA))
Date: Wed, 8 Dec 2010 02:01:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Updated: (LBACCESS-18) NPE is case of
desrialized AccessEvent
In-Reply-To: <1017980597.1291624431265.JavaMail.ceki@pixie>
Message-ID: <1737054732.1291770111299.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBACCESS-18?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Denis Bazhenov updated LBACCESS-18:
-----------------------------------
Attachment: (was: LBACCESS-18.patch)
> NPE is case of desrialized AccessEvent
> --------------------------------------
>
> Key: LBACCESS-18
> URL: http://jira.qos.ch/browse/LBACCESS-18
> Project: logback-access
> Issue Type: Bug
> Affects Versions: 0.9.26
> Environment: Sun Java HotSpot(TM) 64-Bit Server VM (build 16.2-b04, mixed mode)
> CentOS Linux 2.6.18-164.el5 #1 SMP Thu Sep 3 03:28:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
> Reporter: Denis Bazhenov
> Assignee: Logback dev list
> Attachments: LBACCESS-18.patch
>
>
> I'm trying to use SimpleSocketServer (from logback-access) for remote logging of AccessEvent's. The problem I faced is following. When object get deserialized in SocketNode on line 64 it has no httpRequest (it's simply null). There is debugger dump of event:
> event = instance of ch.qos.logback.access.spi.AccessEvent(id=932)
> Thread-1[1] dump event
> event = {
> serialVersionUID: 866718993618836343
> NA: "-"
> NA_STRING_ARRAY: instance of java.lang.String[1] (id=914)
> EMPTY: ""
> SENTINEL: -1
> httpRequest: null
> httpResponse: null
> requestURI: "/"
> requestURL: "GET / HTTP/1.1"
> remoteHost: "192.168.20.179"
> remoteUser: null
> remoteAddr: "192.168.20.179"
> protocol: "HTTP/1.1"
> method: "GET"
> serverName: "jetty-test"
> requestContent: ""
> responseContent: ""
> requestHeaderMap: instance of java.util.TreeMap(id=938)
> requestParameterMap: instance of java.util.HashMap(id=939)
> responseHeaderMap: instance of java.util.HashMap(id=940)
> contentLength: 1288
> statusCode: 503
> localPort: 8080
> serverAdapter: null
> timeStamp: 1291621192027
> }
> So later this gives me NPE in AccessEvent.buildRequestHeaderMap().
> I have following logback-access.xml for client
>
>
> logs.vfarm.loc
> 6000
> 100
> true
>
> class="ch.qos.logback.core.rolling.RollingFileAppender">
> /var/log/jetty/access.log
> class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
> access.%d{yyyy-MM-dd}.log.zip
>
>
> combined
>
>
>
>
>
> So logs are written locally (sucessfully) and sent over network to logs.vfarm.loc. On logs.vfarm.loc I have running SimpleSocketServer:
> java -cp jetty-6.1.24.jar:\
> servlet-api-2.5.jar:\
> logback-access-0.9.26.jar:\
> slf4j-api-1.6.1.jar:\
> logback-core-0.9.26.jar \
> ch.qos.logback.access.net.SimpleSocketServer 6000 access.xml
> with following access.xml
>
>
> class="ch.qos.logback.core.ConsoleAppender">
>
> combined
>
>
>
>
>
> I think this issue is closely related to LBACCESS-6, but it's still reproducible.
--
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
From noreply-jira at qos.ch Wed Dec 8 02:01:51 2010
From: noreply-jira at qos.ch (Denis Bazhenov (JIRA))
Date: Wed, 8 Dec 2010 02:01:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Updated: (LBACCESS-18) NPE is case of
desrialized AccessEvent
In-Reply-To: <1017980597.1291624431265.JavaMail.ceki@pixie>
Message-ID: <288942942.1291770111458.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBACCESS-18?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Denis Bazhenov updated LBACCESS-18:
-----------------------------------
Attachment: LBACCESS-18.patch
update a patch. fix another similar issue
> NPE is case of desrialized AccessEvent
> --------------------------------------
>
> Key: LBACCESS-18
> URL: http://jira.qos.ch/browse/LBACCESS-18
> Project: logback-access
> Issue Type: Bug
> Affects Versions: 0.9.26
> Environment: Sun Java HotSpot(TM) 64-Bit Server VM (build 16.2-b04, mixed mode)
> CentOS Linux 2.6.18-164.el5 #1 SMP Thu Sep 3 03:28:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
> Reporter: Denis Bazhenov
> Assignee: Logback dev list
> Attachments: LBACCESS-18.patch
>
>
> I'm trying to use SimpleSocketServer (from logback-access) for remote logging of AccessEvent's. The problem I faced is following. When object get deserialized in SocketNode on line 64 it has no httpRequest (it's simply null). There is debugger dump of event:
> event = instance of ch.qos.logback.access.spi.AccessEvent(id=932)
> Thread-1[1] dump event
> event = {
> serialVersionUID: 866718993618836343
> NA: "-"
> NA_STRING_ARRAY: instance of java.lang.String[1] (id=914)
> EMPTY: ""
> SENTINEL: -1
> httpRequest: null
> httpResponse: null
> requestURI: "/"
> requestURL: "GET / HTTP/1.1"
> remoteHost: "192.168.20.179"
> remoteUser: null
> remoteAddr: "192.168.20.179"
> protocol: "HTTP/1.1"
> method: "GET"
> serverName: "jetty-test"
> requestContent: ""
> responseContent: ""
> requestHeaderMap: instance of java.util.TreeMap(id=938)
> requestParameterMap: instance of java.util.HashMap(id=939)
> responseHeaderMap: instance of java.util.HashMap(id=940)
> contentLength: 1288
> statusCode: 503
> localPort: 8080
> serverAdapter: null
> timeStamp: 1291621192027
> }
> So later this gives me NPE in AccessEvent.buildRequestHeaderMap().
> I have following logback-access.xml for client
>
>
> logs.vfarm.loc
> 6000
> 100
> true
>
> class="ch.qos.logback.core.rolling.RollingFileAppender">
> /var/log/jetty/access.log
> class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
> access.%d{yyyy-MM-dd}.log.zip
>
>
> combined
>
>
>
>
>
> So logs are written locally (sucessfully) and sent over network to logs.vfarm.loc. On logs.vfarm.loc I have running SimpleSocketServer:
> java -cp jetty-6.1.24.jar:\
> servlet-api-2.5.jar:\
> logback-access-0.9.26.jar:\
> slf4j-api-1.6.1.jar:\
> logback-core-0.9.26.jar \
> ch.qos.logback.access.net.SimpleSocketServer 6000 access.xml
> with following access.xml
>
>
> class="ch.qos.logback.core.ConsoleAppender">
>
> combined
>
>
>
>
>
> I think this issue is closely related to LBACCESS-6, but it's still reproducible.
--
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
From noreply-jira at qos.ch Wed Dec 8 02:25:51 2010
From: noreply-jira at qos.ch (Ralph Goers (JIRA))
Date: Wed, 8 Dec 2010 02:25:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Commented: (LBCORE-183) race condition when
creating log directory in multithreaded environment
In-Reply-To: <1880974034.1291769031316.JavaMail.ceki@pixie>
Message-ID: <774394791.1291771551284.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBCORE-183?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11911#action_11911 ]
Ralph Goers commented on LBCORE-183:
------------------------------------
Not that your patch is bad, but your description has to be incorrect. FileAppender.openFile() synchronizes on a lock so there is no way you can have a race from the same appender calling createMissingParentDirectories. From what I can see, the only way this can occur is if two different appenders are creating files in the same directory.
> race condition when creating log directory in multithreaded environment
> -----------------------------------------------------------------------
>
> Key: LBCORE-183
> URL: http://jira.qos.ch/browse/LBCORE-183
> Project: logback-core
> Issue Type: Bug
> Components: Other
> Affects Versions: 0.9.26
> Reporter: Mats Henrikson
> Assignee: Logback dev list
> Attachments: parent_dirs.patch
>
>
> There is a race condition when multiple threads are trying to create the same parent log directory in logback:
> {noformat}
> java.lang.IllegalStateException: /path/to/log/dir/2010/2010_12/2010_12_08/file.log should not have existing parent directory
> at ch.qos.logback.core.util.FileUtil.createMissingParentDirectories(FileUtil.java:43) ~[logback-core-0.9.26.jar:na]
> at ch.qos.logback.core.FileAppender.openFile(FileAppender.java:156) ~[logback-core-0.9.26.jar:na]
> at ch.qos.logback.core.FileAppender.start(FileAppender.java:115) ~[logback-core-0.9.26.jar:na]
> [...]
> {noformat}
> It is completely ok for the check to start if the directory is there and then have the directory appear when we actually come around to creating it. This is because you may have multiple threads wanting to log to the same directory, and if they try to create the dir at the same time one will succeed and one will have it already created. This happens for instance in the case above where a new dir is created at midnight every day, and two threads log at the same time.
> Will attach a patch that fixes the problem.
--
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
From noreply-jira at qos.ch Wed Dec 8 02:39:51 2010
From: noreply-jira at qos.ch (Mats Henrikson (JIRA))
Date: Wed, 8 Dec 2010 02:39:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Commented: (LBCORE-183) race condition when
creating log directory in multithreaded environment
In-Reply-To: <1880974034.1291769031316.JavaMail.ceki@pixie>
Message-ID: <773347310.1291772391266.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBCORE-183?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11912#action_11912 ]
Mats Henrikson commented on LBCORE-183:
---------------------------------------
I wouldn't go as far as calling it incorrect, but I guess I should indeed have included appenders.
Yes, it is indeed multiple appenders being logged to by different threads. If the appenders are logging to different files in the same directory then this can occur if the directory needs to be created. We see this pretty regularly.
> race condition when creating log directory in multithreaded environment
> -----------------------------------------------------------------------
>
> Key: LBCORE-183
> URL: http://jira.qos.ch/browse/LBCORE-183
> Project: logback-core
> Issue Type: Bug
> Components: Other
> Affects Versions: 0.9.26
> Reporter: Mats Henrikson
> Assignee: Logback dev list
> Attachments: parent_dirs.patch
>
>
> There is a race condition when multiple threads are trying to create the same parent log directory in logback:
> {noformat}
> java.lang.IllegalStateException: /path/to/log/dir/2010/2010_12/2010_12_08/file.log should not have existing parent directory
> at ch.qos.logback.core.util.FileUtil.createMissingParentDirectories(FileUtil.java:43) ~[logback-core-0.9.26.jar:na]
> at ch.qos.logback.core.FileAppender.openFile(FileAppender.java:156) ~[logback-core-0.9.26.jar:na]
> at ch.qos.logback.core.FileAppender.start(FileAppender.java:115) ~[logback-core-0.9.26.jar:na]
> [...]
> {noformat}
> It is completely ok for the check to start if the directory is there and then have the directory appear when we actually come around to creating it. This is because you may have multiple threads wanting to log to the same directory, and if they try to create the dir at the same time one will succeed and one will have it already created. This happens for instance in the case above where a new dir is created at midnight every day, and two threads log at the same time.
> Will attach a patch that fixes the problem.
--
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
From noreply-jira at qos.ch Thu Dec 9 11:05:52 2010
From: noreply-jira at qos.ch (Dieter Mueller (JIRA))
Date: Thu, 9 Dec 2010 11:05:52 +0100 (CET)
Subject: [logback-dev] [JIRA] Commented: (LBCORE-147) RollingPolicy
MaxHistory not deleting old files
In-Reply-To: <1427078273.1269441196428.JavaMail.ceki@pixie>
Message-ID: <961942434.1291889152262.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBCORE-147?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11913#action_11913 ]
Dieter Mueller commented on LBCORE-147:
---------------------------------------
I just tested it with current version 0.9.26 and verified the bug.
config:
foo-%d{yyyy-MM-dd}.%i.log.zip420MB
But the main key is, that the application did not run for some days:
e.g. Today (09.12.) I had logfiles from 1.12, 2.12., 3.12, 4.12. 5.12., 6.12.
When I started the app, then the logfile from 4.12. (older than 4 days) was deleted, but the older ones (1.12. 2.12., 3.12)
were not deleted.
It seems, that logback calculates the ONE day to be deleted. It does not look back into the past, which is reasonable to me,
because how far it should look back?
regards,
Dieter Mueller
> RollingPolicy MaxHistory not deleting old files
> -----------------------------------------------
>
> Key: LBCORE-147
> URL: http://jira.qos.ch/browse/LBCORE-147
> Project: logback-core
> Issue Type: Bug
> Components: Rolling
> Affects Versions: 0.9.18
> Environment: linux 2.6.18 64bits apache-tomcat-6.0.20 java/jre1.6.0_18
> Reporter: Rafael Diaz Maurin
> Assignee: Ceki Gulcu
>
> The MaxHistory does not do the trick : the old files are not deleted at all :
> cat logging.xml
>
> /shibboleth-idp/logs/idp-access.log
> false
> true
>
> /shibboleth-idp/logs/old/idp-access-%d{yyyy-MM-dd_HH-mm}.log.gz
> 3
>
>
> %msg%n
>
>
--
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
From noreply-jira at qos.ch Thu Dec 9 11:24:51 2010
From: noreply-jira at qos.ch (Dieter Mueller (JIRA))
Date: Thu, 9 Dec 2010 11:24:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Commented: (LBCORE-147) RollingPolicy
MaxHistory not deleting old files
In-Reply-To: <1427078273.1269441196428.JavaMail.ceki@pixie>
Message-ID: <935760003.1291890291285.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBCORE-147?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11914#action_11914 ]
Dieter Mueller commented on LBCORE-147:
---------------------------------------
I wrote:
>It seems, that logback calculates the ONE day to be deleted. It does not look back into the past, which is reasonable to me,
>because how far it should look back?
Perhaps a simple but unorthodox way would be, if there is a list (e.g. property-file) of created log files is maintained and
persisted by logback. On every rollover the list is loaded and checked for old, deleteable files.
I assume, the list would not be that big, so that there should be no big performance impact.
One additional sugar piece would be, that if the filename patten (e.g. directory structure) is changed between a run of
the application, logback will still be able, to delete an old logfile, which does not follow the new (changed) file name pattern.
On the other hand, concurent access to this file via threads or several VMs will have to be synchronized?
Dieter Mueller
> RollingPolicy MaxHistory not deleting old files
> -----------------------------------------------
>
> Key: LBCORE-147
> URL: http://jira.qos.ch/browse/LBCORE-147
> Project: logback-core
> Issue Type: Bug
> Components: Rolling
> Affects Versions: 0.9.18
> Environment: linux 2.6.18 64bits apache-tomcat-6.0.20 java/jre1.6.0_18
> Reporter: Rafael Diaz Maurin
> Assignee: Ceki Gulcu
>
> The MaxHistory does not do the trick : the old files are not deleted at all :
> cat logging.xml
>
> /shibboleth-idp/logs/idp-access.log
> false
> true
>
> /shibboleth-idp/logs/old/idp-access-%d{yyyy-MM-dd_HH-mm}.log.gz
> 3
>
>
> %msg%n
>
>
--
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
From noreply-jira at qos.ch Sat Dec 11 17:21:52 2010
From: noreply-jira at qos.ch (Eric Estievenart (JIRA))
Date: Sat, 11 Dec 2010 17:21:52 +0100 (CET)
Subject: [logback-dev] [JIRA] Created: (LBCLASSIC-235) Should log an error
if -Dlogback.configurationFile but not found, and not attempt default config
Message-ID: <1385607978.1292084512352.JavaMail.ceki@pixie>
Should log an error if -Dlogback.configurationFile but not found, and not attempt default config
------------------------------------------------------------------------------------------------
Key: LBCLASSIC-235
URL: http://jira.qos.ch/browse/LBCLASSIC-235
Project: logback-classic
Issue Type: Bug
Affects Versions: 0.9.26
Reporter: Eric Estievenart
Assignee: Logback dev list
$ java -Dlogback.configurationFile=missingfile.xml -cp .... MyClass
>> no output is generated
A status dump says:
16:14:01,778 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [missingfile.xml]
16:14:01,779 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
16:14:01,779 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
16:14:01,780 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
16:14:01,786 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Setting up default configuration.
First, logback should issue an error saying that the explicitely selected 'missingfile' was not found.
Then I don't thing that it should try to load default config files, since one has been requested by the user.
--
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
From noreply-jira at qos.ch Sat Dec 11 17:23:51 2010
From: noreply-jira at qos.ch (Eric Estievenart (JIRA))
Date: Sat, 11 Dec 2010 17:23:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Created: (LBCLASSIC-236) Provide a way to tell
wether logback has defaulted to a default configuration.
Message-ID: <433482092.1292084631247.JavaMail.ceki@pixie>
Provide a way to tell wether logback has defaulted to a default configuration.
------------------------------------------------------------------------------
Key: LBCLASSIC-236
URL: http://jira.qos.ch/browse/LBCLASSIC-236
Project: logback-classic
Issue Type: Improvement
Affects Versions: 0.9.26
Reporter: Eric Estievenart
Assignee: Logback dev list
Priority: Minor
There is no way to know if logback is using its default configuration or one supplied explicitly or found in resources.
LoggerContext.getName() returns "default" for the default config or for one which has no name given.
--
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
From noreply-jira at qos.ch Sun Dec 12 18:54:52 2010
From: noreply-jira at qos.ch (Eric Estievenart (JIRA))
Date: Sun, 12 Dec 2010 18:54:52 +0100 (CET)
Subject: [logback-dev] [JIRA] Created: (LBCORE-184) FileAppender should
permit lazy file creation
Message-ID: <1668306216.1292176492303.JavaMail.ceki@pixie>
FileAppender should permit lazy file creation
---------------------------------------------
Key: LBCORE-184
URL: http://jira.qos.ch/browse/LBCORE-184
Project: logback-core
Issue Type: New Feature
Components: Appender
Affects Versions: 0.9.26
Reporter: Eric Estievenart
Assignee: Logback dev list
There should be an option to allow lazy file creation, so that the files are created only when an
event has to be logged into it, and not when the appender starts.
The main idea behind that is that I dislike seeing files like ERROR.log (or even worse CRASH.log !) in the log
folders, even if their size is zero. And these files are probably even rolled over (at least with time based policy),
which can generate many (empty and useless) files with frightening names.
I think that something like
true
...
would be very convenient, as well as a way to globally set all file based appenders lazy (or not) at once:
(or whatever people may find more convenient, maybe )
(because you may not want to add that on a dozen or more file appenders).
This applies to all file appenders, including rolling ones, and maybe others ?
BTW, the more I use logback the more impressed I am.
You deserve a gold medal for your good job guys ! (and I don't give so many)
--
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
From git-noreply at pixie.qos.ch Mon Dec 13 17:17:23 2010
From: git-noreply at pixie.qos.ch (added by portage for gitosis-gentoo)
Date: Mon, 13 Dec 2010 17:17:23 +0100 (CET)
Subject: [logback-dev] [GIT] Logback: the generic, reliable,
fast and flexible logging framework. branch, master,
updated. v_0.9.25-41-gfc45086
Message-ID: <20101213161724.5E80A31702C@pixie.qos.ch>
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 fc4508616906b773dd9d93d4e0d2c45628d3f7b5 (commit)
from 1c9ce863a577cf5075088eb66ca5353f4de0e209 (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=fc4508616906b773dd9d93d4e0d2c45628d3f7b5
http://github.com/ceki/logback/commit/fc4508616906b773dd9d93d4e0d2c45628d3f7b5
commit fc4508616906b773dd9d93d4e0d2c45628d3f7b5
Author: Ceki Gulcu
Date: Mon Dec 13 17:17:28 2010 +0100
add support for dynamic destination address computation in SMTPAppender
diff --git a/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java b/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
index 40917f3..43590ed 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
@@ -182,5 +182,4 @@ public class PatternLayout extends PatternLayoutBase {
}
super.start();
}
-
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java b/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java
index 4d48cc8..4584e4f 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java
@@ -79,4 +79,12 @@ public class SMTPAppender extends SMTPAppenderBase {
pl.start();
return pl;
}
+
+ protected PatternLayout makeNewToPatternLayout(String toPattern) {
+ PatternLayout pl = new PatternLayout();
+ pl.setPattern(toPattern);
+ return pl;
+ }
+
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java b/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java
index a3fc208..3a6442d 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java
@@ -139,5 +139,4 @@ public class PatternLayout extends PatternLayoutBase {
}
return writeLoopOnConverters(event);
}
-
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
index c30e24c..262bd91 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
@@ -101,4 +101,10 @@ public class SMTPAppender extends SMTPAppenderBase {
pl.start();
return pl;
}
+
+ protected PatternLayout makeNewToPatternLayout(String toPattern) {
+ PatternLayout pl = new PatternLayout();
+ pl.setPattern(toPattern+"%nopex");
+ return pl;
+ }
}
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 ea94697..2e5d65f 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
@@ -189,7 +189,7 @@ class ConfigurationDelegateTest {
PatternLayout layout = sa.layout
assertEquals("%m%n", layout.pattern)
- assertEquals(["a", "b"], sa.toList.sort());
+ assertEquals(["a%nopex", "b%nopex"], sa.getToAsListOfString().sort());
}
// test parent injection
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/DilutedSMTPAppenderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/DilutedSMTPAppenderTest.java
index 5e3f912..53bbc0c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/DilutedSMTPAppenderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/DilutedSMTPAppenderTest.java
@@ -81,9 +81,7 @@ public class DilutedSMTPAppenderTest {
addressArray = null;
address = null;
- addressArray = appender.getMessage().getAllRecipients();
- address = addressArray[0];
- assertEquals("sebastien.nospam at qos.ch", address.toString());
+ assertEquals("sebastien.nospam at qos.ch%nopex", appender.getToAsListOfString().get(0));
assertEquals("logging report", appender.getSubject());
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/PackageTest.java
index 076d7ca..f97ea53 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/PackageTest.java
@@ -19,6 +19,7 @@ import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses( { SyslogAppenderTest.class, DilutedSMTPAppenderTest.class,
- SocketAppenderTest.class, JMSQueueAppenderTest.class, JMSTopicAppenderTest.class })
+ SocketAppenderTest.class, JMSQueueAppenderTest.class, JMSTopicAppenderTest.class,
+ SMTPAppender_GreenTest.class, SMTPAppender_SubethaSMTPTest.class })
public class PackageTest {
}
\ No newline at end of file
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 6d1ee31..01f9dbe 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
@@ -35,6 +35,7 @@ import ch.qos.logback.core.Layout;
import ch.qos.logback.core.boolex.EvaluationException;
import ch.qos.logback.core.boolex.EventEvaluator;
import ch.qos.logback.core.helpers.CyclicBuffer;
+import ch.qos.logback.core.pattern.PatternLayoutBase;
import ch.qos.logback.core.sift.DefaultDiscriminator;
import ch.qos.logback.core.sift.Discriminator;
import ch.qos.logback.core.spi.CyclicBufferTracker;
@@ -58,18 +59,21 @@ import ch.qos.logback.core.util.OptionHelper;
*/
public abstract class SMTPAppenderBase extends AppenderBase {
-
+ static InternetAddress[] EMPTY_IA_ARRAY = new InternetAddress[0];
// ~ 14 days
static final int MAX_DELAY_BETWEEN_STATUS_MESSAGES = 1228800 * CoreConstants.MILLIS_IN_ONE_SECOND;
long lastTrackerStatusPrint = 0;
int delayBetweenStatusMessages = 300 * CoreConstants.MILLIS_IN_ONE_SECOND;
+
+
+
protected Layout subjectLayout;
protected Layout layout;
- private List toList = new ArrayList();
+ private List> toPatternLayoutList = new ArrayList>();
private String from;
private String subjectStr = null;
private String smtpHost;
@@ -150,8 +154,6 @@ public abstract class SMTPAppenderBase extends AppenderBase {
mimeMsg.setFrom();
}
- mimeMsg.setRecipients(Message.RecipientType.TO, parseAddress(toList));
-
subjectLayout = makeSubjectLayout(subjectStr);
started = true;
@@ -190,7 +192,7 @@ public abstract class SMTPAppenderBase extends AppenderBase {
if (lastTrackerStatusPrint + delayBetweenStatusMessages < now) {
addInfo("SMTPAppender [" + name + "] is tracking [" + cbTracker.size() + "] buffers");
lastTrackerStatusPrint = now;
- // quadruple 'delay' assuming less than max delay
+ // quadruple 'delay' assuming less than max delay
if (delayBetweenStatusMessages < MAX_DELAY_BETWEEN_STATUS_MESSAGES) {
delayBetweenStatusMessages *= 4;
}
@@ -246,29 +248,35 @@ public abstract class SMTPAppenderBase extends AppenderBase {
}
}
- InternetAddress[] parseAddress(List addressList) {
+ private List parseAddress(E event) {
+ int len = toPatternLayoutList.size();
- InternetAddress[] iaArray = new InternetAddress[addressList.size()];
+ List iaList = new ArrayList();
- for (int i = 0; i < addressList.size(); i++) {
+ for (int i = 0; i < len; i++) {
try {
- InternetAddress[] tmp = InternetAddress.parse(addressList.get(i), true);
+ PatternLayoutBase emailPL = toPatternLayoutList.get(i);
+ String email = emailPL.doLayout(event);
+ if(email == null || email.length() == 0) {
+ continue;
+ }
+ InternetAddress[] tmp = InternetAddress.parse(email, true);
// one element should contain one email address
- iaArray[i] = tmp[0];
+ iaList.add(tmp[0]);
} catch (AddressException e) {
- addError("Could not parse address [" + addressList.get(i) + "].", e);
- return null;
+ addError("Could not parse email address for [" + toPatternLayoutList.get(i) + "] for event ["+event+"]", e);
+ return iaList;
}
}
- return iaArray;
+ return iaList;
}
/**
* Returns value of the toList option.
*/
- public List getToList() {
- return toList;
+ public List> getToList() {
+ return toPatternLayoutList;
}
/**
@@ -306,6 +314,13 @@ public abstract class SMTPAppenderBase extends AppenderBase {
charsetEncoding);
}
+ List destinationAddresses = parseAddress(lastEventObject);
+ if(destinationAddresses.isEmpty()) {
+ addInfo("Empty destination address. Aborting email transmission");
+ return;
+ }
+ mimeMsg.setRecipients(Message.RecipientType.TO, destinationAddresses.toArray(EMPTY_IA_ARRAY));
+
String contentType = layout.getContentType();
if (ContentTypeUtil.isTextual(contentType)) {
@@ -326,6 +341,8 @@ public abstract class SMTPAppenderBase extends AppenderBase {
}
}
+
+
abstract protected void fillBuffer(CyclicBuffer cb, StringBuffer sbuf);
/**
@@ -437,17 +454,28 @@ public abstract class SMTPAppenderBase extends AppenderBase {
this.discriminator = discriminator;
}
- /**
- * The To option takes a string value which should be an e-mail address
- * of one of the recipients.
- */
public void addTo(String to) {
- this.toList.add(to);
+ if(to == null || to.length() == 0) {
+ throw new IllegalArgumentException("Null or empty property");
+ }
+ PatternLayoutBase plb = makeNewToPatternLayout(to.trim());
+ plb.setContext(context);
+ plb.start();
+ this.toPatternLayoutList.add(plb);
}
- // for testing purpose only
+ abstract protected PatternLayoutBase makeNewToPatternLayout(String toPattern);
+
+ public List getToAsListOfString() {
+ List toList = new ArrayList();
+ for(PatternLayoutBase plb: toPatternLayoutList) {
+ toList.add(plb.getPattern());
+ }
+ return toList;
+ }
- public Message getMessage() {
+ // for testing purpose only
+ public Message getMessage() {
return mimeMsg;
}
diff --git a/logback-site/src/site/pages/recipes/captureHttp.html b/logback-site/src/site/pages/recipes/captureHttp.html
index 244478a..86488e6 100644
--- a/logback-site/src/site/pages/recipes/captureHttp.html
+++ b/logback-site/src/site/pages/recipes/captureHttp.html
@@ -200,11 +200,11 @@ Set-Cookie: JSESSIONID=bgebt99ce9om;path=/logback-demo
probe made by the load-balancer.
-
We need to a way to filter-out these probes so that they are
- no longer contaminate the log output. However, we need a way to
+
We need to a way to filter-out these probes so that they no
+ longer contaminate the log output. In other words, we need to
distinguish probes emanating from the load-balancer from other
- requests that we deem desirable. The contents of the requests
- can give you clues about possible criteria.
+ requests. The contents of the probes can give us clues about
+ possible distinguishing criteria.
Here is a sample probe as logged by logback-access:
Here is a logback-access.xml configuration file
- which will deny any access event which uses the HEAD
- method. Note that it is based on Janino.
+ which will deny any AccessEvent where the method is
+ HEAD. Note that events are evaluated using
+ JaninoEventEvaluator which requires Janino.
<configuration>
<!-- always a good idea to install OnConsoleStatusListener -->
-----------------------------------------------------------------------
Summary of changes:
.../java/ch/qos/logback/access/PatternLayout.java | 1 -
.../ch/qos/logback/access/net/SMTPAppender.java | 8 ++
.../java/ch/qos/logback/classic/PatternLayout.java | 1 -
.../ch/qos/logback/classic/net/SMTPAppender.java | 6 ++
.../gaffer/ConfigurationDelegateTest.groovy | 2 +-
.../classic/net/DilutedSMTPAppenderTest.java | 4 +-
.../ch/qos/logback/classic/net/PackageTest.java | 3 +-
.../ch/qos/logback/core/net/SMTPAppenderBase.java | 72 ++++++++++++++------
.../src/site/pages/recipes/captureHttp.html | 17 +++--
9 files changed, 77 insertions(+), 37 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
From noreply-jira at qos.ch Mon Dec 13 19:08:51 2010
From: noreply-jira at qos.ch (subes (JIRA))
Date: Mon, 13 Dec 2010 19:08:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Created: (LBCLASSIC-237) create a
DelegateAppender which delegates all events to multiple child appenders
Message-ID: <32647700.1292263731278.JavaMail.ceki@pixie>
create a DelegateAppender which delegates all events to multiple child appenders
--------------------------------------------------------------------------------
Key: LBCLASSIC-237
URL: http://jira.qos.ch/browse/LBCLASSIC-237
Project: logback-classic
Issue Type: New Feature
Components: appender
Affects Versions: unspecified
Reporter: subes
Assignee: Logback dev list
Hi,
I'm using LogBack now since some time and got a config that suits me quite well, which i even modularized by merging multiple logback xml files to one and giving that as the configuration to logback. Thats needed because I am building a modular software productline with decentral configuration per module which have their own eclipse project.
I have two default console appenders. One for System.out (level<=INFO) called "stdout" and another one for System.err (level>=WARN) called "stderr".
On top of that I got two default log files. One for all the stuff that goes to both console appenders called "default" and another one for detailed error stacktraces called "error". I do that because I filter stacktraces for console but still want to have access to the complete stacktraces in another log file specific for that purpose. And beside those loggers my modules can create other file appenders like sql.log or messages.log and stuff.
Now to my point: Because I have 4 appenders I almost always use together (2x console and 2x file), i have quite a lot of appender-refs I have to write on my logger definitions. To help with that, I would like to have an appender (called "common") which has the other 4 appenders as children like this:
With that I could either just put "common" on a logger to print to all 4 appenders or I would still have the flexibility to specify only one of those appers.
I tried to implement this on my own, Implementing the appender class itself wasn't a problem, but I don't get how to make joran to understand the appender-ref and insert the delegate appender class into my DelegatingAppender via some setter. It would be nice if you could either include this as a feature into logback-classic or help me out writing it on my own. :)
--
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
From noreply-jira at qos.ch Mon Dec 13 19:11:51 2010
From: noreply-jira at qos.ch (subes (JIRA))
Date: Mon, 13 Dec 2010 19:11:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Commented: (LBCLASSIC-237) create a
DelegateAppender which delegates all events to multiple child appenders
In-Reply-To: <32647700.1292263731278.JavaMail.ceki@pixie>
Message-ID: <648011091.1292263911330.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBCLASSIC-237?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11915#action_11915 ]
subes commented on LBCLASSIC-237:
---------------------------------
I also looked at the SiftingAppender, but that one creates appenders on demand via an AppenderFactory, which is not actually what I want to achieve.
> create a DelegateAppender which delegates all events to multiple child appenders
> --------------------------------------------------------------------------------
>
> Key: LBCLASSIC-237
> URL: http://jira.qos.ch/browse/LBCLASSIC-237
> Project: logback-classic
> Issue Type: New Feature
> Components: appender
> Affects Versions: unspecified
> Reporter: subes
> Assignee: Logback dev list
>
> Hi,
> I'm using LogBack now since some time and got a config that suits me quite well, which i even modularized by merging multiple logback xml files to one and giving that as the configuration to logback. Thats needed because I am building a modular software productline with decentral configuration per module which have their own eclipse project.
> I have two default console appenders. One for System.out (level<=INFO) called "stdout" and another one for System.err (level>=WARN) called "stderr".
> On top of that I got two default log files. One for all the stuff that goes to both console appenders called "default" and another one for detailed error stacktraces called "error". I do that because I filter stacktraces for console but still want to have access to the complete stacktraces in another log file specific for that purpose. And beside those loggers my modules can create other file appenders like sql.log or messages.log and stuff.
> Now to my point: Because I have 4 appenders I almost always use together (2x console and 2x file), i have quite a lot of appender-refs I have to write on my logger definitions. To help with that, I would like to have an appender (called "common") which has the other 4 appenders as children like this:
>
>
>
>
>
>
>
>
>
>
> With that I could either just put "common" on a logger to print to all 4 appenders or I would still have the flexibility to specify only one of those appers.
> I tried to implement this on my own, Implementing the appender class itself wasn't a problem, but I don't get how to make joran to understand the appender-ref and insert the delegate appender class into my DelegatingAppender via some setter. It would be nice if you could either include this as a feature into logback-classic or help me out writing it on my own. :)
--
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
From noreply-jira at qos.ch Mon Dec 13 19:13:51 2010
From: noreply-jira at qos.ch (subes (JIRA))
Date: Mon, 13 Dec 2010 19:13:51 +0100 (CET)
Subject: [logback-dev] [JIRA] Issue Comment Edited: (LBCLASSIC-237) create a
DelegateAppender which delegates all events to multiple child appenders
In-Reply-To: <32647700.1292263731278.JavaMail.ceki@pixie>
Message-ID: <2120721631.1292264031271.JavaMail.ceki@pixie>
[ http://jira.qos.ch/browse/LBCLASSIC-237?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11915#action_11915 ]
subes edited comment on LBCLASSIC-237 at 12/13/10 7:12 PM:
-----------------------------------------------------------
I also looked at the SiftingAppender, but that one creates appenders on demand via an AppenderFactory, which is not actually what I want to achieve. And hacking that to acommodate my wishes seemed hard and quite naughty :)
was (Author: subes):
I also looked at the SiftingAppender, but that one creates appenders on demand via an AppenderFactory, which is not actually what I want to achieve.
> create a DelegateAppender which delegates all events to multiple child appenders
> --------------------------------------------------------------------------------
>
> Key: LBCLASSIC-237
> URL: http://jira.qos.ch/browse/LBCLASSIC-237
> Project: logback-classic
> Issue Type: New Feature
> Components: appender
> Affects Versions: unspecified
> Reporter: subes
> Assignee: Logback dev list
>
> Hi,
> I'm using LogBack now since some time and got a config that suits me quite well, which i even modularized by merging multiple logback xml files to one and giving that as the configuration to logback. Thats needed because I am building a modular software productline with decentral configuration per module which have their own eclipse project.
> I have two default console appenders. One for System.out (level<=INFO) called "stdout" and another one for System.err (level>=WARN) called "stderr".
> On top of that I got two default log files. One for all the stuff that goes to both console appenders called "default" and another one for detailed error stacktraces called "error". I do that because I filter stacktraces for console but still want to have access to the complete stacktraces in another log file specific for that purpose. And beside those loggers my modules can create other file appenders like sql.log or messages.log and stuff.
> Now to my point: Because I have 4 appenders I almost always use together (2x console and 2x file), i have quite a lot of appender-refs I have to write on my logger definitions. To help with that, I would like to have an appender (called "common") which has the other 4 appenders as children like this:
>
>
>
>
>
>
>
>
>
>
> With that I could either just put "common" on a logger to print to all 4 appenders or I would still have the flexibility to specify only one of those appers.
> I tried to implement this on my own, Implementing the appender class itself wasn't a problem, but I don't get how to make joran to understand the appender-ref and insert the delegate appender class into my DelegatingAppender via some setter. It would be nice if you could either include this as a feature into logback-classic or help me out writing it on my own. :)
--
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
From git-noreply at pixie.qos.ch Wed Dec 15 19:07:08 2010
From: git-noreply at pixie.qos.ch (added by portage for gitosis-gentoo)
Date: Wed, 15 Dec 2010 19:07:08 +0100 (CET)
Subject: [logback-dev] [GIT] Logback: the generic, reliable,
fast and flexible logging framework. branch, master,
updated. v_0.9.25-42-g2742a97
Message-ID: <20101215180709.82F0A317077@pixie.qos.ch>
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 2742a97de478cd3fc270223816eaa1c24d13cd82 (commit)
from fc4508616906b773dd9d93d4e0d2c45628d3f7b5 (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=2742a97de478cd3fc270223816eaa1c24d13cd82
http://github.com/ceki/logback/commit/2742a97de478cd3fc270223816eaa1c24d13cd82
commit 2742a97de478cd3fc270223816eaa1c24d13cd82
Author: Ceki Gulcu
Date: Wed Dec 15 19:07:04 2010 +0100
adding support for composite keywords
diff --git a/goscp b/goscp
new file mode 100644
index 0000000..406a6ae
--- /dev/null
+++ b/goscp
@@ -0,0 +1,3 @@
+TARGET=cgulcu at hqchnesoa07:/srv/jboss-eap-4.3.0.GA_CP05/jboss-as/server/nesoa-04-esb-01/lib/
+
+scp logback-core/target/logback-core-0.9.27-SNAPSHOT.jar logback-classic/target/logback-classic-0.9.27-SNAPSHOT.jar logback-access/target/logback-access-0.9.27-SNAPSHOT.jar $TARGET
\ No newline at end of file
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/DateConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/DateConverter.java
index 84226b5..4f0a449 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/DateConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/DateConverter.java
@@ -29,6 +29,7 @@ public class DateConverter extends ClassicConverter {
public void start() {
+
String datePattern = getFirstOption();
if (datePattern == null) {
datePattern = CoreConstants.ISO8601_PATTERN;
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
index 4259f26..546a653 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
@@ -179,7 +179,7 @@ public class ReconfigureOnChangeTest {
// we can't have the test succeed under JDK 1.5, punt and require 1.6+
if (Env.isJDK6OrHigher()) {
assertTrue(failMsg,
- (effectiveResets * 1.3) >= (expectedReconfigurations * 1.0));
+ (effectiveResets * 1.4) >= (expectedReconfigurations * 1.0));
}
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java b/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java
index 0ba51b4..05f1a7b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java
@@ -210,8 +210,9 @@ public class OutputStreamAppender extends UnsynchronizedAppenderBase {
if (event instanceof DeferredProcessingAware) {
((DeferredProcessingAware) event).prepareForDeferredProcessing();
}
- // the synchronized prevents the OutputStream from being closed while we
- // are writing
+ // the synchronization prevents the OutputStream from being closed while we
+ // are writing. It also prevents multiple thread from entering the same
+ // converter. Converters assume that they are in a synchronized block.
synchronized (lock) {
writeOut(event);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java b/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
index 5ee84d0..af16edf 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
@@ -83,7 +83,7 @@ public abstract class HTMLLayoutBase extends LayoutBase {
Parser p = new Parser(pattern);
p.setContext(getContext());
Node t = p.parse();
- this.head = p.compile(t, getEffectiveConverterMap());
+ this.head = p.compile(t, getEffectiveConverterMap(), Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
ConverterUtil.startConverters(this.head);
} catch (ScanException ex) {
addError("Incorrect pattern found", ex);
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/CompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/CompositeConverter.java
index 07e352e..bad3c8c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/CompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/CompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ * 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
@@ -13,24 +13,22 @@
*/
package ch.qos.logback.core.pattern;
-public class CompositeConverter extends FormattingConverter {
+abstract public class CompositeConverter extends DynamicConverter {
- StringBuilder buf = new StringBuilder();
Converter childConverter;
public String convert(E event) {
- if (buf.capacity() > MAX_CAPACITY) {
- buf = new StringBuilder(INITIAL_BUF_SIZE);
- } else {
- buf.setLength(0);
- }
+ StringBuilder buf = new StringBuilder();
for (Converter c = childConverter; c != null; c = c.next) {
c.write(buf, event);
}
- return buf.toString();
+ String intermediary = buf.toString();
+ return transform(intermediary);
}
+ abstract String transform(String in);
+
public void setChildConverter(Converter child) {
childConverter = child;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/ConverterUtil.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/ConverterUtil.java
index 03f65e8..1dc12b2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/ConverterUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/ConverterUtil.java
@@ -17,25 +17,28 @@ public class ConverterUtil {
/**
* Start converters in the chain of converters.
+ *
* @param head
*/
public static void startConverters(Converter head) {
Converter c = head;
while (c != null) {
- if (c instanceof DynamicConverter) {
- DynamicConverter dc = (DynamicConverter) c;
- dc.start();
- } else if(c instanceof CompositeConverter){
+ // CompositeConverter is a subclass of DynamicConverter
+ if (c instanceof CompositeConverter) {
CompositeConverter cc = (CompositeConverter) c;
Converter childConverter = cc.childConverter;
startConverters(childConverter);
+ cc.start();
+ } else if (c instanceof DynamicConverter) {
+ DynamicConverter dc = (DynamicConverter) c;
+ dc.start();
}
c = c.getNext();
}
}
-
- public static Converter findTail(Converter head) {
+
+ public static Converter findTail(Converter head) {
Converter p = head;
while (p != null) {
Converter next = p.getNext();
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/DynamicConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/DynamicConverter.java
index 53eb3b8..cdb0958 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/DynamicConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/DynamicConverter.java
@@ -21,7 +21,7 @@ abstract public class DynamicConverter extends FormattingConverter
implements LifeCycle {
// Contains a list of option Strings.
- private List optionList;
+ private List optionList;
/**
* Is this component active?
@@ -46,7 +46,7 @@ abstract public class DynamicConverter extends FormattingConverter
return started;
}
- public void setOptionList(List optionList) {
+ public void setOptionList(List optionList) {
this.optionList = optionList;
}
@@ -60,11 +60,11 @@ abstract public class DynamicConverter extends FormattingConverter
if (optionList == null || optionList.size() == 0) {
return null;
} else {
- return (String) optionList.get(0);
+ return optionList.get(0);
}
}
- protected List getOptionList() {
+ protected List getOptionList() {
return optionList;
}
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/IdentityCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/IdentityCompositeConverter.java
new file mode 100644
index 0000000..473ff6c
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/IdentityCompositeConverter.java
@@ -0,0 +1,22 @@
+/**
+ * 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.core.pattern;
+
+public class IdentityCompositeConverter extends CompositeConverter {
+
+ @Override
+ String transform(String in) {
+ return in;
+ }
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java
index d507887..e60ee6f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java
@@ -81,7 +81,7 @@ abstract public class PatternLayoutBase extends LayoutBase {
p.setContext(getContext());
}
Node t = p.parse();
- this.head = p.compile(t, getEffectiveConverterMap());
+ this.head = p.compile(t, getEffectiveConverterMap(), Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
if (postCompileProcessor != null) {
postCompileProcessor.process(head);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/ReplacingCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/ReplacingCompositeConverter.java
new file mode 100644
index 0000000..c5e29ef
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/ReplacingCompositeConverter.java
@@ -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.core.pattern;
+
+import java.util.List;
+
+public class ReplacingCompositeConverter extends CompositeConverter {
+
+ String regex;
+ String by;
+
+ public void start() {
+ final List optionList = getOptionList();
+ regex = optionList.get(0);
+ }
+ @Override
+ String transform(String in) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Compiler.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Compiler.java
index bc94153..9bcb1a6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Compiler.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Compiler.java
@@ -15,10 +15,7 @@ package ch.qos.logback.core.pattern.parser;
import java.util.Map;
-import ch.qos.logback.core.pattern.CompositeConverter;
-import ch.qos.logback.core.pattern.Converter;
-import ch.qos.logback.core.pattern.DynamicConverter;
-import ch.qos.logback.core.pattern.LiteralConverter;
+import ch.qos.logback.core.pattern.*;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.status.ErrorStatus;
import ch.qos.logback.core.util.OptionHelper;
@@ -29,46 +26,49 @@ class Compiler extends ContextAwareBase {
Converter tail;
final Node top;
final Map converterMap;
+ final Map compositeConverterMap;
- Compiler(final Node top, final Map converterMap) {
+ Compiler(final Node top, final Map converterMap, Map compositeConverterMap) {
this.top = top;
this.converterMap = converterMap;
+ this.compositeConverterMap = compositeConverterMap;
}
Converter compile() {
head = tail = null;
for (Node n = top; n != null; n = n.next) {
switch (n.type) {
- case Node.LITERAL:
- addToList(new LiteralConverter((String) n.getValue()));
- break;
- case Node.COMPOSITE:
- CompositeNode cn = (CompositeNode) n;
- CompositeConverter compositeConverter = new CompositeConverter();
- compositeConverter.setFormattingInfo(cn.getFormatInfo());
- Compiler childCompiler = new Compiler(cn.getChildNode(),
- converterMap);
- childCompiler.setContext(context);
- Converter childConverter = childCompiler.compile();
- compositeConverter.setChildConverter(childConverter);
- addToList(compositeConverter);
- break;
- case Node.KEYWORD:
- KeywordNode kn = (KeywordNode) n;
- DynamicConverter dynaConverter = createConverter(kn);
- if (dynaConverter != null) {
- dynaConverter.setFormattingInfo(kn.getFormatInfo());
- dynaConverter.setOptionList(kn.getOptions());
- addToList(dynaConverter);
- } else {
- // if the appropriate dynaconverter cannot be found, then replace
- // it with a dummy LiteralConverter indicating an error.
- Converter errConveter = new LiteralConverter("%PARSER_ERROR["
- + kn.getValue()+"]");
- addStatus(new ErrorStatus("[" + kn.getValue()
- + "] is not a valid conversion word", this));
- addToList(errConveter);
- }
+ case Node.LITERAL:
+ addToList(new LiteralConverter((String) n.getValue()));
+ break;
+ case Node.COMPOSITE_KEYWORD:
+ CompositeNode cn = (CompositeNode) n;
+ CompositeConverter compositeConverter = createCompiteConverter(cn);
+ compositeConverter.setFormattingInfo(cn.getFormatInfo());
+ compositeConverter.setOptionList(cn.getOptions());
+ Compiler childCompiler = new Compiler(cn.getChildNode(),
+ converterMap, compositeConverterMap);
+ childCompiler.setContext(context);
+ Converter childConverter = childCompiler.compile();
+ compositeConverter.setChildConverter(childConverter);
+ addToList(compositeConverter);
+ break;
+ case Node.SIMPLE_KEYWORD:
+ SimpleKeywordNode kn = (SimpleKeywordNode) n;
+ DynamicConverter dynaConverter = createConverter(kn);
+ if (dynaConverter != null) {
+ dynaConverter.setFormattingInfo(kn.getFormatInfo());
+ dynaConverter.setOptionList(kn.getOptions());
+ addToList(dynaConverter);
+ } else {
+ // if the appropriate dynaconverter cannot be found, then replace
+ // it with a dummy LiteralConverter indicating an error.
+ Converter errConveter = new LiteralConverter("%PARSER_ERROR["
+ + kn.getValue() + "]");
+ addStatus(new ErrorStatus("[" + kn.getValue()
+ + "] is not a valid conversion word", this));
+ addToList(errConveter);
+ }
}
}
@@ -87,31 +87,60 @@ class Compiler extends ContextAwareBase {
/**
* Attempt to create a converter using the information found in
* 'converterMap'.
- *
+ *
* @param kn
* @return
*/
@SuppressWarnings("unchecked")
- DynamicConverter createConverter(KeywordNode kn) {
+ DynamicConverter createConverter(SimpleKeywordNode kn) {
String keyword = (String) kn.getValue();
String converterClassStr = (String) converterMap.get(keyword);
if (converterClassStr != null) {
try {
return (DynamicConverter) OptionHelper.instantiateByClassName(
- converterClassStr, DynamicConverter.class, context);
+ converterClassStr, DynamicConverter.class, context);
} catch (Exception e) {
addError("Failed to instantiate converter class [" + converterClassStr
- + "]", e);
+ + "]", e);
return null;
}
} else {
addError("There is no conversion class registered for conversion word ["
- + keyword + "]");
+ + keyword + "]");
return null;
}
}
+ /**
+ * Attempt to create a converter using the information found in
+ * 'compositeConverterMap'.
+ *
+ * @param cn
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ CompositeConverter createCompiteConverter(CompositeNode cn) {
+ String keyword = (String) cn.getValue();
+ String converterClassStr = (String) compositeConverterMap.get(keyword);
+
+ if (converterClassStr != null) {
+ try {
+ return (CompositeConverter) OptionHelper.instantiateByClassName(
+ converterClassStr, CompositeConverter.class, context);
+ } catch (Exception e) {
+ addError("Failed to instantiate converter class [" + converterClassStr
+ + "]", e);
+ return null;
+ }
+ } else {
+ addError("There is no conversion class registered for composite conversion word ["
+ + keyword + "]");
+ return null;
+ }
+ }
+
+
// public void setStatusManager(StatusManager statusManager) {
// this.statusManager = statusManager;
// }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/CompositeNode.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/CompositeNode.java
index 8fd2029..cf3c402 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/CompositeNode.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/CompositeNode.java
@@ -13,11 +13,12 @@
*/
package ch.qos.logback.core.pattern.parser;
-public class CompositeNode extends FormattingNode {
+public class CompositeNode extends SimpleKeywordNode {
Node childNode;
- CompositeNode() {
- super(Node.COMPOSITE);
+ CompositeNode(String keyword) {
+ super(Node.COMPOSITE_KEYWORD, keyword);
+
}
public Node getChildNode() {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Node.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Node.java
index 615e2e9..e9bee8b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Node.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Node.java
@@ -15,8 +15,8 @@ package ch.qos.logback.core.pattern.parser;
public class Node {
static final int LITERAL = 0;
- static final int KEYWORD = 1;
- static final int COMPOSITE = 2;
+ static final int SIMPLE_KEYWORD = 1;
+ static final int COMPOSITE_KEYWORD = 2;
final int type;
final Object value;
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/OptionTokenizer.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/OptionTokenizer.java
index 65308db..ad4c762 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/OptionTokenizer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/OptionTokenizer.java
@@ -52,7 +52,7 @@ public class OptionTokenizer {
this.escapeUtil = escapeUtil;
}
- List tokenize() throws ScanException {
+ List tokenize() throws ScanException {
List tokenList = new ArrayList();
StringBuffer buf = new StringBuffer();
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Parser.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Parser.java
index 268edea..510aa7a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Parser.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Parser.java
@@ -13,18 +13,46 @@
*/
package ch.qos.logback.core.pattern.parser;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ch.qos.logback.core.pattern.Converter;
import ch.qos.logback.core.pattern.FormatInfo;
+import ch.qos.logback.core.pattern.IdentityCompositeConverter;
+import ch.qos.logback.core.pattern.ReplacingCompositeConverter;
import ch.qos.logback.core.pattern.util.IEscapeUtil;
import ch.qos.logback.core.pattern.util.RegularEscapeUtil;
import ch.qos.logback.core.spi.ContextAwareBase;
+// ~=lamda
+// E = TE|T
+
+// Left factorization
+// E = T(E|~)
+// Eopt = E|~
+// replace E|~ with Eopt in E
+// E = TEopt
+
+// T = LITERAL | '%' C | '%' FORMAT_MODIFIER C
+// C = SIMPLE_KEYWORD OPTION | COMPOSITE_KEYWORD COMPOSITE
+// OPTION = {...} | ~
+// COMPOSITE = E ')' OPTION
+
+
public class Parser extends ContextAwareBase {
+ public final static Map DEFAULT_COMPOSITE_CONVERTER_MAP = new HashMap();
+ public final static String REPLACER_CONVERTER_WORD = "replace";
+ static {
+ DEFAULT_COMPOSITE_CONVERTER_MAP.put(Token.BARE_COMPOSITE_KEYWORD_TOKEN.getValue().toString(),
+ IdentityCompositeConverter.class.getName());
+ DEFAULT_COMPOSITE_CONVERTER_MAP.put(REPLACER_CONVERTER_WORD,
+ ReplacingCompositeConverter.class.getName());
+
+ }
+
final List tokenList;
int pointer = 0;
@@ -32,7 +60,6 @@ public class Parser extends ContextAwareBase {
this.tokenList = ts.tokenize();
}
- // this variant should be used for testing purposes only
public Parser(String pattern) throws ScanException {
this(pattern, new RegularEscapeUtil());
}
@@ -46,40 +73,51 @@ public class Parser extends ContextAwareBase {
}
}
- public Node parse() throws ScanException {
- return E();
- }
-
/**
* When the parsing step is done, the Node list can be transformed into a
* converter chain.
- *
+ *
* @param top
* @param converterMap
* @return
* @throws ScanException
*/
- public Converter compile(final Node top, Map converterMap) {
- Compiler compiler = new Compiler(top, converterMap);
+ public Converter compile(final Node top, Map converterMap, Map compositeConverterMap) {
+ Compiler compiler = new Compiler(top, converterMap, compositeConverterMap);
compiler.setContext(context);
//compiler.setStatusManager(statusManager);
return compiler.compile();
}
+ public Node parse() throws ScanException {
+ return E();
+ }
+
+ // E = TEopt
Node E() throws ScanException {
- // System.out.println("in E()");
Node t = T();
if (t == null) {
return null;
}
Node eOpt = Eopt();
if (eOpt != null) {
- // System.out.println("setting next node to " + eOpt);
t.setNext(eOpt);
}
return t;
}
+ // Eopt = E|~
+ Node Eopt() throws ScanException {
+ // System.out.println("in Eopt()");
+ Token next = getCurentToken();
+ // System.out.println("Current token is " + next);
+ if (next == null) {
+ return null;
+ } else {
+ return E();
+ }
+ }
+
Node T() throws ScanException {
// System.out.println("in T()");
Token t = getCurentToken();
@@ -117,17 +155,6 @@ public class Parser extends ContextAwareBase {
}
- Node Eopt() throws ScanException {
- // System.out.println("in Eopt()");
- Token next = getCurentToken();
- // System.out.println("Current token is " + next);
- if (next == null) {
- return null;
- } else {
- return E();
- }
- }
-
FormattingNode C() throws ScanException {
Token t = getCurentToken();
// System.out.println("in C()");
@@ -135,11 +162,11 @@ public class Parser extends ContextAwareBase {
expectNotNull(t, "a LEFT_PARENTHESIS or KEYWORD");
int type = t.getType();
switch (type) {
- case Token.KEYWORD:
+ case Token.SIMPLE_KEYWORD:
return SINGLE();
- case Token.LEFT_PARENTHESIS:
+ case Token.COMPOSITE_KEYWORD:
advanceTokenPointer();
- return COMPOSITE();
+ return COMPOSITE(t.getValue().toString());
default:
throw new IllegalStateException("Unexpected token " + t);
}
@@ -149,19 +176,19 @@ public class Parser extends ContextAwareBase {
// System.out.println("in SINGLE()");
Token t = getNextToken();
// System.out.println("==" + t);
- KeywordNode keywordNode = new KeywordNode(t.getValue());
+ SimpleKeywordNode keywordNode = new SimpleKeywordNode(t.getValue());
Token ot = getCurentToken();
if (ot != null && ot.getType() == Token.OPTION) {
- List optionList = new OptionTokenizer((String) ot.getValue()).tokenize();
+ List optionList = new OptionTokenizer((String) ot.getValue()).tokenize();
keywordNode.setOptions(optionList);
advanceTokenPointer();
}
return keywordNode;
}
- FormattingNode COMPOSITE() throws ScanException {
- CompositeNode compositeNode = new CompositeNode();
+ FormattingNode COMPOSITE(String keyword) throws ScanException {
+ CompositeNode compositeNode = new CompositeNode(keyword);
Node childNode = E();
// System.out.println("Child node: " + childNode);
@@ -177,6 +204,12 @@ public class Parser extends ContextAwareBase {
} else {
// System.out.println("got expected ')'");
}
+ Token ot = getCurentToken();
+ if (ot != null && ot.getType() == Token.OPTION) {
+ List optionList = new OptionTokenizer((String) ot.getValue()).tokenize();
+ compositeNode.setOptions(optionList);
+ advanceTokenPointer();
+ }
return compositeNode;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/KeywordNode.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/SimpleKeywordNode.java
similarity index 71%
rename from logback-core/src/main/java/ch/qos/logback/core/pattern/parser/KeywordNode.java
rename to logback-core/src/main/java/ch/qos/logback/core/pattern/parser/SimpleKeywordNode.java
index 3d2879c..3eda998 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/KeywordNode.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/SimpleKeywordNode.java
@@ -1,60 +1,64 @@
-/**
- * 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.pattern.parser;
-
-import java.util.List;
-
-public class KeywordNode extends FormattingNode {
-
- List optionList;
-
- KeywordNode(Object value) {
- super(Node.KEYWORD, value);
- }
-
- public List getOptions() {
- return optionList;
- }
-
- public void setOptions(List optionList) {
- this.optionList = optionList;
- }
-
- public boolean equals(Object o) {
- // System.out.println("Keyword.equals()");
- if (!super.equals(o)) {
- return false;
- }
-
- if (!(o instanceof KeywordNode)) {
- return false;
- }
- KeywordNode r = (KeywordNode) o;
-
- return (optionList != null ? optionList.equals(r.optionList)
- : r.optionList == null);
- }
-
- public String toString() {
- StringBuffer buf = new StringBuffer();
- if (optionList == null) {
- buf.append("KeyWord(" + value + "," + formatInfo + ")");
- } else {
- buf.append("KeyWord(" + value + ", " + formatInfo + "," + optionList
- + ")");
- }
- buf.append(printNext());
- return buf.toString();
- }
-}
+/**
+ * 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.pattern.parser;
+
+import java.util.List;
+
+public class SimpleKeywordNode extends FormattingNode {
+
+ List optionList;
+
+ SimpleKeywordNode(Object value) {
+ super(Node.SIMPLE_KEYWORD, value);
+ }
+
+ protected SimpleKeywordNode(int type, Object value) {
+ super(type, value);
+ }
+
+ public List getOptions() {
+ return optionList;
+ }
+
+ public void setOptions(List optionList) {
+ this.optionList = optionList;
+ }
+
+ public boolean equals(Object o) {
+ // System.out.println("Keyword.equals()");
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ if (!(o instanceof SimpleKeywordNode)) {
+ return false;
+ }
+ SimpleKeywordNode r = (SimpleKeywordNode) o;
+
+ return (optionList != null ? optionList.equals(r.optionList)
+ : r.optionList == null);
+ }
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ if (optionList == null) {
+ buf.append("KeyWord(" + value + "," + formatInfo + ")");
+ } else {
+ buf.append("KeyWord(" + value + ", " + formatInfo + "," + optionList
+ + ")");
+ }
+ buf.append(printNext());
+ return buf.toString();
+ }
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Token.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Token.java
index 2965a1c..1e8a385 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Token.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Token.java
@@ -16,7 +16,7 @@ package ch.qos.logback.core.pattern.parser;
class Token {
static final int PERCENT = 37;
- static final int LEFT_PARENTHESIS = 40;
+ //static final int LEFT_PARENTHESIS = 40;
static final int RIGHT_PARENTHESIS = 41;
static final int MINUS = 45;
static final int DOT = 46;
@@ -24,14 +24,15 @@ class Token {
static final int CURLY_RIGHT = 125;
static final int LITERAL = 1000;
static final int FORMAT_MODIFIER = 1002;
- static final int KEYWORD = 1004;
+ static final int SIMPLE_KEYWORD = 1004;
+ static final int COMPOSITE_KEYWORD = 1005;
static final int OPTION = 1006;
static final int EOF = Integer.MAX_VALUE;
static Token EOF_TOKEN = new Token(EOF, "EOF");
static Token RIGHT_PARENTHESIS_TOKEN = new Token(RIGHT_PARENTHESIS);
- static Token LEFT_PARENTHESIS_TOKEN = new Token(LEFT_PARENTHESIS);
+ static Token BARE_COMPOSITE_KEYWORD_TOKEN = new Token(COMPOSITE_KEYWORD, "BARE");
static Token PERCENT_TOKEN = new Token(PERCENT);
private final int type;
@@ -72,15 +73,15 @@ class Token {
case OPTION:
typeStr = "OPTION";
break;
- case KEYWORD:
- typeStr = "KEYWORD";
+ case SIMPLE_KEYWORD:
+ typeStr = "SIMPLE_KEYWORD";
break;
+ case COMPOSITE_KEYWORD:
+ typeStr = "COMPOSITE_KEYWORD";
+ break;
case RIGHT_PARENTHESIS:
typeStr = "RIGHT_PARENTHESIS";
break;
- case LEFT_PARENTHESIS:
- typeStr = "LEFT_PARENTHESIS";
- break;
default:
typeStr = "UNKNOWN";
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/TokenStream.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/TokenStream.java
index b0dc881..19d8311 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/TokenStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/TokenStream.java
@@ -24,17 +24,17 @@ import ch.qos.logback.core.pattern.util.RegularEscapeUtil;
*
* Return a steady stream of tokens.
*
- *
+ *
*
- * The returned tokens are one of: LITERAL, '%', FORMAT_MODIFIER, KEYWWORD,
+ * The returned tokens are one of: LITERAL, '%', FORMAT_MODIFIER, SIMPLE_KEYWORD, COMPOSITE_KEYWORD
* OPTION, LEFT_PARENTHESIS, and RIGHT_PARENTHESIS.
*
- *
+ *
*
* The '\' character is used as escape. It can be used to escape '_', '%', '('
* and '('.
*
- *
+ *
*
* Note that there is no EOS token returned.
*
@@ -42,7 +42,6 @@ import ch.qos.logback.core.pattern.util.RegularEscapeUtil;
class TokenStream {
private static final char ESCAPE_CHAR = '\\';
- private static final char PERCENT_CHAR = CoreConstants.PERCENT_CHAR;
private static final char CURLY_LEFT = '{';
private static final char CURLY_RIGHT = '}';
@@ -66,7 +65,7 @@ class TokenStream {
TokenStream(String pattern, IEscapeUtil escapeUtil) {
if (pattern == null || pattern.length() == 0) {
throw new IllegalArgumentException(
- "null or empty pattern string not allowed");
+ "null or empty pattern string not allowed");
}
this.pattern = pattern;
patternLength = pattern.length();
@@ -83,105 +82,121 @@ class TokenStream {
switch (state) {
- case LITERAL_STATE:
- switch (c) {
- case ESCAPE_CHAR:
- escape("%()", buf);
+ case LITERAL_STATE:
+ handleLiteralState(c, tokenList, buf);
break;
- case PERCENT_CHAR:
- addValuedToken(Token.LITERAL, buf, tokenList);
- tokenList.add(Token.PERCENT_TOKEN);
- state = FORMAT_MODIFIER_STATE;
+ //
+ case FORMAT_MODIFIER_STATE:
+ handleFormatModifierState(c, tokenList, buf);
break;
-
- case CoreConstants.RIGHT_PARENTHESIS_CHAR:
- if (buf.length() >= 1 && buf.charAt(buf.length() - 1) == '\\') {
- buf.deleteCharAt(buf.length() - 1);
- buf.append(CoreConstants.RIGHT_PARENTHESIS_CHAR);
- } else {
- addValuedToken(Token.LITERAL, buf, tokenList);
- tokenList.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ case OPTION_STATE:
+ switch (c) {
+ case CURLY_RIGHT:
+ addValuedToken(Token.OPTION, buf, tokenList);
+ state = LITERAL_STATE;
+ break;
+ case ESCAPE_CHAR:
+ escape("%{}", buf);
+ break;
+ default:
+ buf.append(c);
}
break;
+ case KEYWORD_STATE:
+ handleKeywordState(c, tokenList, buf);
+ break;
default:
- buf.append(c);
- }
+ }
+ }
+
+ // EOS
+ switch (state) {
+ case LITERAL_STATE:
+ addValuedToken(Token.LITERAL, buf, tokenList);
break;
- //
- case FORMAT_MODIFIER_STATE:
- if (c == CoreConstants.LEFT_PARENTHESIS_CHAR) {
- addValuedToken(Token.FORMAT_MODIFIER, buf, tokenList);
- tokenList.add(Token.LEFT_PARENTHESIS_TOKEN);
- state = LITERAL_STATE;
- } else if (Character.isJavaIdentifierStart(c)) {
- addValuedToken(Token.FORMAT_MODIFIER, buf, tokenList);
- state = KEYWORD_STATE;
- buf.append(c);
- } else {
- buf.append(c);
- }
+ case KEYWORD_STATE:
+ tokenList.add(new Token(Token.SIMPLE_KEYWORD, buf.toString()));
+ buf.setLength(0);
break;
+
+ case FORMAT_MODIFIER_STATE:
case OPTION_STATE:
- switch (c) {
- case CURLY_RIGHT:
- addValuedToken(Token.OPTION, buf, tokenList);
- state = LITERAL_STATE;
- break;
- case ESCAPE_CHAR:
- escape("%{}", buf);
- break;
- default:
- buf.append(c);
- }
+ throw new ScanException("Unexpected end of pattern string");
+ }
+
+ return tokenList;
+ }
+
+ private void handleFormatModifierState(char c, List tokenList, StringBuffer buf) {
+ if (c == CoreConstants.LEFT_PARENTHESIS_CHAR) {
+ addValuedToken(Token.FORMAT_MODIFIER, buf, tokenList);
+ tokenList.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
+ state = LITERAL_STATE;
+ } else if (Character.isJavaIdentifierStart(c)) {
+ addValuedToken(Token.FORMAT_MODIFIER, buf, tokenList);
+ state = KEYWORD_STATE;
+ buf.append(c);
+ } else {
+ buf.append(c);
+ }
+ }
+
+ private void handleLiteralState(char c, List tokenList, StringBuffer buf) {
+ switch (c) {
+ case ESCAPE_CHAR:
+ escape("%()", buf);
break;
- case KEYWORD_STATE:
- if (c == CURLY_LEFT) {
- addValuedToken(Token.KEYWORD, buf, tokenList);
- state = OPTION_STATE;
- } else if (Character.isJavaIdentifierPart(c)) {
- buf.append(c);
- } else if (c == PERCENT_CHAR) {
- addValuedToken(Token.KEYWORD, buf, tokenList);
- tokenList.add(Token.PERCENT_TOKEN);
- state = FORMAT_MODIFIER_STATE;
+
+ case CoreConstants.PERCENT_CHAR:
+ addValuedToken(Token.LITERAL, buf, tokenList);
+ tokenList.add(Token.PERCENT_TOKEN);
+ state = FORMAT_MODIFIER_STATE;
+ break;
+
+ case CoreConstants.RIGHT_PARENTHESIS_CHAR:
+ if (buf.length() >= 1 && buf.charAt(buf.length() - 1) == '\\') {
+ buf.deleteCharAt(buf.length() - 1);
+ buf.append(CoreConstants.RIGHT_PARENTHESIS_CHAR);
} else {
- addValuedToken(Token.KEYWORD, buf, tokenList);
- if (c == CoreConstants.RIGHT_PARENTHESIS_CHAR) {
- // if c is a right parenthesis, then add it as such
- tokenList.add(Token.RIGHT_PARENTHESIS_TOKEN);
- } else if (c == ESCAPE_CHAR) {
- if ((pointer < patternLength)) {
- char next = pattern.charAt(pointer++);
- escapeUtil.escape("%()", buf, next, pointer);
- }
- } else {
- buf.append(c);
- }
- state = LITERAL_STATE;
+ addValuedToken(Token.LITERAL, buf, tokenList);
+ tokenList.add(Token.RIGHT_PARENTHESIS_TOKEN);
}
break;
default:
- }
+ buf.append(c);
}
+ }
- // EOS
- switch (state) {
- case LITERAL_STATE:
- addValuedToken(Token.LITERAL, buf, tokenList);
- break;
- case KEYWORD_STATE:
- tokenList.add(new Token(Token.KEYWORD, buf.toString()));
- buf.setLength(0);
- break;
-
- case FORMAT_MODIFIER_STATE:
- case OPTION_STATE:
- throw new ScanException("Unexpected end of pattern string");
+ private void handleKeywordState(char c, List tokenList, StringBuffer buf) {
+ if (c == CURLY_LEFT) {
+ addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
+ state = OPTION_STATE;
+ } else if (Character.isJavaIdentifierPart(c)) {
+ buf.append(c);
+ } else if (c == CoreConstants.LEFT_PARENTHESIS_CHAR) {
+ addValuedToken(Token.COMPOSITE_KEYWORD, buf, tokenList);
+ state = LITERAL_STATE;
+ } else if (c == CoreConstants.PERCENT_CHAR) {
+ addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
+ tokenList.add(Token.PERCENT_TOKEN);
+ state = FORMAT_MODIFIER_STATE;
+ } else {
+ addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
+ if (c == CoreConstants.RIGHT_PARENTHESIS_CHAR) {
+ // if c is a right parenthesis, then add it as such
+ tokenList.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ } else if (c == ESCAPE_CHAR) {
+ if ((pointer < patternLength)) {
+ char next = pattern.charAt(pointer++);
+ escapeUtil.escape("%()", buf, next, pointer);
+ }
+ } else {
+ buf.append(c);
+ }
+ state = LITERAL_STATE;
}
-
- return tokenList;
}
void escape(String escapeChars, StringBuffer buf) {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java
index 88adfe6..be3c8b5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java
@@ -66,7 +66,7 @@ public class FileNamePattern extends ContextAwareBase {
Parser