[jira] [Commented] (LOG4J2-599) Support lambda functions (or similar) for log message parameters

2015-08-09 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-599?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14679377#comment-14679377
 ] 

Bruce Brouwer commented on LOG4J2-599:
--

I wonder how well that would work using generics like that. What gotchas will I 
run into?

I have to say that I'm not entirely thrilled with introducing the whole Logger2 
interface. The main argument against just adding it to Logger is that anything 
that implements the Logger interface (particularly something that is not part 
of the log4j project) will break BC. From a technical standpoint, this is true, 
but from a practical standpoint, I don't think it is important. 

I just made a little example project to prove this out, and things don't 
actually break. If you add a method to the Logger api, implementors of the 2.3 
version will not blow up once the 2.4 log4j-api is on the classpath. The only 
thing that will blow up is if I call the new method and the implementor has not 
yet implemented it. To me, that seems like a completely reasonable outcome. 

Consider why I am using the log4j-api 2.4 without a log4j implementation. The 
only real case I can think of is if if there is a bridge APIs that Log4j 
doesn't cover. Perhaps a custom logging implementation that some company has. 
If they did come across a library that required the new methods from log4j-api 
version 2.4, it doesn't seem that unreasonable to require them to update their 
custom bridge. And if nothing actually used those new methods, nothing will 
blow up, which I believe is by far the most likely situation. 

Other API libraries deal with this exact same issue. For example, JPA when it 
went from 2.0 to 2.1 added new API methods to the CriteriaBuilder. They weren't 
forced to version 3.0 simply because they added a new method to an API. 

And furthermore, I don't like where this will ultimately lead us to. So we know 
today what we're talking about adding to Logger2, but what about for version 
2.5 when there is more stuff we want to add. Do we make Logger3 so that we 
don't break the BC for Logger2? and then Logger4? That seems ridiculous to me. 

I would much rather see a few new methods added to the main Logger API.

 Support lambda functions (or similar) for log message parameters
 

 Key: LOG4J2-599
 URL: https://issues.apache.org/jira/browse/LOG4J2-599
 Project: Log4j 2
  Issue Type: Brainstorming
  Components: Core
Reporter: Matt Sicker
Assignee: Remko Popma
Priority: Minor
  Labels: Java8
 Fix For: 2.4


 It would be nice if we could support 0-param lambda functions (or the 
 equivalent: interfaces with a single empty-parameter message call), or more 
 simply, allow Runnables (or something similar) to be passed which will be 
 dynamically executed if the log message is enabled.
 The use case here is that although string construction of the log message is 
 a performance issue that is already solved quite well, the problem of adding 
 in information to the log message that makes other calculations still needs 
 to be wrapped in an if check.
 I'm not sure if it'd be best to just use Runnable, or create a new interface, 
 or try to emulate how Java 1.8 lambdas work via an interface with a single 
 method defined. The details here would still need to be fleshed out, but I 
 think this sort of feature could be rather handy (especially in a Java 1.8+ 
 environment, or in Groovy/Scala/etc.).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-599) Support lambda functions (or similar) for log message parameters

2015-08-09 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-599?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14679435#comment-14679435
 ] 

Bruce Brouwer commented on LOG4J2-599:
--

My test showed that implementors of the old Logger interface continue to load 
just fine with the newer API. An exception is only thrown when calling the new 
method. That exception is {{java.lang.AbstractMethodError}}

 Support lambda functions (or similar) for log message parameters
 

 Key: LOG4J2-599
 URL: https://issues.apache.org/jira/browse/LOG4J2-599
 Project: Log4j 2
  Issue Type: Brainstorming
  Components: Core
Reporter: Matt Sicker
Assignee: Remko Popma
Priority: Minor
  Labels: Java8
 Fix For: 2.4


 It would be nice if we could support 0-param lambda functions (or the 
 equivalent: interfaces with a single empty-parameter message call), or more 
 simply, allow Runnables (or something similar) to be passed which will be 
 dynamically executed if the log message is enabled.
 The use case here is that although string construction of the log message is 
 a performance issue that is already solved quite well, the problem of adding 
 in information to the log message that makes other calculations still needs 
 to be wrapped in an if check.
 I'm not sure if it'd be best to just use Runnable, or create a new interface, 
 or try to emulate how Java 1.8 lambdas work via an interface with a single 
 method defined. The details here would still need to be fleshed out, but I 
 think this sort of feature could be rather handy (especially in a Java 1.8+ 
 environment, or in Groovy/Scala/etc.).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-599) Support lambda functions (or similar) for log message parameters

2015-08-09 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-599?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14679435#comment-14679435
 ] 

Bruce Brouwer edited comment on LOG4J2-599 at 8/10/15 12:42 AM:


My test showed that implementors of the old Logger interface continue to load 
and old methods continue to work just fine with the newer API. An exception is 
only thrown when calling the new method. That exception is 
{{java.lang.AbstractMethodError}}


was (Author: bruce.brouwer):
My test showed that implementors of the old Logger interface continue to load 
just fine with the newer API. An exception is only thrown when calling the new 
method. That exception is {{java.lang.AbstractMethodError}}

 Support lambda functions (or similar) for log message parameters
 

 Key: LOG4J2-599
 URL: https://issues.apache.org/jira/browse/LOG4J2-599
 Project: Log4j 2
  Issue Type: Brainstorming
  Components: Core
Reporter: Matt Sicker
Assignee: Remko Popma
Priority: Minor
  Labels: Java8
 Fix For: 2.4


 It would be nice if we could support 0-param lambda functions (or the 
 equivalent: interfaces with a single empty-parameter message call), or more 
 simply, allow Runnables (or something similar) to be passed which will be 
 dynamically executed if the log message is enabled.
 The use case here is that although string construction of the log message is 
 a performance issue that is already solved quite well, the problem of adding 
 in information to the log message that makes other calculations still needs 
 to be wrapped in an if check.
 I'm not sure if it'd be best to just use Runnable, or create a new interface, 
 or try to emulate how Java 1.8 lambdas work via an interface with a single 
 method defined. The details here would still need to be fleshed out, but I 
 think this sort of feature could be rather handy (especially in a Java 1.8+ 
 environment, or in Groovy/Scala/etc.).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-599) Support lambda functions (or similar) for log message parameters

2015-08-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-599?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14661006#comment-14661006
 ] 

Bruce Brouwer commented on LOG4J2-599:
--

Could we avoid the whole api change thing by having a static method that I
could static import which had a signature something like

public static Object lazyParam(Callable param) { return param; }

Then it would be simple to even mix and match lazy and non-lazy params.

logger.trace(msg {} {}, lazyParam(() - expensive operation()), nonLazy);
On Aug 6, 2015 7:04 PM, Remko Popma (JIRA) j...@apache.org wrote:


[
https://issues.apache.org/jira/browse/LOG4J2-599?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14660945#comment-14660945
]

Remko Popma commented on LOG4J2-599:


That is the use case for this ticket: users on Java 8 will be able to avoid
the explicit level check and instead write
{code}
logger.trace(Some expensive operation returned {}, () -
expensiveOperation());
{code}

resulting in more compact and cleaner code.

The only logging product that I am aware of that currently supports lambda
expressions for lazy logging is the JDK [Logger|
http://docs.oracle.com/javase/8/docs/api/java/util/logging/Logger.html#log-java.util.logging.Level-java.util.function.Supplier-].
But IMHO the JDK Logger is only doing a partial job: it only lazily
constructs the whole log message. There is no API for lazily constructing
message parameters.

I think keeping up to date with Java language developments makes this a
strategic feature that adds to the reasons why Log4j 2 is the logging
library of choice for our users.

equivalent: interfaces with a single empty-parameter message call), or more
simply, allow Runnables (or something similar) to be passed which will be
dynamically executed if the log message is enabled.
is a performance issue that is already solved quite well, the problem of
adding in information to the log message that makes other calculations
still needs to be wrapped in an if check.
interface, or try to emulate how Java 1.8 lambdas work via an interface
with a single method defined. The details here would still need to be
fleshed out, but I think this sort of feature could be rather handy
(especially in a Java 1.8+ environment, or in Groovy/Scala/etc.).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


 Support lambda functions (or similar) for log message parameters
 

 Key: LOG4J2-599
 URL: https://issues.apache.org/jira/browse/LOG4J2-599
 Project: Log4j 2
  Issue Type: Brainstorming
  Components: Core
Reporter: Matt Sicker
Priority: Minor
  Labels: Java8

 It would be nice if we could support 0-param lambda functions (or the 
 equivalent: interfaces with a single empty-parameter message call), or more 
 simply, allow Runnables (or something similar) to be passed which will be 
 dynamically executed if the log message is enabled.
 The use case here is that although string construction of the log message is 
 a performance issue that is already solved quite well, the problem of adding 
 in information to the log message that makes other calculations still needs 
 to be wrapped in an if check.
 I'm not sure if it'd be best to just use Runnable, or create a new interface, 
 or try to emulate how Java 1.8 lambdas work via an interface with a single 
 method defined. The details here would still need to be fleshed out, but I 
 think this sort of feature could be rather handy (especially in a Java 1.8+ 
 environment, or in Groovy/Scala/etc.).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Assigned] (LOG4J2-514) ConsoleAppender closing System.out on Windows

2014-07-15 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-514?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer reassigned LOG4J2-514:


Assignee: Bruce Brouwer

 ConsoleAppender closing System.out on Windows
 -

 Key: LOG4J2-514
 URL: https://issues.apache.org/jira/browse/LOG4J2-514
 Project: Log4j 2
  Issue Type: Bug
  Components: Appenders
Affects Versions: 2.0-beta9
 Environment: Windows 7 64-bit
 Oracle JDK 1.7.0_51
Reporter: Wolf480 Pl
Assignee: Bruce Brouwer
 Attachments: LOG4J2-514.patch.txt


 If the Console appender is not specified in the configuration file, after the 
 configuration is read, the Console appender is being destroyed, which causes 
 it to release its OutputStreamManager, When this manager is released and 
 closed, it checks if the stream is System.out or System.err, and if it is, 
 doesn't close it. But on Windows, ConsoleAppender wraps the System.out into a 
 WindowsAnsiOutputStream. The OutputStreamManager closes the stream when it's 
 released, and the stream closes the underlaying System.out.
 proof: http://imageshack.com/a/img31/8296/cg6b.png
 -I think the easiest solution would be to use new 
 FileOutputStream(FileDescriptor.out)) instead of System.out in 
 ConsoleAppender implementation.- unfortunately, that would still cause 
 System.out to be closed.
 A solution would be to wrap System.out with some FilterStream that overrides 
 close() to do nothing.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-07-15 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14062201#comment-14062201
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

Why should the {{StatusData}} constructor be public (other than it is a small 
breaking API change)? Nothing should be creating these {{StatusData}} objects 
other than {{StatusLogger}}.

The only thing that ever registered {{StatusConsoleListener}} was 
{{JsonConfiguration}} or {{XmlConfiguration}}, both of which are in -core. So 
if someone only included log4j-api, the behavior now will be the same now as 
before. Well, I suppose it is a little different than before. Before, the 
default level was FATAL, so {{StatusLogger.getLogger().isEnabled(Level.FATAL, 
null)}} would return true, even though it wouldn't actually do anything when 
{{.fatal(some error)}} was called. 

Now, I did like the suggestion that Matt made where perhaps sending 
{{StatusLogger}} output to {{System.out}} or {{System.err}} should have nothing 
to do with {{JsonConfiguration}} or {{XmlConfiguration}}, but rather should be 
configured from the Log4j properties. I would be on board with that change as 
long as we rip out that configuration from {{JsonConfiguration}} and 
{{XmlConfiguration}}. This way if I only included log4j-api, I could still get 
some messages to show on {{System.out}}. 

I actually would like this change very much. Right now, nothing will ever 
remove that {{StatusConsoleListener}}. With changing this to use Log4j 
properties, nobody would expect the ability to turn off {{StatusLogger}} output 
to {{System.out}}. In fact, I probably wouldn't even implement this as a 
{{StatusListener}}, but rather directly inside {{StatusLogger}}. 

What do you say to that?



 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: LOG4J2-609.unfinished.patch, log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-07-15 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14062219#comment-14062219
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

You know, since this would be the majority case, this could simplify 
{{StatusLogger}} even further by not requiring it to keep a bounded list of 
past Status messages. No longer would we expect future listeners to receive 
past status messages. There would be no longer be any chance that Status 
messages would be lost when being sent to {{System.out}}. 

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: LOG4J2-609.unfinished.patch, log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-07-15 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14062503#comment-14062503
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

I will relent on the public constructor for {{StatusData}}. 

You're right about the {{SimpleLogger.isEnabled(...)}}. I should have been 
looking at the code when I wrote my statements. I updated it on the branch 
according to my next statements.  

With all the talk about how to configure log4j so that status logs go the 
stdout or stderr, I decided to try out the approach of making a log4j property 
that controls what goes to System.out or System.err. I think it makes it much 
simpler. It eliminates {{StatusConsoleListener}} completely.

I'm looking for some feedback on this idea.

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: LOG4J2-609.unfinished.patch, log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-07-15 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14063016#comment-14063016
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

I had to revert most of that last simplification as it was causing too much 
impact for now. Please check what is there now. 

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: LOG4J2-609.unfinished.patch, log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-07-14 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14060930#comment-14060930
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

# You're right. .getStatusLevel() can remain. The important part was removing 
the caching of .getStatusLevel() from StatusLogger. I put that back to the way 
it was before. As for .registerListener(...), the code on the branch was 
simplified beyond what is identified in this JIRA as a result of the mailing 
list discussion. That is why no such parameter is added to 
.registerListener(...) on the branch. It isn't necessary on 
.registerListener(...) with this simplification. 
# I was originally thinking that status listeners might make some decision 
based on the Marker. Also, why not include the marker. Every other piece of 
information from the logged message is included. I'm guessing nothing that uses 
StatusLogger provides a marker so I can see your point from that perspective. 
But if we decide to start doing more with StatusLogger and Markers, it is 
ready. To prevent the StatusData constructor becoming part of the public API 
(and possibly making it harder to add a Marker in the future) I made the 
constructor package private. This will allow us to add the Marker back in later 
without being considered a breaking API change. What do you think of that? 

If people like this, I'm pretty happy with the way it has turned out without 
being too impactful. 

To recap what was mentioned on the mailing list, 
* The StatusLogger no longer maintains a cached copy of the logger level
* StatusConsoleListener was moved to log4j-core with subclasses of 
StatusStdErrListener and StatusStdOutListener which correctly track changes to 
System.out and System.err
* There is no longer an option in XML or JSON configuration to direct 
StatusLogger messages to a file; only System.out and/or System.err


 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: LOG4J2-609.unfinished.patch, log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-609) StatusConfiguration doesn't close files

2014-07-14 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14060930#comment-14060930
 ] 

Bruce Brouwer edited comment on LOG4J2-609 at 7/14/14 5:50 PM:
---

# You're right. .getStatusLevel() can remain. The important part was removing 
the caching of .getStatusLevel() from StatusLogger. I put that back to the way 
it was before. As for .registerListener(...), the code on the branch was 
simplified beyond what is identified in this JIRA as a result of the mailing 
list discussion. That is why no such parameter is added to 
.registerListener(...) on the branch. It isn't necessary on 
.registerListener(...) with this simplification. 
# I was originally thinking that status listeners might make some decision 
based on the Marker. Also, why not include the marker. Every other piece of 
information from the logged message is included. I'm guessing nothing that uses 
StatusLogger provides a marker so I can see your point from that perspective. 
But if we decide to start doing more with StatusLogger and Markers, it is 
ready. To prevent the StatusData constructor becoming part of the public API 
(and possibly making it harder to add a Marker in the future) I made the 
constructor package private. This will allow us to add the Marker back in later 
without being considered a breaking API change. What do you think of that? 

If people like this, I'm pretty happy with the way it has turned out without 
being too impactful. 

To recap what has actually changed: 
* The StatusLogger no longer maintains a cached copy of the logger level
* StatusConsoleListener was moved to log4j-core with subclasses of 
StatusStdErrListener and StatusStdOutListener which correctly track changes to 
System.out and System.err
* There is no longer an option in XML or JSON configuration to direct 
StatusLogger messages to a file; only System.out and/or System.err



was (Author: bruce.brouwer):
# You're right. .getStatusLevel() can remain. The important part was removing 
the caching of .getStatusLevel() from StatusLogger. I put that back to the way 
it was before. As for .registerListener(...), the code on the branch was 
simplified beyond what is identified in this JIRA as a result of the mailing 
list discussion. That is why no such parameter is added to 
.registerListener(...) on the branch. It isn't necessary on 
.registerListener(...) with this simplification. 
# I was originally thinking that status listeners might make some decision 
based on the Marker. Also, why not include the marker. Every other piece of 
information from the logged message is included. I'm guessing nothing that uses 
StatusLogger provides a marker so I can see your point from that perspective. 
But if we decide to start doing more with StatusLogger and Markers, it is 
ready. To prevent the StatusData constructor becoming part of the public API 
(and possibly making it harder to add a Marker in the future) I made the 
constructor package private. This will allow us to add the Marker back in later 
without being considered a breaking API change. What do you think of that? 

If people like this, I'm pretty happy with the way it has turned out without 
being too impactful. 

To recap what was mentioned on the mailing list, 
* The StatusLogger no longer maintains a cached copy of the logger level
* StatusConsoleListener was moved to log4j-core with subclasses of 
StatusStdErrListener and StatusStdOutListener which correctly track changes to 
System.out and System.err
* There is no longer an option in XML or JSON configuration to direct 
StatusLogger messages to a file; only System.out and/or System.err


 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: LOG4J2-609.unfinished.patch, log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, 

[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-06-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14019805#comment-14019805
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

I forgot one other point:
5. I removed StatusListener.getStatusLevel() and moved it to a parameter on 
StatusLogger.registerListener(...). Before, I might be inclined to allow my 
listener to change its level, but that would actually not work in many cases. 
It seemed better to require a listener to be removed and then re-registered if 
you wanted to change the status level.

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: LOG4J2-609.unfinished.patch, log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-609) StatusConfiguration doesn't close files

2014-06-05 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-609:
-

Attachment: LOG4J2-609.unfinished.patch

Here is my second attempt. It's going to require some explanation. It isn't 
finished, but I wanted to get your thoughts. 

