1
#region Copyright & License
3
// Copyright 2001-2005 The Apache Software Foundation
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
9
// http://www.apache.org/licenses/LICENSE-2.0
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
26
namespace log4net.Appender
29
/// Sends logging events to a <see cref="TextWriter"/>.
33
/// An Appender that writes to a <see cref="TextWriter"/>.
36
/// This appender may be used stand alone if initialized with an appropriate
37
/// writer, however it is typically used as a base class for an appender that
38
/// can open a <see cref="TextWriter"/> to write to.
41
/// <author>Nicko Cadell</author>
42
/// <author>Gert Driesen</author>
43
/// <author>Douglas de la Torre</author>
44
public class TextWriterAppender : AppenderSkeleton
46
#region Public Instance Constructors
49
/// Initializes a new instance of the <see cref="TextWriterAppender" /> class.
53
/// Default constructor.
56
public TextWriterAppender()
61
/// Initializes a new instance of the <see cref="TextWriterAppender" /> class and
62
/// sets the output destination to a new <see cref="StreamWriter"/> initialized
63
/// with the specified <see cref="Stream"/>.
65
/// <param name="layout">The layout to use with this appender.</param>
66
/// <param name="os">The <see cref="Stream"/> to output to.</param>
69
/// Obsolete constructor.
72
[Obsolete("Instead use the default constructor and set the Layout & Writer properties")]
73
public TextWriterAppender(ILayout layout, Stream os) : this(layout, new StreamWriter(os))
78
/// Initializes a new instance of the <see cref="TextWriterAppender" /> class and sets
79
/// the output destination to the specified <see cref="StreamWriter" />.
81
/// <param name="layout">The layout to use with this appender</param>
82
/// <param name="writer">The <see cref="TextWriter" /> to output to</param>
84
/// The <see cref="TextWriter" /> must have been previously opened.
88
/// Obsolete constructor.
91
[Obsolete("Instead use the default constructor and set the Layout & Writer properties")]
92
public TextWriterAppender(ILayout layout, TextWriter writer)
100
#region Public Instance Properties
103
/// Gets or set whether the appender will flush at the end
104
/// of each append operation.
108
/// The default behavior is to flush at the end of each
109
/// append operation.
112
/// If this option is set to <c>false</c>, then the underlying
113
/// stream can defer persisting the logging event to a later
118
/// Avoiding the flush operation at the end of each append results in
119
/// a performance gain of 10 to 20 percent. However, there is safety
120
/// trade-off involved in skipping flushing. Indeed, when flushing is
121
/// skipped, then it is likely that the last few log events will not
122
/// be recorded on disk when the application exits. This is a high
123
/// price to pay even for a 20% performance gain.
125
public bool ImmediateFlush
127
get { return m_immediateFlush; }
128
set { m_immediateFlush = value; }
132
/// Sets the <see cref="TextWriter"/> where the log output will go.
136
/// The specified <see cref="TextWriter"/> must be open and writable.
139
/// The <see cref="TextWriter"/> will be closed when the appender
140
/// instance is closed.
143
/// <b>Note:</b> Logging to an unopened <see cref="TextWriter"/> will fail.
146
virtual public TextWriter Writer
148
get { return m_qtw; }
156
m_qtw = new QuietTextWriter(value, ErrorHandler);
163
#endregion Public Instance Properties
165
#region Override implementation of AppenderSkeleton
168
/// This method determines if there is a sense in attempting to append.
172
/// This method checked if an output target has been set and if a
173
/// layout has been set.
176
/// <returns><c>false</c> if any of the preconditions fail.</returns>
177
override protected bool PreAppendCheck()
179
if (!base.PreAppendCheck())
186
// Allow subclass to lazily create the writer
191
ErrorHandler.Error("No output stream or file set for the appender named ["+ Name +"].");
197
ErrorHandler.Error("Output stream for appender named ["+ Name +"] has been closed.");
205
/// This method is called by the <see cref="AppenderSkeleton.DoAppend(LoggingEvent)"/>
208
/// <param name="loggingEvent">The event to log.</param>
211
/// Writes a log statement to the output stream if the output stream exists
215
/// The format of the output will depend on the appender's layout.
218
override protected void Append(LoggingEvent loggingEvent)
220
RenderLoggingEvent(m_qtw, loggingEvent);
222
if (m_immediateFlush)
229
/// This method is called by the <see cref="AppenderSkeleton.DoAppend(LoggingEvent[])"/>
232
/// <param name="loggingEvents">The array of events to log.</param>
235
/// This method writes all the bulk logged events to the output writer
236
/// before flushing the stream.
239
override protected void Append(LoggingEvent[] loggingEvents)
241
foreach(LoggingEvent loggingEvent in loggingEvents)
243
RenderLoggingEvent(m_qtw, loggingEvent);
246
if (m_immediateFlush)
253
/// Close this appender instance. The underlying stream or writer is also closed.
256
/// Closed appenders cannot be reused.
258
override protected void OnClose()
267
/// Gets or set the <see cref="IErrorHandler"/> and the underlying
268
/// <see cref="QuietTextWriter"/>, if any, for this appender.
271
/// The <see cref="IErrorHandler"/> for this appender.
273
override public IErrorHandler ErrorHandler
275
get { return base.ErrorHandler; }
282
LogLog.Warn("TextWriterAppender: You have tried to set a null error-handler.");
286
base.ErrorHandler = value;
289
m_qtw.ErrorHandler = value;
297
/// This appender requires a <see cref="Layout"/> to be set.
299
/// <value><c>true</c></value>
302
/// This appender requires a <see cref="Layout"/> to be set.
305
override protected bool RequiresLayout
310
#endregion Override implementation of AppenderSkeleton
312
#region Protected Instance Methods
315
/// Writes the footer and closes the underlying <see cref="TextWriter"/>.
319
/// Writes the footer and closes the underlying <see cref="TextWriter"/>.
322
virtual protected void WriteFooterAndCloseWriter()
329
/// Closes the underlying <see cref="TextWriter"/>.
333
/// Closes the underlying <see cref="TextWriter"/>.
336
virtual protected void CloseWriter()
346
ErrorHandler.Error("Could not close writer ["+m_qtw+"]", e);
347
// do need to invoke an error handler
348
// at this late stage
354
/// Clears internal references to the underlying <see cref="TextWriter" />
355
/// and other variables.
359
/// Subclasses can override this method for an alternate closing behavior.
362
virtual protected void Reset()
364
WriteFooterAndCloseWriter();
369
/// Writes a footer as produced by the embedded layout's <see cref="ILayout.Footer"/> property.
373
/// Writes a footer as produced by the embedded layout's <see cref="ILayout.Footer"/> property.
376
virtual protected void WriteFooter()
378
if (Layout != null && m_qtw != null && !m_qtw.Closed)
380
string f = Layout.Footer;
389
/// Writes a header produced by the embedded layout's <see cref="ILayout.Header"/> property.
393
/// Writes a header produced by the embedded layout's <see cref="ILayout.Header"/> property.
396
virtual protected void WriteHeader()
398
if (Layout != null && m_qtw != null && !m_qtw.Closed)
400
string h = Layout.Header;
409
/// Called to allow a subclass to lazily initialize the writer
413
/// This method is called when an event is logged and the <see cref="Writer"/> or
414
/// <see cref="QuietWriter"/> have not been set. This allows a subclass to
415
/// attempt to initialize the writer multiple times.
418
virtual protected void PrepareWriter()
422
#endregion Protected Instance Methods
425
/// Gets or sets the <see cref="log4net.Util.QuietTextWriter"/> where logging events
426
/// will be written to.
429
/// The <see cref="log4net.Util.QuietTextWriter"/> where logging events are written.
433
/// This is the <see cref="log4net.Util.QuietTextWriter"/> where logging events
434
/// will be written to.
437
protected QuietTextWriter QuietWriter
439
get { return m_qtw; }
440
set { m_qtw = value; }
443
#region Private Instance Fields
446
/// This is the <see cref="log4net.Util.QuietTextWriter"/> where logging events
447
/// will be written to.
449
private QuietTextWriter m_qtw;
452
/// Immediate flush means that the underlying <see cref="TextWriter" />
453
/// or output stream will be flushed at the end of each append operation.
457
/// Immediate flush is slower but ensures that each append request is
458
/// actually written. If <see cref="ImmediateFlush"/> is set to
459
/// <c>false</c>, then there is a good chance that the last few
460
/// logging events are not actually persisted if and when the application
464
/// The default value is <c>true</c>.
467
private bool m_immediateFlush = true;
469
#endregion Private Instance Fields