You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Martin Nyolt <a3...@freenet.de> on 2011/02/18 15:01:42 UTC

Log4j closes System.err

Hello,

I use the following code to load a default configuration in case no configuration was set using the log4j.configuration property:

static {
	LOGGER = Logger.getLogger(MyClass.class);
	Logger root = Logger.getRootLogger();
	boolean inited = root.getAllAppenders().hasMoreElements();

	if (!inited) {
		Layout layout = new PatternLayout("%-5p [%t]: %m%n");
		// create Appender to System.err
		ConsoleAppender app = new ConsoleAppender(layout, ConsoleAppender.SYSTEM_ERR);
		// set the follow option
		app.setFollow(true);
		app.activateOptions();
		root.addAppender(app);
		root.setLevel(Level.ERROR);
	}
}

If I don't call "app.activateOptions()", the follow-option wouldn't take effect (and I do need "follow" to be true).
But activateOptions finally calls WriterAppender.reset, which calls ConsoleAppender.close and closes the previous output stream, in this case System.err - but closing System.err is not a good idea, as it is still needed - I just want to change the Follow-Option.

Is this a misbehaviour of log4j, or am I incorrectly using the API?

Best regards
Martin Nyolt

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


Re: Log4j closes System.err

Posted by Martin Nyolt <a3...@freenet.de>.
On 28/02/11 16:26, Christian Grobmeier wrote:
>>
>> activateOptions calls WriterAppender.setWriter(), which first calls reset(),
>> which in turn calls closeWriter().
>> see
>> https://svn.apache.org/repos/asf/logging/log4j/trunk/src/main/java/org/apache/log4j/WriterAppender.java
>> (the base class of ConsoleAppender containing all mentioned methods)
>
> yes, but its creating a new quiet writer afterwards. so you should be
> able to write to another stream, right?

No, in my case neither I nor log4j are able to write to System.err, have a look at the attached code.