# Using just a listener that many configurations shared will not work when they 
each want to log at a different level. The real goal is to make configure (or 
filter) which status logs end up on System.out or System.err or some file. So 
rather than a single registerListener which takes a StatusListener, I have 
added registerSystemOutFilter, registerSystemErrFilter and registerFileFilter. 
This way, each configuration can register its own filter and the StatusLogger 
will look for the least specific filter for the specified target and log at 
that level. 
# Rather than a single fall-back SimpleLogger, there is now a SimpleLogger 
registered for System.out, System.err and each file filter that is registered. 
I don't know if that simplified the code much, but at least the logging 
statements are much closer to a straight pass-through for the majority of cases
# The only thing that is using registerListener now is jmx.StatusLoggerAdmin 
some JmsTests in log4j-core, which I haven't figured out why they are there 
yet. 
# I refactored away StatusConfiguration in favor of 
AbstractStatusLoggingConfiguration so that XmlConfiguration and 
JsonConfiguration can be more consistent in their configuration. The only 
different I saw is that they had seemingly opposite behavior for what verbose 
meant, and even if you don't consider it opposite (the terminology I think is 
confusing) they were definitely using different values (true/false vs. 
quiet/verbose). 


 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: LOG4J2-609.unfinished.patch, log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-06-05 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14019537#comment-14019537
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

I don't think there is anything in there that will cause stdout or stderr to be 
closed. By making SimpleLogger implement Closeable, it does open that 
possibility for someone using their own SimpleLogger to do that, but in this 
code StatusLogger never closes SimpleLogger instances that represent stdout or 
stderr. The only SimpleLoggers that get closed are the ones that are created 
for files. 

And as I said, it isn't finished yet, but I think it is close, at least 
conceptually. 

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: LOG4J2-609.unfinished.patch, log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Closed] (LOG4J2-242) Make Messages more fluent

2014-05-04 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-242?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer closed LOG4J2-242.



 Make Messages more fluent
 -

 Key: LOG4J2-242
 URL: https://issues.apache.org/jira/browse/LOG4J2-242
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-beta5
Reporter: Bruce Brouwer
Assignee: Nick Williams
  Labels: backlog
 Attachments: LOG4J2-242.patch

   Original Estimate: 48h
  Remaining Estimate: 48h

 I really like the feature were we can pass in a Message object into the 
 logger methods. However, it bugs me that some of the implementations of 
 Message provide vararg constructors, and others only provide an Object[] 
 parameter. I really would like to write this code:
 log.info(new ParameterizedMessage(abc: {} xyz: {}, abc, xyz), 
 throwable);
 I realize that this particular example would work with this code by default:
 log.info(abc: {} xyz: {}, abc, xyz, throwable);
 But the other Message implementations don't provide a vararg constructor, nor 
 do they try to detect the last parameter as a Throwable.
 [LOG4J2-48] addresses some of the complexity of having varargs with the last 
 vararg being an implicit final parameter, but again, this only works with 
 ParameterizedMessage. But I would like this to be more consistent across the 
 board. One idea that I had was this:
 log.info(new ParameterizedMessage(abc: {} xyz: {}, abc, 
 xyz).throwing(throwable));
 Now all of the message constructors (not just ParameterizedMessage) could 
 have varargs with none of them providing a Throwable parameter in the 
 constructor, but provided through a more fluent API. I don't know that it 
 would warrant adding it to the Message interface, but we could go further 
 with it by adding these methods:
 Message withParameters(Object... parameters);
 Message throwing(Throwable throwable);
 It wouldn't be absolutely necessary as the concrete implementations could 
 define that and work in my case.
 Another idea that I had was maybe a bit more impactful to the Logger API. 
 What if I wrote my code like this:
 log.with(exception).info(abc: {} xyz: {}, abc, xyz);
 // or maybe this
 log.message(abc: {} xyz: {}, abc, xyz).with(exception).info();
 That would necessitate something like a LogBuilder interface, maybe tie it 
 into the MessageFactory classes. This LogBuilder interface could have these 
 methods:
 LogBuilder message(String pattern, Object... params);
 LogBuilder with(Throwable t);
 LogBuilder marker(Marker marker);
 LogBuilder level(Level level);
 void info(); // and others like it
 void info(String pattern, Object... params); // and others like it
 I'm not exactly sure what the best way would be to go and implement this as 
 I'm sure you don't want to have objects created all over the place. 
 Is this an idea worth pursuing a bit further?



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Closed] (LOG4J2-439) Create a LogEventPatternConverter to escape newlines and HTML special characters

2014-05-04 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-439?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer closed LOG4J2-439.



 Create a LogEventPatternConverter to escape newlines and HTML special 
 characters
 

 Key: LOG4J2-439
 URL: https://issues.apache.org/jira/browse/LOG4J2-439
 Project: Log4j 2
  Issue Type: New Feature
  Components: Layouts
Affects Versions: 2.0-beta9
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: EncodingPatternConverter.patch, log4j2-439-doc.patch


 To prevent log forging and HTML based attacks from viewing logs in a browser, 
 we could add a LogEventPatternConverter that escapes newlines and HTML 
 special characters. [ESAPI has a method to do 
 this|http://owasp-esapi-java.googlecode.com/svn/trunk_doc/2.0-rc7/apidocs/org/owasp/esapi/Logger.html],
  but it doesn't have any of the nice API features that Log4j 2 has. 
 I was able to create a LogEventPatternConverter to do this. Note, this is 
 only a proof of concept. I didn't try to exhaustively list all the special 
 characters that might need to be replaced. I also didn't provide any 
 configuration so we could choose to not escape HTML, for example.
 With this configuration:
 {code:xml}
 PatternLayout pattern=%d %-5p [%t] %c %encode{%m}%n/
 {code}
 And logging this message:
 {code}
 LOG.warn(hi\n  h1 there);
 {code}
 Would result in this being logged:
 {code}
 2013-10-28 16:31:21,606 WARN  [main] example.Test hi\n amp; lt;h1gt; there 
 {code}
 instead of this (which shows the potential for log forging):
 {code}
 2013-10-28 16:31:21,606 WARN  [main] example.Test hi
  h1 there 
 {code}
 This is roughly the code I used:
 {code}
 @Plugin(name = escape, category = Converter)
 @ConverterKeys({ escape })
 public final class EscapingReplacementConverter extends 
 LogEventPatternConverter {
 private final ListPatternFormatter formatters;
 private EscapingReplacementConverter(final ListPatternFormatter 
 formatters) {
 super(escape, escape);
 this.formatters = formatters;
 }
 public static EscapingReplacementConverter newInstance(final 
 Configuration config,
final String[] 
 options) {
 if (options.length != 1) {
 LOGGER.error(Incorrect number of options on escape. Expected 1, 
 received 
 + options.length);
 return null;
 }
 if (options[0] == null) {
 LOGGER.error(No pattern supplied on escape);
 return null;
 }
 final PatternParser parser = 
 PatternLayout.createPatternParser(config);
 final ListPatternFormatter formatters = parser.parse(options[0]);
 return new EscapingReplacementConverter(formatters);
 }
 @Override
 public void format(final LogEvent event, final StringBuilder toAppendTo) {
 final StringBuilder buf = new StringBuilder();
 for (final PatternFormatter formatter : formatters) {
 formatter.format(event, buf);
 }
 toAppendTo.append(buf.toString()
  .replaceAll(\\r, r)
  .replaceAll(\\n, n)
  .replaceAll(, amp;)
  .replaceAll(, lt;)
  .replaceAll(, gt;));
 }
 }
 {code}
 If this sounds good, I would like to hear feedback and ideas on how to make 
 this better. I will then contribute this to the project. Do you think this 
 could this get in 2.0?



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Closed] (LOG4J2-558) Create a log4j-bom

2014-05-04 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-558?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer closed LOG4J2-558.



 Create a log4j-bom
 --

 Key: LOG4J2-558
 URL: https://issues.apache.org/jira/browse/LOG4J2-558
 Project: Log4j 2
  Issue Type: Improvement
Reporter: Bruce Brouwer
Assignee: Matt Sicker
 Fix For: 2.0-rc2

 Attachments: log4j-bom.patch


 Create a log4j-bom (Bill of Materials) POM to make it easier for clients to 
 keep consistent versions for multiple log4j artifacts.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Closed] (LOG4J2-585) Markers not as powerful as slf4j

2014-05-04 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer closed LOG4J2-585.



 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Fix For: 2.0-rc2

 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-05-01 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13986527#comment-13986527
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

It seemed odd to me that a configuration (be it XMLConfiguration or 
JSONConfiguration) would modify a different configuration's listener. I thought 
it would be better if each configuration held onto a reference of its own 
StatusConsoleListener and unregistered it at appropriate times (e.g. 
reconfigure or close). 

This way, if I modified my XML config file to switch from one destination file 
to another destination file, the old destination file will get closed and the 
new destination file will start to be used. In the original code, there would 
be no switch from the previous destination to the new destination file and no 
way to close the destination file. 

This is probably the most impactful part of my change, so I appreciate that you 
are looking carefully into what I did. 

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-05-01 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13986604#comment-13986604
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

Ah yes, I wasn't thinking about that. I'll have to come up with a different 
solution then.

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Attachments: log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-609) StatusConfiguration doesn't close files

2014-04-30 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-609:
-

Attachment: log4j2-609.patch

With log4j2-609.patch, now all tests pass with a clean install on Windows. This 
patch gets into some of the deeper guts of log4j that I haven't had to deal 
with before, so I would appreciate someone vetting what I did. 

But at least all the tests pass, so that's good. 

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: log4j2-609.patch


 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Created] (LOG4J2-609) StatusConfiguration doesn't close files

2014-04-21 Thread Bruce Brouwer (JIRA)
Bruce Brouwer created LOG4J2-609:


 Summary: StatusConfiguration doesn't close files
 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer


org.apache.logging.log4j.core.config.status.StatusConfiguration allows you to 
specify a destination such as out, err or a file name. If specifying a 
file, that file stream is used when creating a StatusConsoleListener that is 
added to the StatusLogger. Those StatusLogger listeners are never cleaned up 
when the XmlConfiguration is reconfigured or when the LoggerContext is shut 
down (e.g. in InitialLoggerContext.apply()). This leaves open file handles and 
is the source of the failing test FileOutputTest on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-609) StatusConfiguration doesn't close files

2014-04-21 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-609:
-

Description: 
{{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows you 
to specify a destination such as out, err or a file name. If specifying a 
file, that file stream is used when creating a {{StatusConsoleListener}} that 
is added to the {{StatusLogger}}. Those {{StatusLogger}} listeners are never 
cleaned up when, for example, the {{XmlConfiguration}} is reconfigured or when 
the {{LoggerContext}} is shut down (e.g. in {{InitialLoggerContext.apply()}}). 
This leaves open file handles and is the source of the failing test 
{{FileOutputTest}} on Windows.   (was: 
org.apache.logging.log4j.core.config.status.StatusConfiguration allows you to 
specify a destination such as out, err or a file name. If specifying a 
file, that file stream is used when creating a StatusConsoleListener that is 
added to the StatusLogger. Those StatusLogger listeners are never cleaned up 
when the XmlConfiguration is reconfigured or when the LoggerContext is shut 
down (e.g. in InitialLoggerContext.apply()). This leaves open file handles and 
is the source of the failing test FileOutputTest on Windows. )

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer

 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-04-21 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13976289#comment-13976289
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

It is also not clear to me why {{StatusConfiguration}} keeps a static reference 
to {{System.out}}. {{System.out}} can change over time. 

I've been digging into this for a little while because I wanted to provide a 
patch, but it is not obvious to me where the right place is to fix this. I 
could use some guidance, or I could let someone else take this one on. 

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer

 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-609) StatusConfiguration doesn't close files

2014-04-21 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13976301#comment-13976301
 ] 

Bruce Brouwer commented on LOG4J2-609:
--

Why is {{StatusConfiguration.configureExistingStatusConsoleListener}} 
reconfiguring all {{StatusConsoleListener}}s? If I had multiple 
{{LoggerContext}}s with different XML configurations, why should the newest 
{{LoggerContext}} be modifying the listeners from other {{LoggerContext}}s? If 
a {{LoggerContext}} is shutting down or being reconfigured, I would think it 
should only mess around with the listeners that it had registered. 

What I was thinking of doing was changing {{StatusConfiguration.initialize()}} 
to return a {{StatusConsoleListener}}, which {{XMLConfiguration}} could store 
in a field so that when {{XMLConfiguration.stop()}} or 
{{XMLConfiguration.reconfigure()}} is called, it can unregister just its own 
listener from the {{StatusLogger}}. Then it could add a new listener if 
necessary, such as when calling {{reconfigure()}}. Or maybe it keeps the 
{{StatusConfiguration}} object in a field instead and calls a new 
{{StatusConfiguration.stop()}} method that unregisters whatever it registered. 

I'm not an expert in here. Am I thinking about this correctly?

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer

 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-609) StatusConfiguration doesn't close files

2014-04-21 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13976301#comment-13976301
 ] 

Bruce Brouwer edited comment on LOG4J2-609 at 4/22/14 2:13 AM:
---

Why is {{StatusConfiguration.configureExistingStatusConsoleListener}} 
reconfiguring all {{StatusConsoleListener}} instances? If I had multiple 
{{LoggerContext}} instances with different XML configurations, why should the 
newest {{LoggerContext}} be modifying the listeners from other 
{{LoggerContext}} instances? If a {{LoggerContext}} is shutting down or being 
reconfigured, I would think it should only mess around with the listeners that 
it had registered. 

What I was thinking of doing was changing {{StatusConfiguration.initialize()}} 
to return a {{StatusConsoleListener}}, which {{XMLConfiguration}} could store 
in a field so that when {{XMLConfiguration.stop()}} or 
{{XMLConfiguration.reconfigure()}} is called, it can unregister just its own 
listener from the {{StatusLogger}}. Then it could add a new listener if 
necessary, such as when calling {{reconfigure()}}. Or maybe it keeps the 
{{StatusConfiguration}} object in a field instead and calls a new 
{{StatusConfiguration.stop()}} method that unregisters whatever it registered. 

I'm not an expert in here. Am I thinking about this correctly?


was (Author: bruce.brouwer):
Why is {{StatusConfiguration.configureExistingStatusConsoleListener}} 
reconfiguring all {{StatusConsoleListener}}s? If I had multiple 
{{LoggerContext}}s with different XML configurations, why should the newest 
{{LoggerContext}} be modifying the listeners from other {{LoggerContext}}s? If 
a {{LoggerContext}} is shutting down or being reconfigured, I would think it 
should only mess around with the listeners that it had registered. 

What I was thinking of doing was changing {{StatusConfiguration.initialize()}} 
to return a {{StatusConsoleListener}}, which {{XMLConfiguration}} could store 
in a field so that when {{XMLConfiguration.stop()}} or 
{{XMLConfiguration.reconfigure()}} is called, it can unregister just its own 
listener from the {{StatusLogger}}. Then it could add a new listener if 
necessary, such as when calling {{reconfigure()}}. Or maybe it keeps the 
{{StatusConfiguration}} object in a field instead and calls a new 
{{StatusConfiguration.stop()}} method that unregisters whatever it registered. 

I'm not an expert in here. Am I thinking about this correctly?

 StatusConfiguration doesn't close files
 ---

 Key: LOG4J2-609
 URL: https://issues.apache.org/jira/browse/LOG4J2-609
 Project: Log4j 2
  Issue Type: Bug
  Components: Core
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer

 {{org.apache.logging.log4j.core.config.status.StatusConfiguration}} allows 
 you to specify a destination such as out, err or a file name. If 
 specifying a file, that file stream is used when creating a 
 {{StatusConsoleListener}} that is added to the {{StatusLogger}}. Those 
 {{StatusLogger}} listeners are never cleaned up when, for example, the 
 {{XmlConfiguration}} is reconfigured or when the {{LoggerContext}} is shut 
 down (e.g. in {{InitialLoggerContext.apply()}}). This leaves open file 
 handles and is the source of the failing test {{FileOutputTest}} on Windows. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-547) Update LoggerStream API

2014-04-17 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-547:
-

Attachment: (was: log4j2-547-builders-and-more.patch)

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: 0001-PrintStream-API-update.patch, MyBenchmark.java, 
 PerfTestCalcLocation.java, log4j2-547-bbrouwer.patch, 
 log4j2-547-new-module.patch, log4j2-547-remove-streams.patch, 
 log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-547) Update LoggerStream API

2014-04-17 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13972262#comment-13972262
 ] 

Bruce Brouwer edited comment on LOG4J2-547 at 4/17/14 12:13 PM:


I like the builder idea too. I was just following the pattern that all other 
Java related streams take. So I decided to take a stab at it with 
log4j2-547-builders.patch.

Also in that patch are some things that I missed originally, so here's what it 
includes:
* LoggerStreams.Builder (and related classes)
* Updated log4j-bom to include streams
* Moved helper classes into a .helpers package

I haven't written the tests because I wanted to hear some feedback on the 
approach. 


was (Author: bruce.brouwer):
I like the builder idea too. I was just following the pattern that all other 
Java related streams take. So I decided to take a stab at it with 
log4j2-547-builders-and-more.patch.

Also in that patch are some things that I missed originally, so here's what it 
includes:
* Builders
* Updated log4j-bom to include streams
* Moved helper classes into a .helpers package

I haven't written the tests because I wanted to hear some feedback on the 
approach. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: 0001-PrintStream-API-update.patch, MyBenchmark.java, 
 PerfTestCalcLocation.java, log4j2-547-bbrouwer.patch, 
 log4j2-547-builders.patch, log4j2-547-new-module.patch, 
 log4j2-547-remove-streams.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-547) Update LoggerStream API

2014-04-17 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-547:
-

Attachment: log4j2-547-builders.patch

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: 0001-PrintStream-API-update.patch, MyBenchmark.java, 
 PerfTestCalcLocation.java, log4j2-547-bbrouwer.patch, 
 log4j2-547-builders.patch, log4j2-547-new-module.patch, 
 log4j2-547-remove-streams.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-547) Update LoggerStream API

2014-04-16 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-547:
-

Attachment: log4j2-547-builders-and-more.patch

I like the builder idea too. I was just following the pattern that all other 
Java related streams take. So I decided to take a stab at it with 
log4j2-547-builders-and-more.patch.

Also in that patch are some things that I missed originally, so here's what it 
includes:
* Builders
* Updated log4j-bom to include streams
* Moved helper classes into a .helpers package

I haven't written the tests because I wanted to hear some feedback on the 
approach. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: 0001-PrintStream-API-update.patch, MyBenchmark.java, 
 PerfTestCalcLocation.java, log4j2-547-bbrouwer.patch, 
 log4j2-547-builders-and-more.patch, log4j2-547-new-module.patch, 
 log4j2-547-remove-streams.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-13 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13967953#comment-13967953
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

* I like the new fluent API. 
* Do you think it will be confusing that we have one method called simply set, 
add or remove, while the getter is called getParents()? I'm thinking 
particularly about the set vs. getParents. 
* You synchronized add and remove, but not set. I know it isn't absolutely 
necessary, but might it cause confusing behavior if some race condition 
occurred from client code calling add and set concurrently? I doubt 
synchronizing set is going to cause serious performance problems. 
* Commentary: Alternatively, in getParents, you could simply return 
{{Arrays.copyOf(this.parents, this.parents.length);}} instead of creating a 
temporary array and calling {{System.arraycopy(...)}}. But what you wrote works 
perfectly fine. 
* It looks like you implemented what I asked regarding 
{{this.isInstanceOf(parent)}} by implementing that {{contains}} method. I like 
it. Thanks. 
* I see you deprecated the getMarker methods that specify a parent. Thanks. Is 
it the plan to remove deprecated methods before 2.0 GA? 

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Resolved] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-13 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer resolved LOG4J2-585.
--

   Resolution: Fixed
