blob: b828f2a21e358f81dc400198621c94d3a950fc76 [file] [log] [blame]
#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.Collections.Generic;
using log4net.Core;
using log4net.Util;
namespace log4net.Appender;
/// <summary>
/// Stores logging events in an array.
/// </summary>
/// <remarks>
/// <para>
/// The memory appender stores all the logging events
/// that are appended in an in-memory array.
/// </para>
/// <para>
/// Use the <see cref="PopAllEvents()"/> method to get
/// and clear the current list of events that have been appended.
/// </para>
/// <para>
/// Use the <see cref="GetEvents()"/> method to get the current
/// list of events that have been appended. Note there is a
/// race-condition when calling <see cref="GetEvents()"/> and
/// <see cref="Clear()"/> in pairs, you better use <see
/// mref="M:PopAllEvents()"/> in that case.
/// </para>
/// <para>
/// Use the <see cref="Clear()"/> method to clear the
/// current list of events. Note there is a
/// race-condition when calling <see cref="GetEvents()"/> and
/// <see cref="Clear()"/> in pairs, you better use <see
/// mref="M:PopAllEvents()"/> in that case.
/// </para>
/// </remarks>
/// <author>Julian Biddle</author>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
public class MemoryAppender : AppenderSkeleton
{
/// <summary>
/// Gets the events that have been logged.
/// </summary>
/// <returns>The events that have been logged</returns>
public virtual LoggingEvent[] GetEvents()
{
lock (_syncRoot)
{
return m_eventsList.ToArray();
}
}
/// <summary>
/// Gets or sets the fields that will be fixed in the event
/// </summary>
/// <remarks>
/// <para>
/// The logging event needs to have certain thread specific values
/// captured before it can be buffered. See <see cref="LoggingEvent.Fix"/>
/// for details.
/// </para>
/// </remarks>
public virtual FixFlags Fix { get; set; } = FixFlags.All;
/// <summary>
/// This method is called by the <see cref="AppenderSkeleton.DoAppend(LoggingEvent)"/> method.
/// </summary>
/// <param name="loggingEvent">the event to log</param>
/// <remarks>
/// <para>Stores the <paramref name="loggingEvent"/> in the events list.</para>
/// </remarks>
protected override void Append(LoggingEvent loggingEvent)
{
// Because we are caching the LoggingEvent beyond the
// lifetime of the Append() method we must fix any
// volatile data in the event.
loggingEvent.EnsureNotNull().Fix = Fix;
lock (_syncRoot)
{
m_eventsList.Add(loggingEvent);
}
}
/// <summary>
/// Clear the list of events
/// </summary>
/// <remarks>
/// Clear the list of events
/// </remarks>
public virtual void Clear()
{
lock (_syncRoot)
{
m_eventsList.Clear();
}
}
/// <summary>
/// Gets the events that have been logged and clears the list of events.
/// </summary>
/// <returns>The events that have been logged</returns>
public virtual LoggingEvent[] PopAllEvents()
{
lock (_syncRoot)
{
LoggingEvent[] tmp = m_eventsList.ToArray();
m_eventsList.Clear();
return tmp;
}
}
/// <summary>
/// The list of events that have been appended.
/// </summary>
// ReSharper disable once InconsistentNaming
// ReSharper disable once FieldCanBeMadeReadOnly.Global
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1002:Do not expose generic lists")]
protected List<LoggingEvent> m_eventsList = [];
private readonly object _syncRoot = new();
}