The expected output is (# denote writes to System.err, otherwise to System.out):

#Writing to System.err #1
configuring log4j
Test
#Writing to System.err #2
#ERROR [main]: Logging some message
Finished


But the output actually looks like:

#Writing to System.err #1
configuring log4j
Test
Finished


If I debug this application and configure Eclipse to break on any caught IOException, the thread pauses with this StackTrace:

Thread [main] (Suspended (exception IOException))	
	PrintStream.ensureOpen() line: 275	
	PrintStream.write(String) line: 474	
	PrintStream.print(String) line: 619	
	PrintStream.println(String) line: 756	
	Log4jTest.main(String[]) line: 29	

PrintStream.ensureOpen() line 275 is «throw new IOException("Stream closed");»
Thus no output is made. The same is true for the logging statement, since it uses System.err, too.

Martin

Re: Log4j closes System.err

Posted by Christian Grobmeier <gr...@gmail.com>.
>
> activateOptions calls WriterAppender.setWriter(), which first calls reset(),
> which in turn calls closeWriter().
> see
> https://svn.apache.org/repos/asf/logging/log4j/trunk/src/main/java/org/apache/log4j/WriterAppender.java
> (the base class of ConsoleAppender containing all mentioned methods)

yes, but its creating a new quiet writer afterwards. so you should be
able to write to another stream, right?

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


Re: Log4j closes System.err

Posted by Martin Nyolt <a3...@freenet.de>.
On 28.02.2011 16:07, Christian Grobmeier wrote:
>>> Looking at the source code, I
>>> cannot see what you mean - in consoleappender new streams are created,
>>> the writerappender is doing nothing. Were is it closed? As far as I
>>> can see only the previous stream is closed, once you set a new one.
>>
>> But in this case, only the follow option is changed, so the previous
>> (underlying) stream is the same as the new one. I. e. the stream is closed,
>> so  writing to it fails.
>>
>> But nevertheless, even if I would change the stream, from say System.err to
>> System.out, the previous stream shouldn't be closed, as no one could ever
>> write to System.err again.
>
> Think you got me wrong... please look at this file:
> https://svn.apache.org/repos/asf/logging/log4j/trunk/src/main/java/org/apache/log4j/ConsoleAppender.java
>
> to activateOptions. You call this and it will set the standard i/o. I
> cannot see were it is closed. Can you point me?
>

activateOptions calls WriterAppender.setWriter(), which first calls reset(), which in turn calls closeWriter().
see
https://svn.apache.org/repos/asf/logging/log4j/trunk/src/main/java/org/apache/log4j/WriterAppender.java
(the base class of ConsoleAppender containing all mentioned methods)

Martin

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


Re: Log4j closes System.err

Posted by Christian Grobmeier <gr...@gmail.com>.
>> Not being deep into log4j, but in log4php world its necessary in most
>> cases to activateOptions on an appender.
>
> That's what I'm doing.  Look at my first mail.

Yes, I wanted to express that this looks correct to me.

>> Looking at the source code, I
>> cannot see what you mean - in consoleappender new streams are created,
>> the writerappender is doing nothing. Were is it closed? As far as I
>> can see only the previous stream is closed, once you set a new one.
>
> But in this case, only the follow option is changed, so the previous
> (underlying) stream is the same as the new one. I. e. the stream is closed,
> so  writing to it fails.
>
> But nevertheless, even if I would change the stream, from say System.err to
> System.out, the previous stream shouldn't be closed, as no one could ever
> write to System.err again.

Think you got me wrong... please look at this file:
https://svn.apache.org/repos/asf/logging/log4j/trunk/src/main/java/org/apache/log4j/ConsoleAppender.java

to activateOptions. You call this and it will set the standard i/o. I
cannot see were it is closed. Can you point me?

cheers

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


Re: Log4j closes System.err

Posted by Martin Nyolt <a3...@freenet.de>.
On 28.02.2011 15:52, Christian Grobmeier wrote:
>>> If I don't call "app.activateOptions()", the follow-option wouldn't take
>>> effect (and I do need "follow" to be true).
>>> But activateOptions finally calls WriterAppender.reset, which calls
>>> ConsoleAppender.close and closes the previous output stream, in this case
>>> System.err - but closing System.err is not a good idea, as it is still
>>> needed - I just want to change the Follow-Option.
>
> Not being deep into log4j, but in log4php world its necessary in most
> cases to activateOptions on an appender.

That's what I'm doing.  Look at my first mail.

> Looking at the source code, I
> cannot see what you mean - in consoleappender new streams are created,
> the writerappender is doing nothing. Were is it closed? As far as I
> can see only the previous stream is closed, once you set a new one.

But in this case, only the follow option is changed, so the previous (underlying) stream is the same as the new one. I. e. the stream is closed, so  writing to it fails.

But nevertheless, even if I would change the stream, from say System.err to System.out, the previous stream shouldn't be closed, as no one could ever write to System.err again.

Martin

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


Re: Log4j closes System.err

Posted by Christian Grobmeier <gr...@gmail.com>.
> No idea, anyone?

Guess most people prefer xml/properties for config - its a bit unusual

>> If I don't call "app.activateOptions()", the follow-option wouldn't take
>> effect (and I do need "follow" to be true).
>> But activateOptions finally calls WriterAppender.reset, which calls
>> ConsoleAppender.close and closes the previous output stream, in this case
>> System.err - but closing System.err is not a good idea, as it is still
>> needed - I just want to change the Follow-Option.

Not being deep into log4j, but in log4php world its necessary in most
cases to activateOptions on an appender. Looking at the source code, I
cannot see what you mean - in consoleappender new streams are created,
the writerappender is doing nothing. Were is it closed? As far as I
can see only the previous stream is closed, once you set a new one.

Cheers,
Christian

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


Re: Log4j closes System.err

Posted by Curt Arnold <ca...@apache.org>.
On Feb 28, 2011, at 4:41 AM, Martin Nyolt wrote:

> No idea, anyone?
> Appearently, this has to work somehow, since using a configuration file you can set the follow-option to be true without closing any stream.
> But I never found any hint how to do this.
> 
> Am 18.02.2011 15:01, schrieb Martin Nyolt:
>> Hello,
>> 
>> I use the following code to load a default configuration in case no configuration was set using the log4j.configuration property:
>> 
>> static {
>> LOGGER = Logger.getLogger(MyClass.class);
>> Logger root = Logger.getRootLogger();
>> boolean inited = root.getAllAppenders().hasMoreElements();
>> 
>> if (!inited) {
>> Layout layout = new PatternLayout("%-5p [%t]: %m%n");
>> // create Appender to System.err
>> ConsoleAppender app = new ConsoleAppender(layout, ConsoleAppender.SYSTEM_ERR);


The preceding call is the problem.  The configurators call the default constructor (in this case, new ConsoleAppender()), then call property setters, then call activateOptions().  The non-default constructors are convenience functions that result in a fully activated appender ready to go in one call.  However, in this case, that behavior is not desired.  Switch this to a default constructor and calls to setLayout, setTarget, setFollow and then activateOptions.
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Re: Log4j closes System.err

Posted by Martin Nyolt <a3...@freenet.de>.
No idea, anyone?
Appearently, this has to work somehow, since using a configuration file you can set the follow-option to be true without closing any stream.
But I never found any hint how to do this.

Am 18.02.2011 15:01, schrieb Martin Nyolt:
> Hello,
>
> I use the following code to load a default configuration in case no configuration was set using the log4j.configuration property:
>
> static {
> LOGGER = Logger.getLogger(MyClass.class);
> Logger root = Logger.getRootLogger();
> boolean inited = root.getAllAppenders().hasMoreElements();
>
> if (!inited) {
> Layout layout = new PatternLayout("%-5p [%t]: %m%n");
> // create Appender to System.err
> ConsoleAppender app = new ConsoleAppender(layout, ConsoleAppender.SYSTEM_ERR);
> // set the follow option
> app.setFollow(true);
> app.activateOptions();
> root.addAppender(app);
> root.setLevel(Level.ERROR);
> }
> }
>
> If I don't call "app.activateOptions()", the follow-option wouldn't take effect (and I do need "follow" to be true).
> But activateOptions finally calls WriterAppender.reset, which calls ConsoleAppender.close and closes the previous output stream, in this case System.err - but closing System.err is not a good idea, as it is still needed - I just want to change the Follow-Option.
>
> Is this a misbehaviour of log4j, or am I incorrectly using the API?
>
> Best regards
> Martin Nyolt


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