Fix Version/s: 2.0-rc2

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Fix For: 2.0-rc2

 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-547) Update LoggerStream API

2014-04-13 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-547:
-

Attachment: log4j2-547-new-module.patch

I've added log4j2-547-new-module.patch. It makes a new module called 
log4j-streams. It also changes the direction of looking for FQCN. It also 
includes tests to show that FQCN works for the streams. As I cannot create a 
branch, I'm providing this patch. You can decide how to apply this patch, 
either as a branch or into trunk. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: 0001-PrintStream-API-update.patch, MyBenchmark.java, 
 PerfTestCalcLocation.java, log4j2-547-bbrouwer.patch, 
 log4j2-547-new-module.patch, log4j2-547-remove-streams.patch, 
 log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13961566#comment-13961566
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

So, here are my thoughts. Maybe some of these should be made into new JIRAs.
* Are we ok with getMarker sometimes creating a marker with the specified 
parents and sometimes returning a marker with a potentially different parent 
hierarchy? This is why my concept renamed those methods to define(name, 
parents...). 
* Do we want a version of getMarker (or define) that takes a list of parent 
marker names, in addition to the new one that takes a list of marker instances?
* Should it be ok to add a parent twice in the hierarchy, once as a grand 
parent, once as a parent? If I was allowed to add marker X as an immediate 
parent of Y when X already existed as a grandparent, then removing the X 
grandparent would allow marker Y to remain an instance of X. The current 
implementation would not allow me to add X as a parent of Y and thus removing 
grandparent X would make Y no longer an instance of X, even though I explicitly 
specified I wanted X to be an immediate parent of Y. (This one is pretty minor 
and I'm willing to accept what is done)
* Log4jMarker.getParents() should return a copy of the array so I can't change 
the contents from outside the control of log4j
* Would a switch statement in Log4jMarker.isInstanceOf provide better 
performance, so there aren't multiple length checks?
* slf4j-impl Log4jMarker is still backwards, treating parents as children and 
children as parents. My concept code showed how I took care of this. In most 
cases, there is no real performance penalty.
* In slf4j-impl Log4jMarkerFactory.getDetachedMarker(), my impression was that 
it should create a marker that wasn't actually attached yet to log4j, but by 
adding it as a child to a parent that is attached would then make it attached. 
This implementation essentially creates the slf4j marker as already attached.

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13961566#comment-13961566
 ] 

Bruce Brouwer edited comment on LOG4J2-585 at 4/6/14 11:44 PM:
---

So, here are my thoughts. Maybe some of these should be made into new JIRAs.
* Are we ok with getMarker sometimes creating a marker with the specified 
parents and sometimes returning a marker with a potentially different parent 
hierarchy? This is why my concept renamed those methods to define(name, 
parents...). 
* Do we want a version of getMarker (or define) that takes a list of parent 
marker names, in addition to the new one that takes a list of marker instances?
* Should it be ok to add a parent twice in the hierarchy, once as a grand 
parent, once as a parent? If I was allowed to add marker X as an immediate 
parent of Y when X already existed as a grandparent, then removing the X 
grandparent would allow marker Y to remain an instance of X. The current 
implementation would not allow me to add X as a parent of Y and thus removing 
grandparent X would make Y no longer an instance of X, even though I explicitly 
specified I wanted X to be an immediate parent of Y. (This one is pretty minor 
and I'm willing to accept what is done)
* Log4jMarker.getParents() should return a copy of the array so I can't change 
the contents from outside the control of log4j
* Would a switch statement in Log4jMarker.isInstanceOf provide better 
performance, so there aren't multiple length checks?
* In slf4j-impl Log4jMarkerFactory.getDetachedMarker(), my impression was that 
it should create a marker that wasn't actually attached yet to log4j, but by 
adding it as a child to a parent that is attached would then make it attached. 
This implementation essentially creates the slf4j marker as already attached.


was (Author: bruce.brouwer):
So, here are my thoughts. Maybe some of these should be made into new JIRAs.
* Are we ok with getMarker sometimes creating a marker with the specified 
parents and sometimes returning a marker with a potentially different parent 
hierarchy? This is why my concept renamed those methods to define(name, 
parents...). 
* Do we want a version of getMarker (or define) that takes a list of parent 
marker names, in addition to the new one that takes a list of marker instances?
* Should it be ok to add a parent twice in the hierarchy, once as a grand 
parent, once as a parent? If I was allowed to add marker X as an immediate 
parent of Y when X already existed as a grandparent, then removing the X 
grandparent would allow marker Y to remain an instance of X. The current 
implementation would not allow me to add X as a parent of Y and thus removing 
grandparent X would make Y no longer an instance of X, even though I explicitly 
specified I wanted X to be an immediate parent of Y. (This one is pretty minor 
and I'm willing to accept what is done)
* Log4jMarker.getParents() should return a copy of the array so I can't change 
the contents from outside the control of log4j
* Would a switch statement in Log4jMarker.isInstanceOf provide better 
performance, so there aren't multiple length checks?
* slf4j-impl Log4jMarker is still backwards, treating parents as children and 
children as parents. My concept code showed how I took care of this. In most 
cases, there is no real performance penalty.
* In slf4j-impl Log4jMarkerFactory.getDetachedMarker(), my impression was that 
it should create a marker that wasn't actually attached yet to log4j, but by 
adding it as a child to a parent that is attached would then make it attached. 
This implementation essentially creates the slf4j marker as already attached.

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that 

[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13961593#comment-13961593
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

* Well, my recommendation in using define is that it would actually change the 
parent hierarchy to be what is listed, so it is different than the current 
.getMarker(...). This way if I wasn't careful in my code, I wouldn't have to 
worry about the order of calls between .getMarker(name) and .define(name, 
parents...) (think if my markers are static member variables and I have little 
control over the order of class initialization). If getMarker(name) did somehow 
get called before define(name, parents...) they would both be pointing at the 
same marker and with the parent heirarchy I desired. I just now need to make 
sure that I only call define(name, parents...) once for each marker name. 
* Cool, thanks
* I'm not talking about a cycle. I agree we need to avoid cycles. given A - B 
- C (A is child, B is parent, C is grand parent). If I add C to A, there is no 
cycle, it just is doubly parented on C. The cycle would happen if I tried to 
add A as a parent of C. The check {{parent.isInstanceOf(this)}} is completely 
valid and is what checks for the cycle. The check {{this.isInstanceOf(parent)}} 
is what I'm asking to change to only check immediate parents.
* Cool, thanks
* When I implemented this in my concept, I simply had the marker reference be 
null until it was attached. Once I add that detached marker to another attached 
marker, my reference to the detached marker should be considered invalid. Any 
use of it with the contains method against an attached marker should return 
false, even if there was an attached marker with the same name that was 
contained by the attached marker. When the marker is attached, I'm not asking 
to stop using the == check, I think that part is perfect. But I do understand 
that this makes the add method considerably more complicated, partly because it 
would need to check for cycles by checking parent names instead of ==, and 
partly because I might be attaching an entire parent hierarchy, not just a 
single marker. (I'm sure I'm just securing in your mind that it isn't worth it, 
aren't I?)

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13961604#comment-13961604
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

* But we've made other breaking changes since RC1. Now, maybe they haven't 
broken the use of log4j-api, but changes have happened in log4j-core that could 
cause breakage. Should I make it a separate JIRA and see what others have to 
say? 
* Thanks
* Honestly, I don't quite understand the point of detached markers. So I agree 
there is going to be very little benefit to this. And if someone finds a real 
use case that isn't handled, we can always fix it later. 

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-05 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-585:
-

Attachment: CurrentMarkerBenchmark.java
ConceptMarkerBenchmark.java

Here are the benchmark classes I was using. They're pretty simple, just dealing 
with a single parent for each marker in order to compare the current vs. 
concept. 

I had an idea to try out myself with volatile references to immutable arrays 
where the array references are replaced when the parents change. Maybe that 
will be faster to iterate over than checking if something is in a 
ConcurrentHashMap.  

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-05 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13961148#comment-13961148
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

Why make that rule that parents added during construction cannot be removed? If 
we allow any modification, it doesn't make sense to me why we would restrict 
those modifications. I suppose I'm asking you to convince me why that is 
better. 

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-05 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13961199#comment-13961199
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

So, are you saying that the only benefit is that I am guaranteed that some 
relationships cannot be modified? That seems like it would add complexity if 
some relationships can be modified and not others. Why can't I just make sure 
my client code never modifies those relationships?

I went ahead and tried the volatile immutable arrays, and it definitely helps. 
Here's my results:
||Depth||Current||Concept worst||Concept average
| 3 | 340K ops/ms | 280K ops/ms (17% slower) | 380K ops/ms (12% faster)
| 2 | 680K ops/ms | 360K ops/ms (47% slower) | 430K ops/ms (36% slower)
| 1 | 1230K ops/ms | 500K ops/ms (60% slower) | same as worst
| 0 | 2550K ops/ms | 2000K ops/ms (21% slower) | same as worst

The difference between Concept Worst and Concept Average is because it 
might not take x number of checks for a parent that is x levels away. On 
average, it would take only x/2 checks since all parent names are merged 
together for testing purposes. As you can see, the average case is already 
faster now at 3 levels deep. I don't think there is any way to get the 0 and 1 
level deep tests to be faster than what we have currently as the current 
implementation simply needs to check one or two variables, rather than 
iterating over an array.

But in the end, we're talking about hundreds of millions of {{isInstanceOf}} 
invocations per second. This marker test is only one small part of the entire 
logging performance picture. And it is only going to cause a small (and I think 
very small) penalty for those who even use the markers.

The benefit is a more flexible marker hierarchy and full support for slf4j. 

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-05 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13961223#comment-13961223
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

{{java -jar target/microbenchmark.jar -t 8}}

So, 8 concurrent threads running on a Windows 7 4-core machine.

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: ConceptMarkerBenchmark.java, 
 CurrentMarkerBenchmark.java, log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-04 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13960867#comment-13960867
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

So another idea I had is along the lines of what Gary was proposing. So we have 
MarkerManager today, which is analogous to LogManager. But instead of 
MarkerManager holding onto a static map of markers, what if the LoggerContext 
is what actually kept track of all the markers, like it keeps track of all the 
Loggers. 

And like LoggerContext now returns LoggerProviders, LoggerContext could return 
MarkerProviders, while the MarkerManager static methods would return simple 
Markers. This would allow the public Marker API to be simpler than the Marker 
SPI. The Marker SPI could have the methods that make markers mutable. The only 
thing I can think that the API would be missing that the SPI has would be the 
{{getParents}} method. 

With this approach, there could be two LoggerContexts, each with their own 
marker hierarchy, rather than one set of markers that everything shares. 

Does this approach sound more palatable? I don't think it would be too hard to 
switch my concept over to this approach.

Also, are the issues I've identified recognized as real issues? (e.g. 
slf4j-impl markers having almost no relation to log4j markers) If the rest of 
the team doesn't agree with me, I'll stop spending time on this. I will be 
using log4j 2 primarily through the slf4j interface and I personally see this 
as a real problem that needs to be fixed before 2.0.

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-03 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-585:
-

Attachment: log4j2-585-concept.patch

Here is a log4j2-585-concept.patch that outlines my ideas for the Markers. It 
is merely a concept and not intended to be committed yet. I'm sure I've 
probably gone too far in some areas, but hear me out first. 

For performance, I checked with JMH. So long as the marker hierarchy is no more 
than 5 deep, the current Log4j code is faster, but after 5 deep, my concept is 
faster than the current Log4j code. For the normal case of only one parent, the 
current Log4j code can perform about 600,000 ops/ms, while my concept performs 
about 200,000 ops/ms. A simpler version of my concept that did not include the 
allParentNames variable was much slower, clocking in at only about 10,000 
ops/ms. 

The big driver behind my concept was to make Log4j Markers just as powerful as 
slf4j. This means primarily two things: mutability and multiple parents. 

First, I got rid of MarkerManager and turned Marker into a concrete, final 
class. By making Marker an interface, clients might be inclined to implement 
the interface themselves and cause issues because the parent hierarchy of their 
markers would likely not match the parent hierarchy of Log4j's markers. It is 
because of this that I don't like the idea of pluggable Marker factories. 

Next, my ReadWriteLock is static. I did this to avoid creating a ton of lock 
objects for each Marker. The majority of time, marker hierarchies are not 
changing, so a lock that blocks most marker functions during an update is 
likely not a concern. Furthermore, the most prevalent cases, such as calling 
isInstanceOf, are not even guarded by a lock and allow ConcurrentHashMap to 
provide all the performance possible.

getParents() is not a SetMarker instead of a simple Marker. This allows 
multiple parents. I went with a custom Set implementation to be able to react 
to changes to the parents set, which is used primarily to keep allParentNames 
up to date. 

The static methods that used to be on MarkerManager are not on Marker. 

Marker.get works exactly like MarkerManager.getMarker. An overloaded version 
allows you to indicate if you want a marker created if it does not exist. This 
was necessary for use in the Slf4j-impl, but I could see it being valuable 
elsewhere, too.

Marker.define works a little bit like MarkerManager.getMarker(name, parent), 
but because Markers are not mutable, it ensures that the parents become the set 
provided here. I like the name define better because it is clear to me that 
this will make the marker look the way I just described. I did not like 
MarkerManager.getMarker(name, parent) because it does not guarantee me that the 
returned marker even has the specified parent. If the marker was created 
earlier to this call, it won't have my specified parent. 

Marker.undefine allows markers to be removed, which is a feature of slf4j and 
it was fairly easy to support here. 

So, is it worth a bit of a performance penalty to get all these features in 
Markers? 

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we 

[jira] [Comment Edited] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-03 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13958801#comment-13958801
 ] 

Bruce Brouwer edited comment on LOG4J2-585 at 4/3/14 1:24 PM:
--

Here is a log4j2-585-concept.patch that outlines my ideas for the Markers. It 
is merely a concept and not intended to be committed yet. I'm sure I've 
probably gone too far in some areas, but hear me out first. 

For performance, I checked with JMH. So long as the marker hierarchy is no more 
than 5 deep, the current Log4j code is faster, but after 5 deep, my concept is 
faster than the current Log4j code. For the normal case of only one parent, the 
current Log4j code can perform about 600,000 ops/ms, while my concept performs 
about 200,000 ops/ms. A simpler version of my concept that did not include the 
allParentNames variable was much slower, clocking in at only about 10,000 
ops/ms. 

The big driver behind my concept was to make Log4j Markers just as powerful as 
slf4j. This means primarily two things: mutability and multiple parents. 

First, I got rid of MarkerManager and turned Marker into a concrete, final 
class. By making Marker an interface, clients might be inclined to implement 
the interface themselves and cause issues because the parent hierarchy of their 
markers would likely not match the parent hierarchy of Log4j's markers. It is 
because of this that I don't like the idea of pluggable Marker factories. 

Next, my ReadWriteLock is static. I did this to avoid creating a ton of lock 
objects for each Marker. The majority of time, marker hierarchies are not 
changing, so a lock that blocks most marker functions during an update is 
likely not a concern. Furthermore, the most prevalent cases, such as calling 
isInstanceOf, are not even guarded by a lock and allow ConcurrentHashMap to 
provide all the performance possible.

getParents() is now a SetMarker instead of a simple Marker. This allows 
multiple parents. I went with a custom Set implementation to be able to react 
to changes to the parents set, which is used primarily to keep allParentNames 
up to date. 

The static methods that used to be on MarkerManager are now on Marker. 

Marker.get works exactly like MarkerManager.getMarker. An overloaded version 
allows you to indicate if you want a marker created if it does not exist. This 
was necessary for use in the Slf4j-impl, but I could see it being valuable 
elsewhere, too.

Marker.define works a little bit like MarkerManager.getMarker(name, parent), 
but because Markers are now mutable, it ensures that the parents become the 
list provided here. I like the name define better because it is clear to me 
that this will make the marker look the way I just described. I did not like 
MarkerManager.getMarker(name, parent) because it does not guarantee me that the 
returned marker even has the specified parent. If the marker was created 
earlier to this call, it won't have my specified parent. 

Marker.undefine allows markers to be removed, which is a feature of slf4j and 
it was fairly easy to support here. 

So, is it worth a bit of a performance penalty to get all these features in 
Markers? 


was (Author: bruce.brouwer):
Here is a log4j2-585-concept.patch that outlines my ideas for the Markers. It 
is merely a concept and not intended to be committed yet. I'm sure I've 
probably gone too far in some areas, but hear me out first. 

For performance, I checked with JMH. So long as the marker hierarchy is no more 
than 5 deep, the current Log4j code is faster, but after 5 deep, my concept is 
faster than the current Log4j code. For the normal case of only one parent, the 
current Log4j code can perform about 600,000 ops/ms, while my concept performs 
about 200,000 ops/ms. A simpler version of my concept that did not include the 
allParentNames variable was much slower, clocking in at only about 10,000 
ops/ms. 

The big driver behind my concept was to make Log4j Markers just as powerful as 
slf4j. This means primarily two things: mutability and multiple parents. 

First, I got rid of MarkerManager and turned Marker into a concrete, final 
class. By making Marker an interface, clients might be inclined to implement 
the interface themselves and cause issues because the parent hierarchy of their 
markers would likely not match the parent hierarchy of Log4j's markers. It is 
because of this that I don't like the idea of pluggable Marker factories. 

Next, my ReadWriteLock is static. I did this to avoid creating a ton of lock 
objects for each Marker. The majority of time, marker hierarchies are not 
changing, so a lock that blocks most marker functions during an update is 
likely not a concern. Furthermore, the most prevalent cases, such as calling 
isInstanceOf, are not even guarded by a lock and allow ConcurrentHashMap to 
provide all the performance possible.

getParents() is not a SetMarker 

[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-03 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13959213#comment-13959213
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

The problem with creating all new immutable markers is that there are likely to 
be references to the old markers all throughout the code that are now invalid. 
Now, I suppose I have opened up that possibility now by allowing markers to be 
undefined and then redefined, but I think that is an even more rare case that 
we don't need to be concerned with.

The other idea is something that I hadn't considered of before. I'm assuming 
you mean marker x.y.z would have a parent of x.y, which has a parent of 
x. However, this fails to give the ability to have multiple parents

If we went a completely different route and just had markers be interfaces, I 
could see code like this:

{code}
public interface MyFirstParentMarker { }
public interface MySecondParentMarker { }
public interface MyChildMarker extends MyFirstParentMarker, 
MySecondParentMarker { }
{code}

This has a few problems, too. First, I have no idea how we could get it to work 
with slf4j which is based upon marker names being strings, not a Java type 
hierarchy. Second, how do we reference these markers? Would we do it like this:

{code}
private final static ClassMyChildMarker myChildMarker = MyChildMarker.class;
{code}

Or would we do something with Java proxies: 

{code}
private final static MyChildMarker myChildMarker = 
MarkerManager.get(MyChildMarker.class);

public class MarkerManager {
  public static T T get(ClassT markerType) {
return java.lang.reflect.Proxy.proxyClass(markerType);
  }
}
{code}

I like this idea, except that I don't see a way to make it work with slf4j. 

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-585) Markers not as powerful as slf4j

2014-04-03 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13959213#comment-13959213
 ] 

Bruce Brouwer edited comment on LOG4J2-585 at 4/3/14 9:04 PM:
--

The problem with creating all new immutable markers is that there are likely to 
be references to the old markers all throughout the code that are now invalid. 
Now, I suppose I have opened up that possibility now by allowing markers to be 
undefined and then redefined, but I think that is an even more rare case that 
we don't need to be concerned with.

The other idea is something that I hadn't considered of before. I'm assuming 
you mean marker x.y.z would have a parent of x.y, which has a parent of 
x. However, this fails to give the ability to have multiple parents

If we went a completely different route and just had markers be interfaces, I 
could see code like this:

{code}
public interface MyFirstParentMarker extends Marker { }
public interface MySecondParentMarker extends Marker { }
public interface MyChildMarker extends MyFirstParentMarker, 
MySecondParentMarker { }
{code}

This has a few problems, too. First, I have no idea how we could get it to work 
with slf4j which is based upon marker names being strings, not a Java type 
hierarchy. Second, how do we reference these markers? The best idea I can come 
up with here is to change the log4j-api to take a {{Class? extends Marker 
marker}} instead of {{Marker marker}}. Now there is no need for a MarkerManager 
as the Java class loader takes care of it for me. 

I like this idea, except that I don't see a way to make it work with slf4j. 


was (Author: bruce.brouwer):
The problem with creating all new immutable markers is that there are likely to 
be references to the old markers all throughout the code that are now invalid. 
Now, I suppose I have opened up that possibility now by allowing markers to be 
undefined and then redefined, but I think that is an even more rare case that 
we don't need to be concerned with.

The other idea is something that I hadn't considered of before. I'm assuming 
you mean marker x.y.z would have a parent of x.y, which has a parent of 
x. However, this fails to give the ability to have multiple parents

If we went a completely different route and just had markers be interfaces, I 
could see code like this:

{code}
public interface MyFirstParentMarker { }
public interface MySecondParentMarker { }
public interface MyChildMarker extends MyFirstParentMarker, 
MySecondParentMarker { }
{code}

This has a few problems, too. First, I have no idea how we could get it to work 
with slf4j which is based upon marker names being strings, not a Java type 
hierarchy. Second, how do we reference these markers? Would we do it like this:

{code}
private final static ClassMyChildMarker myChildMarker = MyChildMarker.class;
{code}

Or would we do something with Java proxies: 

{code}
private final static MyChildMarker myChildMarker = 
MarkerManager.get(MyChildMarker.class);

public class MarkerManager {
  public static T T get(ClassT markerType) {
return java.lang.reflect.Proxy.proxyClass(markerType);
  }
}
{code}

I like this idea, except that I don't see a way to make it work with slf4j. 

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer
 Attachments: log4j2-585-concept.patch


 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private 

[jira] [Created] (LOG4J2-585) Markers not as powerful as slf4j

2014-03-30 Thread Bruce Brouwer (JIRA)
Bruce Brouwer created LOG4J2-585:


 Summary: Markers not as powerful as slf4j
 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer


Log4J's markers are not as flexible as markers in SLF4J. 

First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
change the relationship of markers to each other based upon runtime or business 
conditions. 

Second, and more importantly I think, is that essentially SLF4J markers have 
this parent/child relationship, much like Log4J, except that in SLF4J, I can 
essentially have a marker with multiple parents. For example, I might want this 
structure:
* Animal
** Bird
*** Duck
** Mammal
*** Bear
*** Dolphin
* Travels by
** Water
*** Duck
*** Dolphin
** Land
*** Duck
*** Bear
** Air
*** Duck

Of course, this is a contrived example, but I wanted to describe the 
relationships. Now, if I wanted to filter based on markers that travel by Water 
for some appenders, and another appender wants to filter by Mammals, I can't 
simply use the single marker of Dolphin. 

Either we need to reverse the marker relationship so that it contains its 
children, much like SLF4J, or we allow markers to have multiple parents, which 
I prefer because it could make it more succinct to define:
{code}
private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
BY_WATER);
{code}

