#region Apache License
|
//
|
// Licensed to the Apache Software Foundation (ASF) under one or more
|
// contributor license agreements. See the NOTICE file distributed with
|
// this work for additional information regarding copyright ownership.
|
// The ASF licenses this file to you under the Apache License, Version 2.0
|
// (the "License"); you may not use this file except in compliance with
|
// the License. You may obtain a copy of the License at
|
//
|
// http://www.apache.org/licenses/LICENSE-2.0
|
//
|
// Unless required by applicable law or agreed to in writing, software
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// See the License for the specific language governing permissions and
|
// limitations under the License.
|
//
|
#endregion
|
|
using System;
|
|
using log4net.Core;
|
using log4net.Appender;
|
|
namespace log4net.Util
|
{
|
/// <summary>
|
/// A straightforward implementation of the <see cref="IAppenderAttachable"/> interface.
|
/// </summary>
|
/// <remarks>
|
/// <para>
|
/// This is the default implementation of the <see cref="IAppenderAttachable"/>
|
/// interface. Implementors of the <see cref="IAppenderAttachable"/> interface
|
/// should aggregate an instance of this type.
|
/// </para>
|
/// </remarks>
|
/// <author>Nicko Cadell</author>
|
/// <author>Gert Driesen</author>
|
public class AppenderAttachedImpl : IAppenderAttachable
|
{
|
#region Public Instance Constructors
|
|
/// <summary>
|
/// Constructor
|
/// </summary>
|
/// <remarks>
|
/// <para>
|
/// Initializes a new instance of the <see cref="AppenderAttachedImpl"/> class.
|
/// </para>
|
/// </remarks>
|
public AppenderAttachedImpl()
|
{
|
}
|
|
#endregion Public Instance Constructors
|
|
#region Public Instance Methods
|
|
/// <summary>
|
/// Append on on all attached appenders.
|
/// </summary>
|
/// <param name="loggingEvent">The event being logged.</param>
|
/// <returns>The number of appenders called.</returns>
|
/// <remarks>
|
/// <para>
|
/// Calls the <see cref="IAppender.DoAppend" /> method on all
|
/// attached appenders.
|
/// </para>
|
/// </remarks>
|
public int AppendLoopOnAppenders(LoggingEvent loggingEvent)
|
{
|
if (loggingEvent == null)
|
{
|
throw new ArgumentNullException("loggingEvent");
|
}
|
|
// m_appenderList is null when empty
|
if (m_appenderList == null)
|
{
|
return 0;
|
}
|
|
if (m_appenderArray == null)
|
{
|
m_appenderArray = m_appenderList.ToArray();
|
}
|
|
foreach(IAppender appender in m_appenderArray)
|
{
|
try
|
{
|
appender.DoAppend(loggingEvent);
|
}
|
catch(Exception ex)
|
{
|
LogLog.Error(declaringType, "Failed to append to appender [" + appender.Name + "]", ex);
|
}
|
}
|
return m_appenderList.Count;
|
}
|
|
/// <summary>
|
/// Append on on all attached appenders.
|
/// </summary>
|
/// <param name="loggingEvents">The array of events being logged.</param>
|
/// <returns>The number of appenders called.</returns>
|
/// <remarks>
|
/// <para>
|
/// Calls the <see cref="IAppender.DoAppend" /> method on all
|
/// attached appenders.
|
/// </para>
|
/// </remarks>
|
public int AppendLoopOnAppenders(LoggingEvent[] loggingEvents)
|
{
|
if (loggingEvents == null)
|
{
|
throw new ArgumentNullException("loggingEvents");
|
}
|
if (loggingEvents.Length == 0)
|
{
|
throw new ArgumentException("loggingEvents array must not be empty", "loggingEvents");
|
}
|
if (loggingEvents.Length == 1)
|
{
|
// Fall back to single event path
|
return AppendLoopOnAppenders(loggingEvents[0]);
|
}
|
|
// m_appenderList is null when empty
|
if (m_appenderList == null)
|
{
|
return 0;
|
}
|
|
if (m_appenderArray == null)
|
{
|
m_appenderArray = m_appenderList.ToArray();
|
}
|
|
foreach(IAppender appender in m_appenderArray)
|
{
|
try
|
{
|
CallAppend(appender, loggingEvents);
|
}
|
catch(Exception ex)
|
{
|
LogLog.Error(declaringType, "Failed to append to appender [" + appender.Name + "]", ex);
|
}
|
}
|
return m_appenderList.Count;
|
}
|
|
#endregion Public Instance Methods
|
|
#region Private Static Methods
|
|
/// <summary>
|
/// Calls the DoAppende method on the <see cref="IAppender"/> with
|
/// the <see cref="LoggingEvent"/> objects supplied.
|
/// </summary>
|
/// <param name="appender">The appender</param>
|
/// <param name="loggingEvents">The events</param>
|
/// <remarks>
|
/// <para>
|
/// If the <paramref name="appender" /> supports the <see cref="IBulkAppender"/>
|
/// interface then the <paramref name="loggingEvents" /> will be passed
|
/// through using that interface. Otherwise the <see cref="LoggingEvent"/>
|
/// objects in the array will be passed one at a time.
|
/// </para>
|
/// </remarks>
|
private static void CallAppend(IAppender appender, LoggingEvent[] loggingEvents)
|
{
|
IBulkAppender bulkAppender = appender as IBulkAppender;
|
if (bulkAppender != null)
|
{
|
bulkAppender.DoAppend(loggingEvents);
|
}
|
else
|
{
|
foreach(LoggingEvent loggingEvent in loggingEvents)
|
{
|
appender.DoAppend(loggingEvent);
|
}
|
}
|
}
|
|
#endregion
|
|
#region Implementation of IAppenderAttachable
|
|
/// <summary>
|
/// Attaches an appender.
|
/// </summary>
|
/// <param name="newAppender">The appender to add.</param>
|
/// <remarks>
|
/// <para>
|
/// If the appender is already in the list it won't be added again.
|
/// </para>
|
/// </remarks>
|
public void AddAppender(IAppender newAppender)
|
{
|
// Null values for newAppender parameter are strictly forbidden.
|
if (newAppender == null)
|
{
|
throw new ArgumentNullException("newAppender");
|
}
|
|
m_appenderArray = null;
|
if (m_appenderList == null)
|
{
|
m_appenderList = new AppenderCollection(1);
|
}
|
if (!m_appenderList.Contains(newAppender))
|
{
|
m_appenderList.Add(newAppender);
|
}
|
}
|
|
/// <summary>
|
/// Gets all attached appenders.
|
/// </summary>
|
/// <returns>
|
/// A collection of attached appenders, or <c>null</c> if there
|
/// are no attached appenders.
|
/// </returns>
|
/// <remarks>
|
/// <para>
|
/// The read only collection of all currently attached appenders.
|
/// </para>
|
/// </remarks>
|
public AppenderCollection Appenders
|
{
|
get
|
{
|
if (m_appenderList == null)
|
{
|
// We must always return a valid collection
|
return AppenderCollection.EmptyCollection;
|
}
|
else
|
{
|
return AppenderCollection.ReadOnly(m_appenderList);
|
}
|
}
|
}
|
|
/// <summary>
|
/// Gets an attached appender with the specified name.
|
/// </summary>
|
/// <param name="name">The name of the appender to get.</param>
|
/// <returns>
|
/// The appender with the name specified, or <c>null</c> if no appender with the
|
/// specified name is found.
|
/// </returns>
|
/// <remarks>
|
/// <para>
|
/// Lookup an attached appender by name.
|
/// </para>
|
/// </remarks>
|
public IAppender GetAppender(string name)
|
{
|
if (m_appenderList != null && name != null)
|
{
|
foreach(IAppender appender in m_appenderList)
|
{
|
if (name == appender.Name)
|
{
|
return appender;
|
}
|
}
|
}
|
return null;
|
}
|
|
/// <summary>
|
/// Removes all attached appenders.
|
/// </summary>
|
/// <remarks>
|
/// <para>
|
/// Removes and closes all attached appenders
|
/// </para>
|
/// </remarks>
|
public void RemoveAllAppenders()
|
{
|
if (m_appenderList != null)
|
{
|
foreach(IAppender appender in m_appenderList)
|
{
|
try
|
{
|
appender.Close();
|
}
|
catch(Exception ex)
|
{
|
LogLog.Error(declaringType, "Failed to Close appender ["+appender.Name+"]", ex);
|
}
|
}
|
m_appenderList = null;
|
m_appenderArray = null;
|
}
|
}
|
|
/// <summary>
|
/// Removes the specified appender from the list of attached appenders.
|
/// </summary>
|
/// <param name="appender">The appender to remove.</param>
|
/// <returns>The appender removed from the list</returns>
|
/// <remarks>
|
/// <para>
|
/// The appender removed is not closed.
|
/// If you are discarding the appender you must call
|
/// <see cref="IAppender.Close"/> on the appender removed.
|
/// </para>
|
/// </remarks>
|
public IAppender RemoveAppender(IAppender appender)
|
{
|
if (appender != null && m_appenderList != null)
|
{
|
m_appenderList.Remove(appender);
|
if (m_appenderList.Count == 0)
|
{
|
m_appenderList = null;
|
}
|
m_appenderArray = null;
|
}
|
return appender;
|
}
|
|
/// <summary>
|
/// Removes the appender with the specified name from the list of appenders.
|
/// </summary>
|
/// <param name="name">The name of the appender to remove.</param>
|
/// <returns>The appender removed from the list</returns>
|
/// <remarks>
|
/// <para>
|
/// The appender removed is not closed.
|
/// If you are discarding the appender you must call
|
/// <see cref="IAppender.Close"/> on the appender removed.
|
/// </para>
|
/// </remarks>
|
public IAppender RemoveAppender(string name)
|
{
|
return RemoveAppender(GetAppender(name));
|
}
|
|
#endregion
|
|
#region Private Instance Fields
|
|
/// <summary>
|
/// List of appenders
|
/// </summary>
|
private AppenderCollection m_appenderList;
|
|
/// <summary>
|
/// Array of appenders, used to cache the m_appenderList
|
/// </summary>
|
private IAppender[] m_appenderArray;
|
|
#endregion Private Instance Fields
|
|
#region Private Static Fields
|
|
/// <summary>
|
/// The fully qualified type of the AppenderAttachedImpl class.
|
/// </summary>
|
/// <remarks>
|
/// Used by the internal logger to record the Type of the
|
/// log message.
|
/// </remarks>
|
private readonly static Type declaringType = typeof(AppenderAttachedImpl);
|
|
#endregion Private Static Fields
|
}
|
}
|