[ https://issues.apache.org/jira/browse/LOG4J2-547?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=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 = 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?
Post by Matt Sicker (JIRA)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)