As for the Marker API, we would either need to change getParent to getParents, 
or get rid of the getParent method from the API and just rely on the 
isInstanceOf method to handle checking multiple parents by looking at private 
member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-03-30 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13954753#comment-13954753
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

About the performance, I suspected what Ralph is saying would be a very real 
concern. I looked at the way BasicMarker is implemented and there is nothing 
that requires us to extend from BasicMarker. I was playing around with an 
implementation that used a ReentrantReadWriteLock. In most cases, the time 
spend modifying markers is only in the startup of the app. So I agree, slapping 
a synchronized on the most important methods is a huge performance bottleneck. 
But with the ReentrantReadWriteLock, the major time of an application would 
cause no blocking at all. 

I also have some ideas on how we could get the performance of the regular Log4J 
markers better than they are today at the expense of a little bit more memory. 

Also, if we made the Log4J markers mutable, then we could have the SLF4J 
implementation simply delegate to the real Log4J markers. Right now, the two 
are completely separate. If you have code that mixes Log4J markers with SLF4J 
markers (because of some 3rd party library that uses SLF4J) the hierarchies can 
be completely different. This is probably not what people would expect to have 
happen. I think it will also have real issues when used with the MarkerFilter, 
which would be referencing a real log4j Marker while comparing against an SLF4J 
marker. 

Another thing that I noticed is that I think the SLF4J implementation is 
broken. SLF4J intends the pointers to be pointing at the children. Log4J 
intends the pointers to be to the parent. Because of this, the implementation 
of MarkerWrapper.isInstanceOf is backwards.

I would like to fix this immutability issue, but the issue of allowing multiple 
parents I think more important, and one that is easy to fix. Would I have 
support of changing these things if I submitted a patch? Especially if I took 
careful consideration for performance issues?

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer

 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-03-30 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13954805#comment-13954805
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

Cool. So, in my patch, when I make log4j Markers mutable, I will make sure read 
operations are as performant as possible, but for operations that modify 
markers, I am not going to spend a lot of effort making those highly performant 
as I think read operations are for more important. 

Of the items in the concurrent collections, the one that seemed promising to me 
for this situation was ConcurrentHashMap, but it does not maintain the original 
order. The only place where I think order might have some impact when allowing 
multiple parents is in the toString method. It wouldn't keep the order that was 
specified when creating the marker with parents. Do you think order is 
important in the toString method? Could I get away with just sorting the parent 
names for .toString()? If so, then I can seriously consider ConcurrentHashMap. 
Otherwise I'll have to go with another collection and use the 
ReentrantReadWriteLock.

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer

 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-585) Markers not as powerful as slf4j

2014-03-30 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13954805#comment-13954805
 ] 

Bruce Brouwer edited comment on LOG4J2-585 at 3/30/14 7:12 PM:
---

Cool. So, in my patch, when I make log4j Markers mutable, I will make sure read 
operations are as performant as possible, but for operations that modify 
markers, I am not going to spend a lot of effort making those highly performant 
as I think read operations are far more important. 

Of the items in the concurrent collections, the one that seemed promising to me 
for this situation was ConcurrentHashMap, but it does not maintain the original 
order and I don't really need the Map feature, just Set. The only place where I 
think order might have some impact when allowing multiple parents is in the 
toString method. It wouldn't keep the order that was specified when creating 
the marker with parents. Do you think order is important in the toString 
method? Could I get away with just sorting the parent names for .toString()? If 
so, then I can seriously consider ConcurrentHashMap. Otherwise I'll have to go 
with another collection and use the ReentrantReadWriteLock.


was (Author: bruce.brouwer):
Cool. So, in my patch, when I make log4j Markers mutable, I will make sure read 
operations are as performant as possible, but for operations that modify 
markers, I am not going to spend a lot of effort making those highly performant 
as I think read operations are for more important. 

Of the items in the concurrent collections, the one that seemed promising to me 
for this situation was ConcurrentHashMap, but it does not maintain the original 
order. The only place where I think order might have some impact when allowing 
multiple parents is in the toString method. It wouldn't keep the order that was 
specified when creating the marker with parents. Do you think order is 
important in the toString method? Could I get away with just sorting the parent 
names for .toString()? If so, then I can seriously consider ConcurrentHashMap. 
Otherwise I'll have to go with another collection and use the 
ReentrantReadWriteLock.

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer

 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-585) Markers not as powerful as slf4j

2014-03-30 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-585?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13954878#comment-13954878
 ] 

Bruce Brouwer commented on LOG4J2-585:
--

Interesting. I don't know if it makes sense for each logger to have a marker 
factory, but in the way we have different LoggerContextFactory implementations, 
we could have different MarkerFactory implementations. log4j-slf4j-impl could 
provide an alternate MarkerFactory. I don't know if I like the idea of simply 
including log4j-slf4j-impl and having it switch the implementation of 
MarkerFactory without me realizing it. But I suppose that is what happens when 
I include log4j-core with LoggerContextFactory. It seems different to me, 
somehow. I would expect log4j-slf4j-impl to be a thin wrapper around the real 
log4j implementation, including the markers. 

I was actually thinking a bit about the Marker interface. If we don't go with 
the MarkerFactory idea, what is the point of having Marker be an interface? It 
should be a concrete final class to prevent anyone or anything making other 
kinds of Markers. I could see weird things happening if we pass an SLF4J marker 
with one hierarchy passed into a Log4J marker's .isInstanceOf method. We could 
run into a situation where slf4jMarker.isInstanceOf(log4jMarker) returns true 
and also log4jMarker.isInstanceOf(slf4jMarker) returns true, event though they 
are not themselves equal. This doesn't really make good logical sense. The only 
impact I think would be that the log4j-slf4j-impl MarkerWrapper couldn't 
implement Marker, but would rather need to provide a getter. 

I'm willing to put in some time developing this, even at the risk of not using 
it if it proves to be too big of a performance hit. But if we don't go down 
this road, we run into the problem of the SLF4J marker hierarchy possibly being 
inconsistent with the Log4j marker hierarchy and having some of the weird 
behavior I described.

 Markers not as powerful as slf4j
 

 Key: LOG4J2-585
 URL: https://issues.apache.org/jira/browse/LOG4J2-585
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Bruce Brouwer

 Log4J's markers are not as flexible as markers in SLF4J. 
 First, SLF4J's markers are mutable. By allowing markers to be mutable, I can 
 change the relationship of markers to each other based upon runtime or 
 business conditions. 
 Second, and more importantly I think, is that essentially SLF4J markers have 
 this parent/child relationship, much like Log4J, except that in SLF4J, I can 
 essentially have a marker with multiple parents. For example, I might want 
 this structure:
 * Animal
 ** Bird
 *** Duck
 ** Mammal
 *** Bear
 *** Dolphin
 * Travels by
 ** Water
 *** Duck
 *** Dolphin
 ** Land
 *** Duck
 *** Bear
 ** Air
 *** Duck
 Of course, this is a contrived example, but I wanted to describe the 
 relationships. Now, if I wanted to filter based on markers that travel by 
 Water for some appenders, and another appender wants to filter by Mammals, I 
 can't simply use the single marker of Dolphin. 
 Either we need to reverse the marker relationship so that it contains its 
 children, much like SLF4J, or we allow markers to have multiple parents, 
 which I prefer because it could make it more succinct to define:
 {code}
 private static final Marker BY_LAND = MarkerManager.getMarker(BY_LAND);
 private static final Marker BY_WATER = MarkerManager.getMarker(BY_WATER);
 private static final Marker DUCK = MarkerManager.getMarker(DUCK, BY_LAND, 
 BY_WATER);
 {code}
 As for the Marker API, we would either need to change getParent to 
 getParents, or get rid of the getParent method from the API and just rely on 
 the isInstanceOf method to handle checking multiple parents by looking at 
 private member variables (my preference)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-547) Update LoggerStream API

2014-03-25 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-547:
-

Attachment: log4j2-547-remove-streams.patch

Perhaps we can agree to at least remove the streaming stuff from log4j-api. 
This way if we can't resolve the streaming solution before 2.0, we at least 
won't have it in the API where it will have to be supported forever.

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: 0001-PrintStream-API-update.patch, MyBenchmark.java, 
 PerfTestCalcLocation.java, log4j2-547-bbrouwer.patch, 
 log4j2-547-remove-streams.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-23 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13944619#comment-13944619
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

My comments of performance were me remembering the code I saw in 
{{ClassLoaderContextSelector}}, which I think actually doesn't come into play 
in this scenario. So, it probably is as simple as getting the stack trace (the 
expensive part) and iterating over the list doing a few string comparisons 
(maybe a few hundred). Would it help if I made a little performance test 
comparison? 

As for my comment about top-down being more technically correct, I was thinking 
that in the short stack trace example that Remko outlined, I think the top 
LoggerPrintStream should report its caller as 
{{FilterOutputStream.someMethod()}}, not 
{{ApplicationClass_TheCaller.theMethod()}}. However, in probably 90%+ of cases, 
the more useful caller to report would be 
{{ApplicationClass_TheCaller.theMethod()}}, which would be discovered by the 
bottom-up approach. It's an interesting edge case, but probably not worth 
worrying about. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: 0001-PrintStream-API-update.patch, 
 log4j2-547-bbrouwer.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-547) Update LoggerStream API

2014-03-23 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-547:
-

Attachment: PerfTestCalcLocation.java

I decided to run a quick performance test. You can see the tester code in 
{{PerfTestCalcLocation.java}}, which I attached. The alternate {{calcLocation}} 
code I wrote looks like this (which is actually much simpler than the current 
code:

{code}
public static StackTraceElement calcLocation2(final String fqcnOfLogger) {
if (fqcnOfLogger == null) {
return null;
}
final StackTraceElement[] stackTrace = 
Thread.currentThread().getStackTrace();

// start 2 below, just in case the last entry happens to match the FQCN
for (int i = stackTrace.length - 2; i = 0; i--) {
if (fqcnOfLogger.equals(stackTrace[i].getClassName())) {
return stackTrace[i + 1];
}
}
return null;
}
{code}

And here are the performance results:
{code}
10 deep: Top-down: 83653 ops/sec, bottom-up: 86745 ops/sec, -3.5644684% slower
50 deep: Top-down: 24557 ops/sec, bottom-up: 24033 ops/sec, 2.180336% slower
100 deep: Top-down: 12854 ops/sec, bottom-up: 12927 ops/sec, -0.5647125% slower
200 deep: Top-down: 6640 ops/sec, bottom-up: 6640 ops/sec, 0.0% slower
500 deep: Top-down: 2623 ops/sec, bottom-up: 2630 ops/sec, -0.26615906% slower
{code}

It appears that the direction we traverse the stack trace has negligible impact 
on the performance, no matter how deep the stack trace. I've never seen the 
results go above 3% slower over multiple runs, and often, it shows it going 
faster. 

So if performance is the only concern, I kind of like the idea of switching to 
the bottom-up approach. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: 0001-PrintStream-API-update.patch, 
 PerfTestCalcLocation.java, log4j2-547-bbrouwer.patch, 
 log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-547) Update LoggerStream API

2014-03-23 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-547:
-

Attachment: MyBenchmark.java

I took a stab at JMH. When I pulled out the code that actually takes the stack 
trace (using a pre-generated stack trace) and left only the iterating code, it 
shows the current code to be *much* faster. However, when you throw in the 
generation of the stack trace, it looks like it becomes inconsequential. Here 
are the results for a stack trace that is 200 entries deep. 
{code}
BenchmarkMode   Samples Mean   Mean errorUnits
o.s.MyBenchmark.bottomUpthrpt   2006.9230.036   ops/ms
o.s.MyBenchmark.topDown thrpt   2006.9130.034   ops/ms
{code}
I've attached the benchmark code, too as {{MyBenchmark.java}}. This could be 
skewed somewhat as part of this time is spent making a recursive call of 208 
methods deep just to make the call to build the stack trace, but I wasn't 
coming up with a better way to generate the stack trace and have it be part of 
the benchmark results. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: 0001-PrintStream-API-update.patch, MyBenchmark.java, 
 PerfTestCalcLocation.java, log4j2-547-bbrouwer.patch, 
 log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Closed] (LOG4J2-562) Improve ability to create custom extended logger

2014-03-23 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-562?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer closed LOG4J2-562.


Resolution: Not A Problem

It seems like everyone is comfortable with what is in LOG4J2-555.

 Improve ability to create custom extended logger
 

 Key: LOG4J2-562
 URL: https://issues.apache.org/jira/browse/LOG4J2-562
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Reporter: Bruce Brouwer
 Attachments: log4j2-loggerExtension.patch


 Create a LoggerExtension from the original logger which simply remembers the 
 FQCN that will ultimately be the extension. 
 Also by doing this, we can switch a bunch of methods that ended up being 
 public back to protected. I'm guessing they became public so extensions could 
 call them. 
 This can simplify extensions (such as slf4j, jcl, custom extensions, logger 
 streams) so they don't have to pass in the FQCN to that special log method on 
 AbstractLogger anymore. Also, you don't have to wrap every extended log 
 method with a check to see if the logging is enabled. Finally, you don't need 
 to have any access to the MessageFactory. This even has to potential to 
 eliminate AbstractLoggerWrapper.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-22 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13944149#comment-13944149
 ] 

Bruce Brouwer commented on LOG4J2-555:
--

All good points from everyone. Yes, it appears that all of the points that 
everyone made are things I simply missed. I am also ok with renaming the 
LoggerProvider {{log}} methods to {{logIfEnabled}}. I definitely appreciate all 
the extra eyes reviewing my code. I'm not planning on providing another patch 
as it sounds like Remko will clean it up. 

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2

 Attachments: LOG4J2-555-delegate.patch, log4j2-555-bbrouwer-2.patch, 
 log4j2-555-bbrouwer.patch, log4j2-555-gg-v3.diff


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-22 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13944321#comment-13944321
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

Yes, walking bottom-up would definitely solve this problem and would work in 
probably 99% of cases. One cost, though, that I can think of is that usually 
the entry we are looking for is usually closest to the top of the stack trace, 
not the bottom. So there might be a performance hit in the bottom-up approach.

Also, in this case, I could theoretically pass a a LoggerPrintStream wrapping a 
FilterOutputStream wrapping another LoggerPrintStream. I have no idea why 
anyone would do that, but in this situation, the top down approach would be the 
only way that could identify the correct caller info. 

