allow the logging system to recursively log using itself
patch by @JJoe2
closes #41
diff --git a/src/Util/ReaderWriterLock.cs b/src/Util/ReaderWriterLock.cs
index 5ed53c5..807a3da 100644
--- a/src/Util/ReaderWriterLock.cs
+++ b/src/Util/ReaderWriterLock.cs
@@ -64,7 +64,7 @@
#if HAS_READERWRITERLOCK
#if HAS_READERWRITERLOCKSLIM
- m_lock = new System.Threading.ReaderWriterLockSlim();
+ m_lock = new System.Threading.ReaderWriterLockSlim(System.Threading.LockRecursionPolicy.SupportsRecursion);
#else
m_lock = new System.Threading.ReaderWriterLock();
#endif
diff --git a/tests/src/Appender/EventRaisingAppender.cs b/tests/src/Appender/EventRaisingAppender.cs
new file mode 100644
index 0000000..517b6bd
--- /dev/null
+++ b/tests/src/Appender/EventRaisingAppender.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace log4net.Tests.Appender
+{
+ /// <summary>
+ /// Provides data for the <see cref="EventRaisingAppender.LoggingEventAppended"/> event.
+ /// </summary>
+ /// <seealso cref="System.EventArgs" />
+ public class LoggingEventEventArgs : EventArgs
+ {
+ public log4net.Core.LoggingEvent LoggingEvent { get; private set; }
+
+ public LoggingEventEventArgs(log4net.Core.LoggingEvent loggingEvent)
+ {
+ if (loggingEvent == null) throw new ArgumentNullException("loggingEvent");
+ LoggingEvent = loggingEvent;
+ }
+ }
+
+ /// <summary>
+ /// A log4net appender that raises an event each time a logging event is appended
+ /// </summary>
+ /// <remarks>
+ /// This class is intended to provide a way for test code to inspect logging
+ /// events as they are generated.
+ /// </remarks>
+ public class EventRaisingAppender : log4net.Appender.IAppender
+ {
+ public event EventHandler<LoggingEventEventArgs> LoggingEventAppended;
+
+ protected void OnLoggingEventAppended(LoggingEventEventArgs e)
+ {
+ var loggingEventAppended = LoggingEventAppended;
+ if (loggingEventAppended != null)
+ {
+ loggingEventAppended(this, e);
+ }
+ }
+
+ public void Close()
+ {
+ }
+
+ public void DoAppend(log4net.Core.LoggingEvent loggingEvent)
+ {
+ OnLoggingEventAppended(new LoggingEventEventArgs(loggingEvent));
+ }
+
+ public string Name
+ {
+ get; set;
+ }
+ }
+}
diff --git a/tests/src/Appender/RecursiveLoggingTest.cs b/tests/src/Appender/RecursiveLoggingTest.cs
new file mode 100644
index 0000000..4b9aeb2
--- /dev/null
+++ b/tests/src/Appender/RecursiveLoggingTest.cs
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+using System;
+using System.Data;
+using System.Xml;
+using log4net.Appender;
+using log4net.Config;
+using log4net.Core;
+using log4net.Layout;
+using log4net.Repository;
+using log4net.Util;
+using NUnit.Framework;
+using System.Globalization;
+
+namespace log4net.Tests.Appender
+{
+ [TestFixture]
+ public class RecursiveLoggingTest
+ {
+ private EventRaisingAppender m_eventRaisingAppender;
+ private Repository.Hierarchy.Hierarchy m_hierarchy;
+ private int m_eventCount;
+ private ILogger m_logger;
+ private const int MaxRecursion = 3;
+
+ private void SetupRepository()
+ {
+ m_hierarchy = new Repository.Hierarchy.Hierarchy();
+
+ m_eventRaisingAppender = new EventRaisingAppender();
+ m_eventRaisingAppender.LoggingEventAppended += eventRaisingAppender_LoggingEventAppended;
+
+ m_hierarchy.Root.Level = Level.All;
+ m_hierarchy.Root.AddAppender(m_eventRaisingAppender);
+
+ BasicConfigurator.Configure(m_hierarchy, m_eventRaisingAppender);
+
+ m_logger = m_hierarchy.GetLogger("test");
+
+ }
+
+ void eventRaisingAppender_LoggingEventAppended(object sender, LoggingEventEventArgs e)
+ {
+ if (m_eventCount < MaxRecursion && m_logger != null)
+ {
+ m_eventCount++;
+ string message = String.Format(CultureInfo.CurrentCulture, "Log event {0} from EventRaisingAppender", m_eventCount);
+ Console.WriteLine("Logging message: " + message);
+ m_logger.Log(typeof(RecursiveLoggingTest), Level.Warn, message, null);
+ }
+ }
+
+ [Test]
+ public void TestAllowRecursiveLoggingFromAppender()
+ {
+ SetupRepository();
+
+ m_eventCount = 0;
+ m_logger.Log(typeof(RecursiveLoggingTest), Level.Warn, "Message logged", null);
+
+ Assert.AreEqual(MaxRecursion, m_eventCount, "Expected MaxRecursion recursive calls");
+ }
+
+ }
+}
diff --git a/tests/src/log4net.Tests.vs2012.csproj b/tests/src/log4net.Tests.vs2012.csproj
index 633afd2..81bbb16 100644
--- a/tests/src/log4net.Tests.vs2012.csproj
+++ b/tests/src/log4net.Tests.vs2012.csproj
@@ -150,9 +150,11 @@
<Compile Include="Appender\EventLogAppenderTest.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Appender\EventRaisingAppender.cs" />
<Compile Include="Appender\MemoryAppenderTest.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Appender\RecursiveLoggingTest.cs" />
<Compile Include="Appender\RemotingAppenderTest.cs">
<SubType>Code</SubType>
</Compile>