logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bruce Brouwer (JIRA)" <j...@apache.org>
Subject [jira] [Comment Edited] (LOG4J2-547) Update LoggerStream API
Date Sun, 02 Mar 2014 17:02:31 GMT

    [ 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: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 = 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.2#6252)

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


Mime
View raw message