I'm not prepared to advocate for switching to a bottom-up approach, but if you 
thought it was best, I would be in support of it. 

If, we don't go for bottom-up, then I'll have to switch this to a delegating 
pattern, rather than simply subclassing PrintWriter.

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 log4j2-547-bbrouwer.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-33) Support Annotations

2014-03-21 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-33?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13943808#comment-13943808
 ] 

Bruce Brouwer commented on LOG4J2-33:
-

You should check out [Project Lombok|http://projectlombok.org/]. It uses Java's 
built in annotation processing features to make your code look like this:

{code}
@Log
public class LogExample {
  public static void main(String... args) {
log.error(Something's wrong here);
  }
}
{code}

And no, that code did not neglect to extend another class, nor did it neglect 
to define the log field. You could probably take the concepts from Lombok to do 
stuff like this as well:
{code}
public class LogExample {
  @LogEntryExit
  public void doStuff() {
// do stuff
  }
}
{code}

Basically, it uses byte code manipulation to make this all work. From what I 
can tell, there is no need to setup anything special with javac or maven; it 
just works. It looks like there are some issues with some IDEs, which Project 
Lombok has solved. I haven't used it yet myself, but it might be fun to try it 
out in Log4j 2 (maybe after 2.0 is released)

 Support Annotations
 ---

 Key: LOG4J2-33
 URL: https://issues.apache.org/jira/browse/LOG4J2-33
 Project: Log4j 2
  Issue Type: New Feature
  Components: API
Affects Versions: 2.0-rc2
Reporter: Ralph Goers
 Fix For: 0.1, 2.0-rc2

 Attachments: 0001-Add-Loggable.patch


 The Log4j API should support using annotations as provided in Java 6 so 
 applications can use them instead of calls to logger APIs. This is especially 
 useful for entering  exiting type of events, but could be used wherever 
 annotations are allowed.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-21 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13943823#comment-13943823
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

So, I put all this stream stuff in package {{org.apache.logging.log4j.streams}} 
inside the log4j-api project. It seems awkward to me to put these tests inside 
log4j-core when the code it is testing is inside log4j-api. To me, it seems 
like another reason to pull this into its own artifact called log4j-streams. 
This way there is nothing related to these streams in log4j-api, and the 
log4j-streams artifact could pull in log4j-core as a test dependency for the 
purpose of making this caller information test. 

I'm going to make some separate caller-info test classes inside log4j-core, but 
in the {{org.apache.logging.log4j.streams}} package (not 
{{org.apache.logging.log4j.*core*.streams}}) just so we can look at what we are 
talking about, but I don't expect things to stay where they are represented in 
my next patch.

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 log4j2-547-bbrouwer.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-17 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13937728#comment-13937728
 ] 

Bruce Brouwer commented on LOG4J2-555:
--

After thinking some more about my change to log4j-jcl Log4jLog, I could quite 
easily be convinced to revert that back to extending AbstractLoggerWrapper. I 
could see some convenience in simply casting Log4jLog between jcl's Log and 
log4j's Logger interface. 

However, if we do that, then we should probably do the same thing to 
log4j-slf4j-impl's SLF4JLogger so it can also be cast to log4j's Logger 
interface. I suppose this change could be tracked in a separate JIRA. 

So what do people think? Should these alternate logging implementations be made 
so it is easy to cast to log4j's Logger interface, or should we try to keep the 
interface to these alternate logging implementations as free as possible of 
log4j public methods? 

Oh, and I now see that my comment about log4j-to-slf4j SLF4JLogger.logMessage 
was in error. It is fine as it is (which is how it remains in the patch)

I also see that I was remiss in finishing up JavaDoc. If people like the 
direction of {{log4j-555-bbrouwer-2.patch}}, I can make a new patch, or I will 
commit to submitting a documentation patch if this is applied before that new 
patch.

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2

 Attachments: LOG4J2-555-delegate.patch, log4j2-555-bbrouwer-2.patch, 
 log4j2-555-bbrouwer.patch


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-17 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13937728#comment-13937728
 ] 

Bruce Brouwer edited comment on LOG4J2-555 at 3/17/14 12:41 PM:


After thinking some more about my change to log4j-jcl Log4jLog, I could quite 
easily be convinced to revert that back to extending AbstractLoggerWrapper. I 
could see some convenience in simply casting Log4jLog between jcl's Log and 
log4j's Logger interface. For example, if I was using jcl's interface to log4j, 
I could simply cast to a jcl Log to log4j's Logger to use the different logger 
streams depicted in LOG4J2-547.

However, if we do that, then we should probably do the same thing to 
log4j-slf4j-impl's SLF4JLogger so it can also be cast to log4j's Logger 
interface. I suppose this change could be tracked in a separate JIRA. 

So what do people think? Should these alternate logging implementations be made 
so it is easy to cast to log4j's Logger interface, or should we try to keep the 
interface to these alternate logging implementations as free as possible of 
log4j public methods? 

Oh, and I now see that my comment about log4j-to-slf4j SLF4JLogger.logMessage 
was in error. It is fine as it is (which is how it remains in the patch)

I also see that I was remiss in finishing up JavaDoc. If people like the 
direction of {{log4j-555-bbrouwer-2.patch}}, I can make a new patch, or I will 
commit to submitting a documentation patch if this is applied before that new 
patch.


was (Author: bruce.brouwer):
After thinking some more about my change to log4j-jcl Log4jLog, I could quite 
easily be convinced to revert that back to extending AbstractLoggerWrapper. I 
could see some convenience in simply casting Log4jLog between jcl's Log and 
log4j's Logger interface. 

However, if we do that, then we should probably do the same thing to 
log4j-slf4j-impl's SLF4JLogger so it can also be cast to log4j's Logger 
interface. I suppose this change could be tracked in a separate JIRA. 

So what do people think? Should these alternate logging implementations be made 
so it is easy to cast to log4j's Logger interface, or should we try to keep the 
interface to these alternate logging implementations as free as possible of 
log4j public methods? 

Oh, and I now see that my comment about log4j-to-slf4j SLF4JLogger.logMessage 
was in error. It is fine as it is (which is how it remains in the patch)

I also see that I was remiss in finishing up JavaDoc. If people like the 
direction of {{log4j-555-bbrouwer-2.patch}}, I can make a new patch, or I will 
commit to submitting a documentation patch if this is applied before that new 
patch.

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2

 Attachments: LOG4J2-555-delegate.patch, log4j2-555-bbrouwer-2.patch, 
 log4j2-555-bbrouwer.patch


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org

[jira] [Updated] (LOG4J2-547) Update LoggerStream API

2014-03-16 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-547:
-

Attachment: log4j2-547-bbrouwer.patch

Here is my solution to LoggerStream (log4j2-547-bbrouwer.patch). It includes 
logger versions of InputStream, BufferedInputStream, Reader, BufferedReader, 
OutputStream, PrintStream, Writer and PrintWriter. 

Something missing from the current LoggerPrintStream is that it cannot handle 
character sets other than the default system character set. In this patch, 
InputStream, BufferedInputStream, OutputStream and PrintStream can all handle 
any specified character set. Supporting other character sets is the reason for 
some of the extra complexity in this patch.

Also, because of the wide variety of options for creating them, there are 
multiple constructors to all of these classes. This goes with the spirit of the 
corresponding classes in Java where they are created by calling their 
constructors. 

Because of the wide variety of options, this would add a significant amount of 
new methods on the LogManager interface. I am proposing that we not do that. As 
directed, I put this in log4j-api, but I want to make one last request that 
this not be included in log4j-api but rather in a new artifact called 
log4j-streams. These new classes stand alone on their own and I see little 
value in adding corresponding factory methods in LogManager for each 
constructor specified by these classes. 

This patch relies on my latest patch in LOG4J2-555 and because of the overlap 
with some classes in the LOG4J-555 patch, I am not able to cleanly provide a 
patch that gets rid of LoggerStream and LoggerWriter and the existing 
printStream and printWriter methods in LogManager. It is my intent that these 
all be removed should this patch be accepted. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 Add_caller_info_tests.patch, log4j2-547-bbrouwer.patch, 
 log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-510) How to close inactive log files

2014-03-16 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-510?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13937411#comment-13937411
 ] 

Bruce Brouwer commented on LOG4J2-510:
--

How do you intend to manage all those log files? Why couldn't you simply log 
the sessionID in each log entry using the MDC and have only one rolling log 
file? I would think you would run into other problems with the file system with 
having thousands, or potentially far more than thousands, of log files sitting 
around. 

I know log management tools like Splunk prefer to watch fewer files. And grep 
will make short work of finding which logs are involved with a particular 
session id. 

 How to close inactive log files
 ---

 Key: LOG4J2-510
 URL: https://issues.apache.org/jira/browse/LOG4J2-510
 Project: Log4j 2
  Issue Type: Bug
  Components: Appenders
Affects Versions: 2.0-beta9
 Environment: linux
Reporter: Eric
  Labels: performance
 Fix For: 2.0-beta9


 Hi There,
 in log4j2 when the App start logging it create and open a file to log into 
 and that file stay open as long as the App is running.
 in my case log4j2 create and open too many files base on ThreadContext and 
 the OS (linux) will complaint that too many files are open and my App will 
 crash and stop responding.
 My question is:
  1 -  how do you close those files with log4j2 if they are inactive for a 
 period of time.
  2 - How do you have access to the log4j2 handle that open those files.
  3 - How do you tell log4j2 to open a file just for a period of time.
 Thanks
 Eric



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-562) Improve ability to create custom extended logger

2014-03-15 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-562?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13936206#comment-13936206
 ] 

Bruce Brouwer commented on LOG4J2-562:
--

The one concept that this patch provided (which definitely needs some 
modification) that I think might have some merit is this LoggerExtension. My 
patch in LOG4J2-555 adds a bunch of log methods that include the FQCN. These 
methods end up being public, while the previous functionality was protected. 
Originally, some extensions of AbstractLogger switched this protected method(s) 
to public and others did not. If we wanted to keep as much stuff non-public as 
possible, then this LoggerExtension idea could be useful.

Concerning my patch in LOG4J2-555, it would mean getting rid of all the 
log(FQCN, ...) methods from LoggerProvider and replacing it with one method 
called .getExtension(), returning a LoggerExtension. LoggerExtension could then 
have all the .log(FQCN, ...) methods on it instead. 

If everyone is generally ok with the approach of my patch in LOG4J2-555 where 
there are more public .log(FQCN, ...) methods on AbstractLogger (essentially 
abstract methods), then this issue can be closed. I don't care about any of the 
other stuff presented in the patch I provided here. 

Personally, I'm totally ok with closing this issue that I reported as long as 
the general direction I proposed in LOG4J2-555 comes through. 

 Improve ability to create custom extended logger
 

 Key: LOG4J2-562
 URL: https://issues.apache.org/jira/browse/LOG4J2-562
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Reporter: Bruce Brouwer
 Attachments: log4j2-loggerExtension.patch


 Create a LoggerExtension from the original logger which simply remembers the 
 FQCN that will ultimately be the extension. 
 Also by doing this, we can switch a bunch of methods that ended up being 
 public back to protected. I'm guessing they became public so extensions could 
 call them. 
 This can simplify extensions (such as slf4j, jcl, custom extensions, logger 
 streams) so they don't have to pass in the FQCN to that special log method on 
 AbstractLogger anymore. Also, you don't have to wrap every extended log 
 method with a check to see if the logging is enabled. Finally, you don't need 
 to have any access to the MessageFactory. This even has to potential to 
 eliminate AbstractLoggerWrapper.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-15 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13936211#comment-13936211
 ] 

Bruce Brouwer commented on LOG4J2-555:
--

I ran the performance test on my Windows 7 64-bit laptop while plugged in. It 
is a single-proc, 4 core Intel i7 2.7GHz machine with 8GB RAM.

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2

 Attachments: LOG4J2-555-delegate.patch, log4j2-555-bbrouwer-2.patch, 
 log4j2-555-bbrouwer.patch


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-14 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13935921#comment-13935921
 ] 

Bruce Brouwer commented on LOG4J2-555:
--

I wanted to give an overview of what my patch is trying to do:

# Simplify most logger methods to be one line of code
# Allow classes that wrap a logger (e.g. using AbstractLoggerWrapper) to use 
one line of code to log. To accomplish this, I created all the variants of the 
log(...) methods that now take a FQCN as the first parameter.
# Created an interface called LoggerProvider that AbstractLogger implements. 
This I think makes it a bit clearer what extra methods are needed beyond what 
is in the Logger interface to succesfully wrap a logger. This also allows for 
different (future) logger implementations that don't need to extend 
AbstractLogger.
# I changed LoggerContext to return LoggerProvider. Most people don't tend to 
go after the LoggerContext, so most people won't see this. But by doing this 
here, it makes it clear that loggers coming from here are guaranteed to have 
this extra functionality, and it eliminates some casting done in the code
# I tried to fix some of the method parameter ordering to be consistent: fqcn, 
level, marker, message, ... This patch doesn't cover all cases where this could 
be done but in the cases were I was changing method signatures anyway, I 
thought I would make the order consistent. 

You may notice that this patch includes a change to log4j-jcl Log4jLog.java. 
This was not absolutely necessary, but it seemed somehow wrong to me to rely on 
the fact that the method signatures of jcl match up perfectly to log4j2. The 
patch implementation also prevents leaking a bunch of other public methods into 
the implementation coming from AbstractLogger and AbstractLoggerWrapper. If 
others don't agree with me, it would be easy to revert Log4jLog.java back to 
what it was before, but instead of the first constructor parameter being 
AbstractLogger, it would change to LoggerProvider. 

I also just noticed that log4j-to-slf4j SLF4JLogger.logMessage has an 
unnecessary switch statement. That should probably be cleaned up as switching 
it to simply call logger.log(FQCN, level, getMarker(marker), ...) would 
actually be more performant, not only because it eliminates the switch 
statement, but it would also go through fewer method invocations. Do you want 
me to provide an updated patch that does this?

Finally, I ran PerfTestDriver, just the Loggers all async tests. I am not 
sure what the best thing is to do to communicate performance, but this is what 
I did. I was kind of surprised to see that this patch is actually consistently 
more performant than the current log4j2 code (at least that's how I'm reading 
it). 

h5. Original:
1. Log4j2: Loggers all async (single thread): throughput: 12,746,429 ops/sec. 
latency(ns): avg=980.2 99%  8192.0 99.99%  1101004.8 (494079 samples)
2. Log4j2: Loggers all async (4 threads): throughput: 6,603,641 ops/sec. 
latency(ns): avg=3157.4 99%  5120.0 99.99%  8703180.8 (3376684 samples)
3. Log4j2: Loggers all async (2 threads): throughput: 3,505,632 ops/sec. 
latency(ns): avg=1103.5 99%  5324.8 99.99%  2516582.4 (2339717 samples)

h5. After:
1. Log4j2: Loggers all async (single thread): throughput: 13,612,251 ops/sec. 
latency(ns): avg=8463.0 99%  8192.0 99.99%  2936012.8 (344455 samples)
2. Log4j2: Loggers all async (4 threads): throughput: 7,395,284 ops/sec. 
latency(ns): avg=2690.5 99%  5939.2 99.99%  8231321.6 (5952262 samples)
3. Log4j2: Loggers all async (2 threads): throughput: 4,639,382 ops/sec. 
latency(ns): avg=1079.2 99%  6144.0 99.99%  2464153.6 (2312163 samples)


 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2

 Attachments: LOG4J2-555-delegate.patch, log4j2-555-bbrouwer-2.patch, 
 log4j2-555-bbrouwer.patch


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 

[jira] [Updated] (LOG4J2-439) Create a LogEventPatternConverter to escape newlines and HTML special characters

2014-03-13 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-439?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-439:
-

Attachment: log4j2-439-doc.patch

 Create a LogEventPatternConverter to escape newlines and HTML special 
 characters
 

 Key: LOG4J2-439
 URL: https://issues.apache.org/jira/browse/LOG4J2-439
 Project: Log4j 2
  Issue Type: New Feature
  Components: Layouts
Affects Versions: 2.0-beta9
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: EncodingPatternConverter.patch, log4j2-439-doc.patch


 To prevent log forging and HTML based attacks from viewing logs in a browser, 
 we could add a LogEventPatternConverter that escapes newlines and HTML 
 special characters. [ESAPI has a method to do 
 this|http://owasp-esapi-java.googlecode.com/svn/trunk_doc/2.0-rc7/apidocs/org/owasp/esapi/Logger.html],
  but it doesn't have any of the nice API features that Log4j 2 has. 
 I was able to create a LogEventPatternConverter to do this. Note, this is 
 only a proof of concept. I didn't try to exhaustively list all the special 
 characters that might need to be replaced. I also didn't provide any 
 configuration so we could choose to not escape HTML, for example.
 With this configuration:
 {code:xml}
 PatternLayout pattern=%d %-5p [%t] %c %encode{%m}%n/
 {code}
 And logging this message:
 {code}
 LOG.warn(hi\n  h1 there);
 {code}
 Would result in this being logged:
 {code}
 2013-10-28 16:31:21,606 WARN  [main] example.Test hi\n amp; lt;h1gt; there 
 {code}
 instead of this (which shows the potential for log forging):
 {code}
 2013-10-28 16:31:21,606 WARN  [main] example.Test hi
  h1 there 
 {code}
 This is roughly the code I used:
 {code}
 @Plugin(name = escape, category = Converter)
 @ConverterKeys({ escape })
 public final class EscapingReplacementConverter extends 
 LogEventPatternConverter {
 private final ListPatternFormatter formatters;
 private EscapingReplacementConverter(final ListPatternFormatter 
 formatters) {
 super(escape, escape);
 this.formatters = formatters;
 }
 public static EscapingReplacementConverter newInstance(final 
 Configuration config,
final String[] 
 options) {
 if (options.length != 1) {
 LOGGER.error(Incorrect number of options on escape. Expected 1, 
 received 
 + options.length);
 return null;
 }
 if (options[0] == null) {
 LOGGER.error(No pattern supplied on escape);
 return null;
 }
 final PatternParser parser = 
 PatternLayout.createPatternParser(config);
 final ListPatternFormatter formatters = parser.parse(options[0]);
 return new EscapingReplacementConverter(formatters);
 }
 @Override
 public void format(final LogEvent event, final StringBuilder toAppendTo) {
 final StringBuilder buf = new StringBuilder();
 for (final PatternFormatter formatter : formatters) {
 formatter.format(event, buf);
 }
 toAppendTo.append(buf.toString()
  .replaceAll(\\r, r)
  .replaceAll(\\n, n)
  .replaceAll(, amp;)
  .replaceAll(, lt;)
  .replaceAll(, gt;));
 }
 }
 {code}
 If this sounds good, I would like to hear feedback and ideas on how to make 
 this better. I will then contribute this to the project. Do you think this 
 could this get in 2.0?



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Reopened] (LOG4J2-439) Create a LogEventPatternConverter to escape newlines and HTML special characters

2014-03-13 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-439?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer reopened LOG4J2-439:
--


I am only re-opening this to provide a documentation patch.

 Create a LogEventPatternConverter to escape newlines and HTML special 
 characters
 

 Key: LOG4J2-439
 URL: https://issues.apache.org/jira/browse/LOG4J2-439
 Project: Log4j 2
  Issue Type: New Feature
  Components: Layouts
Affects Versions: 2.0-beta9
Reporter: Bruce Brouwer
Assignee: Ralph Goers
 Fix For: 2.0-rc2

 Attachments: EncodingPatternConverter.patch, log4j2-439-doc.patch


 To prevent log forging and HTML based attacks from viewing logs in a browser, 
 we could add a LogEventPatternConverter that escapes newlines and HTML 
 special characters. [ESAPI has a method to do 
 this|http://owasp-esapi-java.googlecode.com/svn/trunk_doc/2.0-rc7/apidocs/org/owasp/esapi/Logger.html],
  but it doesn't have any of the nice API features that Log4j 2 has. 
 I was able to create a LogEventPatternConverter to do this. Note, this is 
 only a proof of concept. I didn't try to exhaustively list all the special 
 characters that might need to be replaced. I also didn't provide any 
 configuration so we could choose to not escape HTML, for example.
 With this configuration:
 {code:xml}
 PatternLayout pattern=%d %-5p [%t] %c %encode{%m}%n/
 {code}
 And logging this message:
 {code}
 LOG.warn(hi\n  h1 there);
 {code}
 Would result in this being logged:
 {code}
 2013-10-28 16:31:21,606 WARN  [main] example.Test hi\n amp; lt;h1gt; there 
 {code}
 instead of this (which shows the potential for log forging):
 {code}
 2013-10-28 16:31:21,606 WARN  [main] example.Test hi
  h1 there 
 {code}
 This is roughly the code I used:
 {code}
 @Plugin(name = escape, category = Converter)
 @ConverterKeys({ escape })
 public final class EscapingReplacementConverter extends 
 LogEventPatternConverter {
 private final ListPatternFormatter formatters;
 private EscapingReplacementConverter(final ListPatternFormatter 
 formatters) {
 super(escape, escape);
 this.formatters = formatters;
 }
 public static EscapingReplacementConverter newInstance(final 
 Configuration config,
final String[] 
 options) {
 if (options.length != 1) {
 LOGGER.error(Incorrect number of options on escape. Expected 1, 
 received 
 + options.length);
 return null;
 }
 if (options[0] == null) {
 LOGGER.error(No pattern supplied on escape);
 return null;
 }
 final PatternParser parser = 
 PatternLayout.createPatternParser(config);
 final ListPatternFormatter formatters = parser.parse(options[0]);
 return new EscapingReplacementConverter(formatters);
 }
 @Override
 public void format(final LogEvent event, final StringBuilder toAppendTo) {
 final StringBuilder buf = new StringBuilder();
 for (final PatternFormatter formatter : formatters) {
 formatter.format(event, buf);
 }
 toAppendTo.append(buf.toString()
  .replaceAll(\\r, r)
  .replaceAll(\\n, n)
  .replaceAll(, amp;)
  .replaceAll(, lt;)
  .replaceAll(, gt;));
 }
 }
 {code}
 If this sounds good, I would like to hear feedback and ideas on how to make 
 this better. I will then contribute this to the project. Do you think this 
 could this get in 2.0?



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-13 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-555:
-

Attachment: log4j2-555-bbrouwer-2.patch

I fixed the problems with the failing tests. Everything now passes. 

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2

 Attachments: LOG4J2-555-delegate.patch, log4j2-555-bbrouwer-2.patch, 
 log4j2-555-bbrouwer.patch


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-12 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13932795#comment-13932795
 ] 

Bruce Brouwer commented on LOG4J2-555:
--

I've attached my patch that takes care of the FQCN issues. AbstractLogger is 
reduced by 171 lines and it does not involve that fun little enum trick that 
Remko proposed. This has impact to anything that extends AbstractLogger, which 
is included in my patch. I haven't finished checking all the tests as I'm 
getting some weird testing errors that I think are unrelated to my changes, but 
I'll check yet. 

My initial performance numbers show it is just as fast as before, but I'll post 
more complete numbers later.

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2

 Attachments: LOG4J2-555-delegate.patch


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-12 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-555:
-

Attachment: log4j2-555-bbrouwer.patch

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2

 Attachments: LOG4J2-555-delegate.patch, log4j2-555-bbrouwer.patch


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-09 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13925424#comment-13925424
 ] 

Bruce Brouwer commented on LOG4J2-555:
--

That MsgBuilder stuff looks interesting. I'm not sure I'm for it yet. It is not 
incompatible with my ideas.

I'm working on my own patch for this that I will post soon and I hope to 
receive feedback.

There are a few things I'm trying to do to make it easier for things using the 
wrapper. 
* Instead of FQCN invading the API, which isn't terribly flexible, I've created 
a SourceLocator interface and related classes. This way custom loggers could 
use multiple FQCNs or something completely different.
* Make the interface LoggerProvider in the spi package which extends Logger and 
which AbstractLogger implements. This has a few more isEnabled and log methods 
available which make it possible for extended loggers to use efficiently. 
LoggerContext would start to return LoggerProvider instead of just Logger, and 
other code would stop casting to AbstractLogger and could instead use the 
LoggerProvider interface.

That second point ends up making more methods public on the concrete 
implementations. I had an alternative idea in LOG4J2-562 that would prevent 
these methods from needing to go public. I'll post my patch soon. I'll try to 
get performance numbers, too. 

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2

 Attachments: LOG4J2-555-delegate.patch


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Reopened] (LOG4J2-558) Create a log4j-bom

2014-03-07 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-558?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer reopened LOG4J2-558:
--


Not quite right. Apply the patch I provided.

This is an example of a pom using the bom

{code:xml}
project xmlns=http://maven.apache.org/POM/4.0.0; 
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance;
xsi:schemaLocation=http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd;
modelVersion4.0.0/modelVersion
groupIdcom.bhb.test/groupId
artifactIdlog4j-testing/artifactId
version0.0.1-SNAPSHOT/version

dependencyManagement
dependencies
dependency
groupIdorg.apache.logging.log4j/groupId
artifactIdlog4j-bom/artifactId
version2.0-rc2-SNAPSHOT/version
typepom/type
scopeimport/scope
/dependency
/dependencies
/dependencyManagement

dependencies
dependency
groupIdorg.apache.logging.log4j/groupId
artifactIdlog4j-core/artifactId
/dependency
/dependencies
/project
{code}

 Create a log4j-bom
 --

 Key: LOG4J2-558
 URL: https://issues.apache.org/jira/browse/LOG4J2-558
 Project: Log4j 2
  Issue Type: Improvement
Reporter: Bruce Brouwer
Assignee: Matt Sicker
 Fix For: 2.0-rc2

 Attachments: log4j-bom.patch


 Create a log4j-bom (Bill of Materials) POM to make it easier for clients to 
 keep consistent versions for multiple log4j artifacts.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-558) Create a log4j-bom

2014-03-07 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-558?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-558:
-

Attachment: log4j-bom.patch

 Create a log4j-bom
 --

 Key: LOG4J2-558
 URL: https://issues.apache.org/jira/browse/LOG4J2-558
 Project: Log4j 2
  Issue Type: Improvement
Reporter: Bruce Brouwer
Assignee: Matt Sicker
 Fix For: 2.0-rc2

 Attachments: log4j-bom.patch


 Create a log4j-bom (Bill of Materials) POM to make it easier for clients to 
 keep consistent versions for multiple log4j artifacts.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-519) Custom/Extended Loggers

2014-03-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-519?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13922497#comment-13922497
 ] 

Bruce Brouwer commented on LOG4J2-519:
--

With my work in LOG4J-547, this example would turn into something like this:

{code}
package com.bhb.log4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.simple.SimpleLogger;
import org.apache.logging.log4j.spi.AbstractLogger;
import org.apache.logging.log4j.spi.LoggerExtension;

public final class ExtLogger extends AbstractLogger {
private static final long serialVersionUID = 26876940739430L;
private static final ConcurrentMapString, ExtLogger loggers = new 
ConcurrentHashMapString, ExtLogger();

private final LoggerExtension logger;

private static final String FQCN = ExtLogger.class.getName();
private static final Level DIAG = Level.forName(DIAG, 350);
private static final Level NOTICE = Level.forName(NOTICE, 450);
private static final Level VERBOSE = Level.forName(VERBOSE, 550);

private ExtLogger(LoggerExtension logger) {
super(logger.getName());
this.logger = logger;
}

/**
 * Returns a custom Logger with the name of the calling class.
 * 
 * @return The custom Logger for the calling class.
 */
public static ExtLogger getLogger() {
return getLogger(getClassName(2));
}

/**
 * Returns a custom Logger using the fully qualified name of the Class as 
the Logger name.
 * 
 * @param loggerName The Class whose name should be used as the Logger 
name. If null it will
 *default to the calling class.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Class? clazz) {
return getLogger(clazz != null ? clazz.getName() : getClassName(2));
}

/**
 * Returns a custom Logger using the fully qualified name of the Class as 
the Logger name.
 * 
 * @param loggerName The Class whose name should be used as the Logger 
name. If null it will
 *default to the calling class.
 * @param messageFactory The message factory is used only when creating a 
logger, subsequent use
 *does not change the logger but will log a warning if 
mismatched.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Class? clazz, final 
MessageFactory factory) {
return getLogger(clazz != null ? clazz.getName() : getClassName(2), 
factory);
}

/**
 * Returns a custom Logger using the fully qualified class name of the 
value as the Logger name.
 * 
 * @param value The value whose class name should be used as the Logger 
name. If null the name
 *of the calling class will be used as the logger name.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Object value) {
return getLogger(value != null ? value.getClass().getName() : 
getClassName(2));
}

/**
 * Returns a custom Logger using the fully qualified class name of the 
value as the Logger name.
 * 
 * @param value The value whose class name should be used as the Logger 
name. If null the name
 *of the calling class will be used as the logger name.
 * @param messageFactory The message factory is used only when creating a 
logger, subsequent use
 *does not change the logger but will log a warning if 
mismatched.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Object value, final MessageFactory 
factory) {
return getLogger(value != null ? value.getClass().getName() : 
getClassName(2), factory);
}

/**
 * Returns a custom Logger with the specified name.
 * 
 * @param name The logger name. If null the name of the calling class will 
be used.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final String name) {
return getLogger(name != null ? name : getClassName(2), null);
}

/**
 * Returns a custom Logger with the specified name.
 * 
 * @param name The logger name. If null the name of the calling class will 
be used.
 * @param messageFactory The message factory is used only when creating a 
logger, subsequent use
 *does not change the logger but will log a warning if 
mismatched.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final String name, final MessageFactory 
factory) {
final String actualName = name != null ? name : getClassName(2);
if 

[jira] [Comment Edited] (LOG4J2-519) Custom/Extended Loggers

2014-03-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-519?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13922497#comment-13922497
 ] 

Bruce Brouwer edited comment on LOG4J2-519 at 3/6/14 1:30 PM:
--

With my work in LOG4J2-547, this example would turn into something like this:

{code}
package com.bhb.log4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.simple.SimpleLogger;
import org.apache.logging.log4j.spi.AbstractLogger;
import org.apache.logging.log4j.spi.LoggerExtension;

public final class ExtLogger extends AbstractLogger {
private static final long serialVersionUID = 26876940739430L;
private static final ConcurrentMapString, ExtLogger loggers = new 
ConcurrentHashMapString, ExtLogger();

private final LoggerExtension logger;

private static final String FQCN = ExtLogger.class.getName();
private static final Level DIAG = Level.forName(DIAG, 350);
private static final Level NOTICE = Level.forName(NOTICE, 450);
private static final Level VERBOSE = Level.forName(VERBOSE, 550);

private ExtLogger(LoggerExtension logger) {
super(logger.getName());
this.logger = logger;
}

/**
 * Returns a custom Logger with the name of the calling class.
 * 
 * @return The custom Logger for the calling class.
 */
public static ExtLogger getLogger() {
return getLogger(getClassName(2));
}

/**
 * Returns a custom Logger using the fully qualified name of the Class as 
the Logger name.
 * 
 * @param loggerName The Class whose name should be used as the Logger 
name. If null it will
 *default to the calling class.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Class? clazz) {
return getLogger(clazz != null ? clazz.getName() : getClassName(2));
}

/**
 * Returns a custom Logger using the fully qualified name of the Class as 
the Logger name.
 * 
 * @param loggerName The Class whose name should be used as the Logger 
name. If null it will
 *default to the calling class.
 * @param messageFactory The message factory is used only when creating a 
logger, subsequent use
 *does not change the logger but will log a warning if 
mismatched.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Class? clazz, final 
MessageFactory factory) {
return getLogger(clazz != null ? clazz.getName() : getClassName(2), 
factory);
}

/**
 * Returns a custom Logger using the fully qualified class name of the 
value as the Logger name.
 * 
 * @param value The value whose class name should be used as the Logger 
name. If null the name
 *of the calling class will be used as the logger name.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Object value) {
return getLogger(value != null ? value.getClass().getName() : 
getClassName(2));
}

/**
 * Returns a custom Logger using the fully qualified class name of the 
value as the Logger name.
 * 
 * @param value The value whose class name should be used as the Logger 
name. If null the name
 *of the calling class will be used as the logger name.
 * @param messageFactory The message factory is used only when creating a 
logger, subsequent use
 *does not change the logger but will log a warning if 
mismatched.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Object value, final MessageFactory 
factory) {
return getLogger(value != null ? value.getClass().getName() : 
getClassName(2), factory);
}

/**
 * Returns a custom Logger with the specified name.
 * 
 * @param name The logger name. If null the name of the calling class will 
be used.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final String name) {
return getLogger(name != null ? name : getClassName(2), null);
}

/**
 * Returns a custom Logger with the specified name.
 * 
 * @param name The logger name. If null the name of the calling class will 
be used.
 * @param messageFactory The message factory is used only when creating a 
logger, subsequent use
 *does not change the logger but will log a warning if 
mismatched.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final String name, final MessageFactory 
factory) {
final String actualName = 

[jira] [Comment Edited] (LOG4J2-519) Custom/Extended Loggers

2014-03-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-519?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13922497#comment-13922497
 ] 

Bruce Brouwer edited comment on LOG4J2-519 at 3/6/14 1:31 PM:
--

With my work in LOG4J2-562, this example would turn into something like this:

{code}
package com.bhb.log4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.simple.SimpleLogger;
import org.apache.logging.log4j.spi.AbstractLogger;
import org.apache.logging.log4j.spi.LoggerExtension;

public final class ExtLogger extends AbstractLogger {
private static final long serialVersionUID = 26876940739430L;
private static final ConcurrentMapString, ExtLogger loggers = new 
ConcurrentHashMapString, ExtLogger();

private final LoggerExtension logger;

private static final String FQCN = ExtLogger.class.getName();
private static final Level DIAG = Level.forName(DIAG, 350);
private static final Level NOTICE = Level.forName(NOTICE, 450);
private static final Level VERBOSE = Level.forName(VERBOSE, 550);

private ExtLogger(LoggerExtension logger) {
super(logger.getName());
this.logger = logger;
}

/**
 * Returns a custom Logger with the name of the calling class.
 * 
 * @return The custom Logger for the calling class.
 */
public static ExtLogger getLogger() {
return getLogger(getClassName(2));
}

/**
 * Returns a custom Logger using the fully qualified name of the Class as 
the Logger name.
 * 
 * @param loggerName The Class whose name should be used as the Logger 
name. If null it will
 *default to the calling class.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Class? clazz) {
return getLogger(clazz != null ? clazz.getName() : getClassName(2));
}

/**
 * Returns a custom Logger using the fully qualified name of the Class as 
the Logger name.
 * 
 * @param loggerName The Class whose name should be used as the Logger 
name. If null it will
 *default to the calling class.
 * @param messageFactory The message factory is used only when creating a 
logger, subsequent use
 *does not change the logger but will log a warning if 
mismatched.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Class? clazz, final 
MessageFactory factory) {
return getLogger(clazz != null ? clazz.getName() : getClassName(2), 
factory);
}

/**
 * Returns a custom Logger using the fully qualified class name of the 
value as the Logger name.
 * 
 * @param value The value whose class name should be used as the Logger 
name. If null the name
 *of the calling class will be used as the logger name.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Object value) {
return getLogger(value != null ? value.getClass().getName() : 
getClassName(2));
}

/**
 * Returns a custom Logger using the fully qualified class name of the 
value as the Logger name.
 * 
 * @param value The value whose class name should be used as the Logger 
name. If null the name
 *of the calling class will be used as the logger name.
 * @param messageFactory The message factory is used only when creating a 
logger, subsequent use
 *does not change the logger but will log a warning if 
mismatched.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final Object value, final MessageFactory 
factory) {
return getLogger(value != null ? value.getClass().getName() : 
getClassName(2), factory);
}

/**
 * Returns a custom Logger with the specified name.
 * 
 * @param name The logger name. If null the name of the calling class will 
be used.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final String name) {
return getLogger(name != null ? name : getClassName(2), null);
}

/**
 * Returns a custom Logger with the specified name.
 * 
 * @param name The logger name. If null the name of the calling class will 
be used.
 * @param messageFactory The message factory is used only when creating a 
logger, subsequent use
 *does not change the logger but will log a warning if 
mismatched.
 * @return The custom Logger.
 */
public static ExtLogger getLogger(final String name, final MessageFactory 
factory) {
final String actualName = 

[jira] [Commented] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13923081#comment-13923081
 ] 

Bruce Brouwer commented on LOG4J2-555:
--

Would it be crazy to use a Java Proxy to proxy the loggers and have the proxy 
figure out the call stack? This should work fine when you're just dealing with 
the Logger interface. I don't know exactly what kind of performance impact this 
would create. Maybe there would be a way to detect if a logger is using a 
location pattern layout like %C and only proxy it if necessary. 

This wouldn't help for the extended loggers unless they implemented an 
interface. For those it could fall back to using cglib (most likely would be an 
optional dependency)

I don't know if this is worth exploring, but I thought I would throw it out as 
an idea. 

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13923094#comment-13923094
 ] 

Bruce Brouwer commented on LOG4J2-555:
--

As for the Set idea, I think that is close to what we need (sans proxies). I 
don't want this to walk up the class hierarchy, though. For what I was working 
on for LOG4J2-547 regarding the LoggerStream, I would be providing a subclass 
of Writer or OutputStream (e.g. LoggerWriter or LoggerOutputStream). These may 
wrap another Writer or OutputStream. If you simply walked up the class 
hierarchy of LoggerWriter, you would be watching for FQCNs of Writer, such as 
the wrapped Writer would also extend. This might cause this locator logic to 
incorrectly identify which class stack element was the outer most call stack 
used for locating caller information. 

I think it would be better if we simply gave the FQCN parameter a collection of 
FQCNs. If I knew I extended every method of AbstractLogger, then why bother 
checking for AbstractLogger in the call stack. 

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-519) Custom/Extended Loggers

2014-03-06 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-519?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13923170#comment-13923170
 ] 

Bruce Brouwer commented on LOG4J2-519:
--

Sorry, I wasn't clear in what my code represents. I neglected to remove FQCN 
from the code I posted as in the last getLogger method, you'll see that my 
example is passing in the ExtLogger.class and AbstractLogger.class. Basically, 
what would have been two separate FQCN. I don't particularly need to pass in 
actual classes. They could be FQCN strings. 

Also, this is is just code that demonstrates where we could take it if we moved 
forward with what I am suggesting in LOG4J2-562 and influenced by the 
discussion in LOG4J2-555. The code as I provided does not actually work 
currently with the trunk on log4j2. 

It is important to note that I'm giving 2 FQCNs. Because some of the 
implemented methods are on AbstractLogger and others on ExtLogger, we need to 
tell the extended logger about both classes. I imagine we would want to allow 
any number of FQCNs if we pursued this approach. 

 Custom/Extended Loggers
 ---

 Key: LOG4J2-519
 URL: https://issues.apache.org/jira/browse/LOG4J2-519
 Project: Log4j 2
  Issue Type: New Feature
  Components: API
Affects Versions: 2.0-rc1
Reporter: Remko Popma
 Attachments: Generate.java, Generate_old_20140130.java


 Please try out the attached [^Generate.java] tool that provides the 
 functionality described below and give feedback if you notice any issues.
 {anchor:Extending}
 *[#Extending] the Logger interface*
 LOG4J2-41 added support for custom log Levels. Users can now log messages at 
 the new custom level by passing the custom level to the {{Logger.log()}} 
 method:
 {code}
 final Logger logger = LogManager.getLogger();
 final Level VERBOSE = Level.forName(VERBOSE, 550);
 logger.log(VERBOSE, a verbose message);
 logger.log(VERBOSE, another message);
 {code}
 However, custom levels are not as easy to use as the built-in levels: one 
 needs to call the generic {{log()}} method and pass a {{Level}} parameter. 
 Built-in levels on the other hand have a set of convenience methods on the 
 Logger interface. For example, the Logger interface has 14 debug methods that 
 support the DEBUG level:
 {code}
 debug(Marker, Message)
 debug(Marker, Message, Throwable)
 debug(Marker, Object)
 debug(Marker, Object, Throwable)
 debug(Marker, String)
 debug(Marker, String, Object...)
 debug(Marker, String, Throwable)
 debug(Message)
 debug(Message, Throwable)
 debug(Object)
 debug(Object, Throwable)
 debug(String)
 debug(String, Object...)
 debug(String, Throwable)
 {code}
 Similar method sets exist for the other built-in levels.
 Several people have expressed the desire to have the same ease of use with 
 custom levels, so after declaring a custom VERBOSE level, we would like to be 
 able to use code like this:
 {code}
 logger.verbose(a verbose message); // no need to pass the VERBOSE level as 
 a parameter
 logger.verbose(another message);
 {code}
 {anchor:Customizing}
 *[#Customizing] the Logger interface*
 In the above use case, convenience methods were _added_ to the Logger 
 interface, in addition to the existing {{trace()}}, {{debug()}}, {{info()}}, 
 ... methods for the built-in log levels.
 There is another use case, Domain Specific Language loggers, where we want to 
 _replace_ the existing {{trace()}}, {{debug()}}, {{info()}}, ... methods with 
 all-custom methods.
 For example, for medical devices we could have only {{critical()}}, 
 {{warning()}}, and {{advisory()}} methods. Another example could be a game 
 that has only {{defcon1()}}, {{defcon2()}}, and {{defcon3()}} levels.
 Finally, if it were possible to hide existing log levels, users could 
 customize the Logger interface to match their requirements. Some people may 
 not want to have a {{FATAL}} or a {{TRACE}} level, for example. They would 
 like to be able to create a custom Logger that only has {{debug()}}, 
 {{info()}}, {{warn()}} and {{error()}} methods.
 {anchor:wrapper}
 *Proposal: Generate source code for a Logger [#wrapper]*
 Common log4j usage is to get an instance of the {{Logger}} interface from the 
 {{LogManager}} and call the methods on this interface. This makes it hard to 
 achieve the above customization; especially taking away existing methods is 
 not possible.
 An alternative is for the user to create a wrapper class that exposes only 
 the convenience methods for the desired log levels. When _extending_ the 
 {{Logger}} API (_adding_ methods), this wrapper class could subclass 
 {{org.apache.logging.log4j.spi.AbstractLoggerWrapper}}. When _customizing_ 
 the {{Logger}} API (_removing_ built-in methods), the wrapper class would 
 simply not extend AbstractLoggerWrapper, so the only public methods would be 
 the methods for the custom log 

[jira] [Created] (LOG4J2-562) Improve ability to create custom extended logger

2014-03-04 Thread Bruce Brouwer (JIRA)
Bruce Brouwer created LOG4J2-562:


 Summary: Improve ability to create custom extended logger
 Key: LOG4J2-562
 URL: https://issues.apache.org/jira/browse/LOG4J2-562
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Reporter: Bruce Brouwer
 Attachments: log4j2-loggerExtension.patch

Create a LoggerExtension from the original logger which simply remembers the 
FQCN that will ultimately be the extension. 

Also by doing this, we can switch a bunch of methods that ended up being public 
back to protected. I'm guessing they became public so extensions could call 
them. 

This can simplify extensions (such as slf4j, jcl, custom extensions, logger 
streams) so they don't have to pass in the FQCN to that special log method on 
AbstractLogger anymore. Also, you don't have to wrap every extended log method 
with a check to see if the logging is enabled. Finally, you don't need to have 
any access to the MessageFactory. This even has to potential to eliminate 
AbstractLoggerWrapper.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-562) Improve ability to create custom extended logger

2014-03-04 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-562?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-562:
-

Attachment: log4j2-loggerExtension.patch

This log4j2-loggerExtension.patch is in no way complete, but I would like some 
feedback on the direction I am taking on this. 

 Improve ability to create custom extended logger
 

 Key: LOG4J2-562
 URL: https://issues.apache.org/jira/browse/LOG4J2-562
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Reporter: Bruce Brouwer
 Attachments: log4j2-loggerExtension.patch


 Create a LoggerExtension from the original logger which simply remembers the 
 FQCN that will ultimately be the extension. 
 Also by doing this, we can switch a bunch of methods that ended up being 
 public back to protected. I'm guessing they became public so extensions could 
 call them. 
 This can simplify extensions (such as slf4j, jcl, custom extensions, logger 
 streams) so they don't have to pass in the FQCN to that special log method on 
 AbstractLogger anymore. Also, you don't have to wrap every extended log 
 method with a check to see if the logging is enabled. Finally, you don't need 
 to have any access to the MessageFactory. This even has to potential to 
 eliminate AbstractLoggerWrapper.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-519) Custom/Extended Loggers

2014-03-03 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-519?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13918741#comment-13918741
 ] 

Bruce Brouwer commented on LOG4J2-519:
--

I've been wondering about the need here to cast to AbstractLogger. This ties us 
to the implementation of Loggers originally conceived in core. What if we had 
an interface that has the .log(...) methods defined on AbstractLogger that take 
the FQCN. Perhaps we could call this interface ExtensibleLogger or something 
like that. I would feel better about casting to an interface that any logging 
implementation could implement.

I'm kind of looking at this for LOG4J2-547 which I am working on. 

 Custom/Extended Loggers
 ---

 Key: LOG4J2-519
 URL: https://issues.apache.org/jira/browse/LOG4J2-519
 Project: Log4j 2
  Issue Type: New Feature
  Components: API
Affects Versions: 2.0-rc1
Reporter: Remko Popma
 Attachments: Generate.java, Generate_old_20140130.java


 Please try out the attached [^Generate.java] tool that provides the 
 functionality described below and give feedback if you notice any issues.
 {anchor:Extending}
 *[#Extending] the Logger interface*
 LOG4J2-41 added support for custom log Levels. Users can now log messages at 
 the new custom level by passing the custom level to the {{Logger.log()}} 
 method:
 {code}
 final Logger logger = LogManager.getLogger();
 final Level VERBOSE = Level.forName(VERBOSE, 550);
 logger.log(VERBOSE, a verbose message);
 logger.log(VERBOSE, another message);
 {code}
 However, custom levels are not as easy to use as the built-in levels: one 
 needs to call the generic {{log()}} method and pass a {{Level}} parameter. 
 Built-in levels on the other hand have a set of convenience methods on the 
 Logger interface. For example, the Logger interface has 14 debug methods that 
 support the DEBUG level:
 {code}
 debug(Marker, Message)
 debug(Marker, Message, Throwable)
 debug(Marker, Object)
 debug(Marker, Object, Throwable)
 debug(Marker, String)
 debug(Marker, String, Object...)
 debug(Marker, String, Throwable)
 debug(Message)
 debug(Message, Throwable)
 debug(Object)
 debug(Object, Throwable)
 debug(String)
 debug(String, Object...)
 debug(String, Throwable)
 {code}
 Similar method sets exist for the other built-in levels.
 Several people have expressed the desire to have the same ease of use with 
 custom levels, so after declaring a custom VERBOSE level, we would like to be 
 able to use code like this:
 {code}
 logger.verbose(a verbose message); // no need to pass the VERBOSE level as 
 a parameter
 logger.verbose(another message);
 {code}
 {anchor:Customizing}
 *[#Customizing] the Logger interface*
 In the above use case, convenience methods were _added_ to the Logger 
 interface, in addition to the existing {{trace()}}, {{debug()}}, {{info()}}, 
 ... methods for the built-in log levels.
 There is another use case, Domain Specific Language loggers, where we want to 
 _replace_ the existing {{trace()}}, {{debug()}}, {{info()}}, ... methods with 
 all-custom methods.
 For example, for medical devices we could have only {{critical()}}, 
 {{warning()}}, and {{advisory()}} methods. Another example could be a game 
 that has only {{defcon1()}}, {{defcon2()}}, and {{defcon3()}} levels.
 Finally, if it were possible to hide existing log levels, users could 
 customize the Logger interface to match their requirements. Some people may 
 not want to have a {{FATAL}} or a {{TRACE}} level, for example. They would 
 like to be able to create a custom Logger that only has {{debug()}}, 
 {{info()}}, {{warn()}} and {{error()}} methods.
 {anchor:wrapper}
 *Proposal: Generate source code for a Logger [#wrapper]*
 Common log4j usage is to get an instance of the {{Logger}} interface from the 
 {{LogManager}} and call the methods on this interface. This makes it hard to 
 achieve the above customization; especially taking away existing methods is 
 not possible.
 An alternative is for the user to create a wrapper class that exposes only 
 the convenience methods for the desired log levels. When _extending_ the 
 {{Logger}} API (_adding_ methods), this wrapper class could subclass 
 {{org.apache.logging.log4j.spi.AbstractLoggerWrapper}}. When _customizing_ 
 the {{Logger}} API (_removing_ built-in methods), the wrapper class would 
 simply not extend AbstractLoggerWrapper, so the only public methods would be 
 the methods for the custom log levels.
 As the custom log Levels are not known in advance, Log4J cannot provide 
 pre-built wrapper classes for these custom log Levels. However, we don't want 
 to ask the users to hand-code such a wrapper class: this is cumbersome and 
 error-prone: there are 14 methods for each built-in level. To provide 
 comparable functionality for custom log Levels one would need to provide 14 
 methods for 

[jira] [Commented] (LOG4J2-555) Location-based functionality broken in AbstractLoggerWrapper subclasses

2014-03-03 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13918817#comment-13918817
 ] 

Bruce Brouwer commented on LOG4J2-555:
--

I am also very interested in knowing where this lands. I'm working on 
LOG4J2-547, the LoggerStream API. In a sense I am writing a logger wrapper, but 
I am unable to extend AbstractLoggerWrapper or AbstractLogger as I need to 
extend Writer or OutputStream.

 Location-based functionality broken in AbstractLoggerWrapper subclasses
 ---

 Key: LOG4J2-555
 URL: https://issues.apache.org/jira/browse/LOG4J2-555
 Project: Log4j 2
  Issue Type: Bug
  Components: API, Core
Affects Versions: 2.0-rc1
Reporter: Remko Popma
Assignee: Remko Popma
 Fix For: 2.0-rc2


 *How to reproduce*
 * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate 
 one with the tool attached to LOG4J2-519)
 * In the custom logger provide a public method that invokes the {{log(Level, 
 String)}} method
 * Configure a pattern layout that uses location, like %C for the logger FQCN
 * From a sample app, call the public method on your custom logger.
 * The output will show the class name of the custom logger instead of the 
 class name of the calling class in the sample application.
 *Cause*
 {{AbstractLogger}}'s FQCN field is {{static final}} and initialized to 
 {{AbstractLogger.class.getName()}}. Then, in 
 {{Log4jLogEvent#calcLocation()}}, when walking over the stack trace elements, 
 the element _following_ the FQCN is returned. So only loggers that directly 
 subclass from {{AbstractLogger}} will work correctly. Loggers that inherit 
 from {{AbstractLoggerWrapper}} are two levels removed from {{AbstractLogger}} 
 and the {{calcLocation()}} method will not work correctly.
 *Solution*
 I think {{AbstractLogger}}'s FQCN field should be made non-static, and 
 initialized to {{getClass().getName()}} in the constructor of 
 {{AbstractLogger}}. {{Log4jLogEvent#calcLocation()}} can then be modified to 
 return the {{StackElement}} whose class name matches the FQCN, instead of the 
 next element. Location-based functionality should then work for arbitrarily 
 deep subclass hierarchies of AbstractLogger.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-519) Custom/Extended Loggers

2014-03-03 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-519?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13918826#comment-13918826
 ] 

Bruce Brouwer commented on LOG4J2-519:
--

Definitely it would go in spi. It would allow flexibility in implementations 
that might not directly extend AbstractLogger and I think it might help me out 
with LOG4J2-547 where my logger needs to extend Writer and OutputStream. I 
could extend Writer and still implement ExtensibleLogger.

 Custom/Extended Loggers
 ---

 Key: LOG4J2-519
 URL: https://issues.apache.org/jira/browse/LOG4J2-519
 Project: Log4j 2
  Issue Type: New Feature
  Components: API
Affects Versions: 2.0-rc1
Reporter: Remko Popma
 Attachments: Generate.java, Generate_old_20140130.java


 Please try out the attached [^Generate.java] tool that provides the 
 functionality described below and give feedback if you notice any issues.
 {anchor:Extending}
 *[#Extending] the Logger interface*
 LOG4J2-41 added support for custom log Levels. Users can now log messages at 
 the new custom level by passing the custom level to the {{Logger.log()}} 
 method:
 {code}
 final Logger logger = LogManager.getLogger();
 final Level VERBOSE = Level.forName(VERBOSE, 550);
 logger.log(VERBOSE, a verbose message);
 logger.log(VERBOSE, another message);
 {code}
 However, custom levels are not as easy to use as the built-in levels: one 
 needs to call the generic {{log()}} method and pass a {{Level}} parameter. 
 Built-in levels on the other hand have a set of convenience methods on the 
 Logger interface. For example, the Logger interface has 14 debug methods that 
 support the DEBUG level:
 {code}
 debug(Marker, Message)
 debug(Marker, Message, Throwable)
 debug(Marker, Object)
 debug(Marker, Object, Throwable)
 debug(Marker, String)
 debug(Marker, String, Object...)
 debug(Marker, String, Throwable)
 debug(Message)
 debug(Message, Throwable)
 debug(Object)
 debug(Object, Throwable)
 debug(String)
 debug(String, Object...)
 debug(String, Throwable)
 {code}
 Similar method sets exist for the other built-in levels.
 Several people have expressed the desire to have the same ease of use with 
 custom levels, so after declaring a custom VERBOSE level, we would like to be 
 able to use code like this:
 {code}
 logger.verbose(a verbose message); // no need to pass the VERBOSE level as 
 a parameter
 logger.verbose(another message);
 {code}
 {anchor:Customizing}
 *[#Customizing] the Logger interface*
 In the above use case, convenience methods were _added_ to the Logger 
 interface, in addition to the existing {{trace()}}, {{debug()}}, {{info()}}, 
 ... methods for the built-in log levels.
 There is another use case, Domain Specific Language loggers, where we want to 
 _replace_ the existing {{trace()}}, {{debug()}}, {{info()}}, ... methods with 
 all-custom methods.
 For example, for medical devices we could have only {{critical()}}, 
 {{warning()}}, and {{advisory()}} methods. Another example could be a game 
 that has only {{defcon1()}}, {{defcon2()}}, and {{defcon3()}} levels.
 Finally, if it were possible to hide existing log levels, users could 
 customize the Logger interface to match their requirements. Some people may 
 not want to have a {{FATAL}} or a {{TRACE}} level, for example. They would 
 like to be able to create a custom Logger that only has {{debug()}}, 
 {{info()}}, {{warn()}} and {{error()}} methods.
 {anchor:wrapper}
 *Proposal: Generate source code for a Logger [#wrapper]*
 Common log4j usage is to get an instance of the {{Logger}} interface from the 
 {{LogManager}} and call the methods on this interface. This makes it hard to 
 achieve the above customization; especially taking away existing methods is 
 not possible.
 An alternative is for the user to create a wrapper class that exposes only 
 the convenience methods for the desired log levels. When _extending_ the 
 {{Logger}} API (_adding_ methods), this wrapper class could subclass 
 {{org.apache.logging.log4j.spi.AbstractLoggerWrapper}}. When _customizing_ 
 the {{Logger}} API (_removing_ built-in methods), the wrapper class would 
 simply not extend AbstractLoggerWrapper, so the only public methods would be 
 the methods for the custom log levels.
 As the custom log Levels are not known in advance, Log4J cannot provide 
 pre-built wrapper classes for these custom log Levels. However, we don't want 
 to ask the users to hand-code such a wrapper class: this is cumbersome and 
 error-prone: there are 14 methods for each built-in level. To provide 
 comparable functionality for custom log Levels one would need to provide 14 
 methods for each custom log Level.
 The proposal is to solve this by providing a tool that generates the source 
 code for a wrapper class. The user can specify:
 * the fully qualified name of the class to generate
 * 

[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-02 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917415#comment-13917415
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

So, I've been thinking about the actual use case for this feature. I was 
thinking it would be even more helpful if I grabbed a writer that actually 
wrapped another writer. This way I could spy on the writer and send all its 
content to a Logger and to the actual writer. I'm thinking of a method 
signatures like this:
{code}
public Writer writer(Writer writer, Level level);
public Writer writer(Writer writer, Marker marker, Level level);
public OutputStream stream(OutputStream stream, Level level);
public OutputStream stream(OutputStream stream, Marker marker, Level level);
{code}
We could also provide ones basically like before:
{code}
public Writer writer(Level level);
public Writer writer(Marker marker, Level level);
public OutputStream stream(Level level);
public OutputStream stream(Marker marker, Level level);
{code}
Maybe we would keep the PrintWriter/PrintStream variants as well. But then why 
stop there. We could spy on Readers as well:
{code}
public Reader reader(Reader reader, Level level);
public Reader reader(Reader reader, Marker marker, Level level);
public InputStream stream(InputStream stream, Level level);
public InputStream stream(InputStream stream, Marker marker, Level level);
{code}
Making this all work is not really any harder than what is already there. 

But now we're starting to really pollute the Logger interface with stuff that 
99% of the time I'll never want or use. What if we took it a different 
direction and didn't put these reader/writer methods on Logger, but instead put 
them on LogManager or even a new class LogStreaming. Now I could get one of 
these things with code like this:
{code}
Writer writer = LogStreaming.writer(myWriter, Level.WARNING);
{code}

We could go even further and add debug/warn/info/error methods on here as well:
{code}
Writer writer = LogStreaming.debugWriter(myWriter);
{code}

This goes along with another idea I had in LOG4J-242 which would make a fluent 
interface for log4j. I eventually decided that all that stuff doesn't belong in 
Logger either, so instead I would want a FluentLogManager instead of LogManager.

Now back to the whole FQCN thing. If I do the hack I mentioned coupled with 
these new methods I described, if I were to pass in a PrintWriter to this 
writer method, then using the FQCN of PrintWriter will determine the caller is 
the caller of the PrintWriter I passed in, and not the one being created by the 
writer method. 

Furthermore, the reason I would want one of these Writers is to pass to some 
function that expects a Writer, and therefore the call stack will not be from 
my code anyway and then the caller location probably won't be as useful to me 
as I would want. 

So, what are your thoughts on all of these ideas? Am I making this more 
complicated than it should be?

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 Add_caller_info_tests.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-547) Update LoggerStream API

2014-03-02 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917415#comment-13917415
 ] 

Bruce Brouwer edited comment on LOG4J2-547 at 3/2/14 5:01 PM:
--

So, I've been thinking about the actual use case for this feature. I was 
thinking it would be even more helpful if I grabbed a writer that actually 
wrapped another writer. This way I could spy on the writer and send all its 
content to a Logger and to the actual writer. I'm thinking of a method 
signatures like this:
{code}
public Writer writer(Writer writer, Level level);
public Writer writer(Writer writer, Marker marker, Level level);
public OutputStream stream(OutputStream stream, Level level);
public OutputStream stream(OutputStream stream, Marker marker, Level level);
{code}
We could also provide ones basically like before:
{code}
public Writer writer(Level level);
public Writer writer(Marker marker, Level level);
public OutputStream stream(Level level);
public OutputStream stream(Marker marker, Level level);
{code}
Maybe we would keep the PrintWriter/PrintStream variants as well. But then why 
stop there. We could spy on Readers as well:
{code}
public Reader reader(Reader reader, Level level);
public Reader reader(Reader reader, Marker marker, Level level);
public InputStream stream(InputStream stream, Level level);
public InputStream stream(InputStream stream, Marker marker, Level level);
{code}
Making this all work is not really any harder than what is already there. 

But now we're starting to really pollute the Logger interface with stuff that 
99% of the time I'll never want or use. What if we took it a different 
direction and didn't put these reader/writer methods on Logger, but instead put 
them on LogManager or even a new class LogStreaming. Now I could get one of 
these things with code like this:
{code}
Writer writer = LogStreaming.writer(myWriter, Level.WARNING);
{code}

We could go even further and add debug/warn/info/error methods on here as well:
{code}
Writer writer = LogStreaming.debugWriter(MyExample.class, myWriter);
{code}

This goes along with another idea I had in LOG4J-242 which would make a fluent 
interface for log4j. I eventually decided that all that stuff doesn't belong in 
Logger either, so instead I would want a FluentLogManager instead of LogManager.

Now back to the whole FQCN thing. If I do the hack I mentioned coupled with 
these new methods I described, if I were to pass in a PrintWriter to this 
writer method, then using the FQCN of PrintWriter will determine the caller is 
the caller of the PrintWriter I passed in, and not the one being created by the 
writer method. 

Furthermore, the reason I would want one of these Writers is to pass to some 
function that expects a Writer, and therefore the call stack will not be from 
my code anyway and then the caller location probably won't be as useful to me 
as I would want. 

So, what are your thoughts on all of these ideas? Am I making this more 
complicated than it should be?


was (Author: bruce.brouwer):
So, I've been thinking about the actual use case for this feature. I was 
thinking it would be even more helpful if I grabbed a writer that actually 
wrapped another writer. This way I could spy on the writer and send all its 
content to a Logger and to the actual writer. I'm thinking of a method 
signatures like this:
{code}
public Writer writer(Writer writer, Level level);
public Writer writer(Writer writer, Marker marker, Level level);
public OutputStream stream(OutputStream stream, Level level);
public OutputStream stream(OutputStream stream, Marker marker, Level level);
{code}
We could also provide ones basically like before:
{code}
public Writer writer(Level level);
public Writer writer(Marker marker, Level level);
public OutputStream stream(Level level);
public OutputStream stream(Marker marker, Level level);
{code}
Maybe we would keep the PrintWriter/PrintStream variants as well. But then why 
stop there. We could spy on Readers as well:
{code}
public Reader reader(Reader reader, Level level);
public Reader reader(Reader reader, Marker marker, Level level);
public InputStream stream(InputStream stream, Level level);
public InputStream stream(InputStream stream, Marker marker, Level level);
{code}
Making this all work is not really any harder than what is already there. 

But now we're starting to really pollute the Logger interface with stuff that 
99% of the time I'll never want or use. What if we took it a different 
direction and didn't put these reader/writer methods on Logger, but instead put 
them on LogManager or even a new class LogStreaming. Now I could get one of 
these things with code like this:
{code}
Writer writer = LogStreaming.writer(myWriter, Level.WARNING);
{code}

We could go even further and add debug/warn/info/error methods on here as well:
{code}
Writer writer = 

[jira] [Comment Edited] (LOG4J2-547) Update LoggerStream API

2014-03-02 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917415#comment-13917415
 ] 

Bruce Brouwer edited comment on LOG4J2-547 at 3/2/14 5:02 PM:
--

So, I've been thinking about the actual use case for this feature. I was 
thinking it would be even more helpful if I grabbed a writer that actually 
wrapped another writer. This way I could spy on the writer and send all its 
content to a Logger and to the actual writer. I'm thinking of a method 
signatures like this:
{code}
public Writer writer(Writer writer, Level level);
public Writer writer(Writer writer, Marker marker, Level level);
public OutputStream stream(OutputStream stream, Level level);
public OutputStream stream(OutputStream stream, Marker marker, Level level);
{code}
We could also provide ones basically like before:
{code}
public Writer writer(Level level);
public Writer writer(Marker marker, Level level);
public OutputStream stream(Level level);
public OutputStream stream(Marker marker, Level level);
{code}
Maybe we would keep the PrintWriter/PrintStream variants as well. But then why 
stop there. We could spy on Readers as well:
{code}
public Reader reader(Reader reader, Level level);
public Reader reader(Reader reader, Marker marker, Level level);
public InputStream stream(InputStream stream, Level level);
public InputStream stream(InputStream stream, Marker marker, Level level);
{code}
Making this all work is not really any harder than what is already there. 

But now we're starting to really pollute the Logger interface with stuff that 
99% of the time I'll never want or use. What if we took it a different 
direction and didn't put these reader/writer methods on Logger, but instead put 
them on LogManager or even a new class LogStreaming. Now I could get one of 
these things with code like this:
{code}
Writer writer = LogStreaming.writer(MyExample.class, myWriter, Level.WARNING);
{code}

We could go even further and add debug/warn/info/error methods on here as well:
{code}
Writer writer = LogStreaming.debugWriter(MyExample.class, myWriter);
{code}

This goes along with another idea I had in LOG4J-242 which would make a fluent 
interface for log4j. I eventually decided that all that stuff doesn't belong in 
Logger either, so instead I would want a FluentLogManager instead of LogManager.

Now back to the whole FQCN thing. If I do the hack I mentioned coupled with 
these new methods I described, if I were to pass in a PrintWriter to this 
writer method, then using the FQCN of PrintWriter will determine the caller is 
the caller of the PrintWriter I passed in, and not the one being created by the 
writer method. 

Furthermore, the reason I would want one of these Writers is to pass to some 
function that expects a Writer, and therefore the call stack will not be from 
my code anyway and then the caller location probably won't be as useful to me 
as I would want. 

So, what are your thoughts on all of these ideas? Am I making this more 
complicated than it should be?


was (Author: bruce.brouwer):
So, I've been thinking about the actual use case for this feature. I was 
thinking it would be even more helpful if I grabbed a writer that actually 
wrapped another writer. This way I could spy on the writer and send all its 
content to a Logger and to the actual writer. I'm thinking of a method 
signatures like this:
{code}
public Writer writer(Writer writer, Level level);
public Writer writer(Writer writer, Marker marker, Level level);
public OutputStream stream(OutputStream stream, Level level);
public OutputStream stream(OutputStream stream, Marker marker, Level level);
{code}
We could also provide ones basically like before:
{code}
public Writer writer(Level level);
public Writer writer(Marker marker, Level level);
public OutputStream stream(Level level);
public OutputStream stream(Marker marker, Level level);
{code}
Maybe we would keep the PrintWriter/PrintStream variants as well. But then why 
stop there. We could spy on Readers as well:
{code}
public Reader reader(Reader reader, Level level);
public Reader reader(Reader reader, Marker marker, Level level);
public InputStream stream(InputStream stream, Level level);
public InputStream stream(InputStream stream, Marker marker, Level level);
{code}
Making this all work is not really any harder than what is already there. 

But now we're starting to really pollute the Logger interface with stuff that 
99% of the time I'll never want or use. What if we took it a different 
direction and didn't put these reader/writer methods on Logger, but instead put 
them on LogManager or even a new class LogStreaming. Now I could get one of 
these things with code like this:
{code}
Writer writer = LogStreaming.writer(myWriter, Level.WARNING);
{code}

We could go even further and add debug/warn/info/error methods on here as well:
{code}
Writer writer = 

[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-02 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917565#comment-13917565
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

Matt, you're going down the exact same thought-path I am. 

The way I'm looking at it, there are a number of alternate log4j interfaces 
available, some of which haven't come to light yet. There's the slf4j interface 
and the jcl interface. I'm starting to think of this streaming API in the same 
light, putting it in log4j-streaming. And I agree, my fluent api should go in 
another module: log4j-fluent.

I like keeping the Logger interface more along the lines of the classic log4j 
interface without adding a bunch of other methods. Because of my viewpoint, I 
would prefer having a different root class that accessed this streaming API. I 
don't have a strong preference for the actual name, I kind of like 
StreamingLogManager. This new root class would live in log4j-streaming and not 
impact the classic nature of the LogManager interface.

Is it too big of a change to introduce a new artifact this late in the game? 
Should the streaming API be pushed off to 2.1? But I like how there is general 
agreement to get it out of Logger. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 Add_caller_info_tests.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-02 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917644#comment-13917644
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

If we were going to put the streaming interface in -core or -api, then I agree 
with Gary that there is no use for another JAR. If, however, we decide this 
streaming API isn't part of the core of log4j (as I am of the opinion), then I 
vote to put that in a -streaming JAR. That would include StreamingLogManager.

I personally don't mind the extra JAR if it requires me to explicitly choose to 
include it for the desired functionality (like slf4j or jcl). I'm a big user of 
Spring and I felt the same way when they broke that up into a whole bunch of 
JARs. Now it just seems like common practice to have smaller, more targeted 
JARs. Sometimes it can be a pain to know which jar has a particular class, but 
[http://search.maven.org] class search makes that easy to figure out. 

Do you think we can gain consensus to just remove it completely until after 2.0 
is released? Maybe some time will help us settle on a direction.

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 Add_caller_info_tests.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Created] (LOG4J2-558) Create a log4j-bom

2014-03-02 Thread Bruce Brouwer (JIRA)
Bruce Brouwer created LOG4J2-558:


 Summary: Create a log4j-bom
 Key: LOG4J2-558
 URL: https://issues.apache.org/jira/browse/LOG4J2-558
 Project: Log4j 2
  Issue Type: Improvement
Reporter: Bruce Brouwer


Create a log4j-bom (Bill of Materials) POM to make it easier for clients to 
keep consistent versions for multiple log4j artifacts.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-02 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917664#comment-13917664
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

Yes, the default search in search.maven.org can yield a ton of stuff. I'm 
talking about the advanced search where you can specify a fully qualified class 
name. And I agree, the Spring docs don't make it clear enough which JARs you 
need for any particular feature.

As for the bom, that's a great idea. I created LOG4J2-558. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 Add_caller_info_tests.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-02 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917673#comment-13917673
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

It sounds like the log4j team supports keeping this in core. I will put 
together a patch unless anyone else volunteers.

I'll put the factory methods in LogManager as this being considered part of the 
core of log4j. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 Add_caller_info_tests.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-02 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917712#comment-13917712
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

Ok, I need a bit of advice. In LogManager, I get access to a Logger. Is it ok 
to just cast that to AbstractLogger or is there some better way?

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 Add_caller_info_tests.patch, log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.2#6252)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-01 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917159#comment-13917159
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

In looking at LoggerStream, I can see how it could help me when shelling out to 
commands when all I want to do is log the output of that shelled command. There 
is some non-trivial stuff that LoggerStream is doing, so I don't want to get 
rid of that concept. 

But I agree that as it stands, the most helpful part of LoggerStream is 
actually the HelperStream. I'm including a patch that gets rid of LoggerStream 
and instead returns a plain old PrintWriter. This involved making a 
LoggerWriter which does basically what HelperStream did before. 

I don't see a whole lot of value adding this to the LoggerContext. In the end 
it needs an AbstractLogger anyway, so why not get it from the AbstractLogger.

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Updated] (LOG4J2-547) Update LoggerStream API

2014-03-01 Thread Bruce Brouwer (JIRA)

 [ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Brouwer updated LOG4J2-547:
-

Attachment: log4j2-loggerStream.patch

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Comment Edited] (LOG4J2-547) Update LoggerStream API

2014-03-01 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917159#comment-13917159
 ] 

Bruce Brouwer edited comment on LOG4J2-547 at 3/1/14 7:04 PM:
--

In looking at LoggerStream, I can see how it could help me when shelling out to 
commands when all I want to do is log the output of that shelled command. There 
is some non-trivial stuff that LoggerStream is doing, so I don't want to get 
rid of that concept. 

But I agree that as it stands, the most helpful part of LoggerStream is 
actually the HelperStream. I'm including a patch that gets rid of LoggerStream 
and instead returns a plain old PrintWriter. This involved making a 
LoggerWriter which does basically what HelperStream did before. 

I don't see a whole lot of value adding this to the LoggerContext. In the end 
it needs an AbstractLogger anyway, so why not get it from the AbstractLogger.

Oh, and I called the method .printWriter(...) instead of .getStream(...). 
First, the old .getStream didn't even return an OutputStream, it returned 
something that extended PrintWriter. And also, by removing the .get part, users 
might not expect to get the exact same PrintWriter instance each time they call 
it. In this case, I don't think I would want to get the same instance each 
time. 


was (Author: bruce.brouwer):
In looking at LoggerStream, I can see how it could help me when shelling out to 
commands when all I want to do is log the output of that shelled command. There 
is some non-trivial stuff that LoggerStream is doing, so I don't want to get 
rid of that concept. 

But I agree that as it stands, the most helpful part of LoggerStream is 
actually the HelperStream. I'm including a patch that gets rid of LoggerStream 
and instead returns a plain old PrintWriter. This involved making a 
LoggerWriter which does basically what HelperStream did before. 

I don't see a whole lot of value adding this to the LoggerContext. In the end 
it needs an AbstractLogger anyway, so why not get it from the AbstractLogger.

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-547) Update LoggerStream API

2014-03-01 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917180#comment-13917180
 ] 

Bruce Brouwer commented on LOG4J2-547:
--

One thing I noticed I missed. We might want to synchronize on buf in the 
close() method. 

 Update LoggerStream API
 ---

 Key: LOG4J2-547
 URL: https://issues.apache.org/jira/browse/LOG4J2-547
 Project: Log4j 2
  Issue Type: Improvement
  Components: API
Affects Versions: 2.0-rc1
Reporter: Matt Sicker
Assignee: Ralph Goers
 Fix For: 2.0

 Attachments: 0001-PrintStream-API-update.patch, 
 log4j2-loggerStream.patch


 I've got some ideas on how to improve the LoggerStream idea that I added a 
 little while ago. The main thing I'd like to do is extract an interface from 
 it, rename the default implementation to SimpleLoggerStream (part of the 
 SimpleLogger stuff), and allow log4j implementations to specify a different 
 implementation if desired.
 In doing this, I'm not sure where specifically I'd prefer the getStream 
 methods to be. Right now, it's in Logger, but really, it could be in 
 LoggerContext instead. I don't think I should be required to get a Logger 
 just to get a LoggerStream.
 Now if only the java.io package used interfaces instead of classes. This 
 would be so much easier to design!



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



[jira] [Commented] (LOG4J2-510) How to close inactive log files

2014-03-01 Thread Bruce Brouwer (JIRA)

[ 
https://issues.apache.org/jira/browse/LOG4J2-510?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13917181#comment-13917181
 ] 

Bruce Brouwer commented on LOG4J2-510:
--

What does your configuration look like that log4j2 is creating many open files? 
The general use case that I'm aware of opens a file and keeps it open for the 
life of the app. If you simply want a way to configure log4j to close a log 
file after some period of inactivity, this should be changed to an enhancement 
request. In that case, I would suggest delaying this until after 2.0 GA

 How to close inactive log files
 ---

 Key: LOG4J2-510
 URL: https://issues.apache.org/jira/browse/LOG4J2-510
 Project: Log4j 2
  Issue Type: Bug
  Components: Appenders
Affects Versions: 2.0-beta9
 Environment: linux
Reporter: Eric
  Labels: performance
 Fix For: 2.0-beta9


 Hi There,
 in log4j2 when the App start logging it create and open a file to log into 
 and that file stay open as long as the App is running.
 in my case log4j2 create and open too many files base on ThreadContext and 
 the OS (linux) will complaint that too many files are open and my App will 
 crash and stop responding.
 My question is:
  1 -  how do you close those files with log4j2 if they are inactive for a 
 period of time.
  2 - How do you have access to the log4j2 handle that open those files.
  3 - How do you tell log4j2 to open a file just for a period of time.
 Thanks
 Eric



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

-
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org



  1   2   >