From 3fe11733255c7d8b3baaf9192885976240f1d7ab Mon Sep 17 00:00:00 2001 From: Ron Grabowski Date: Mon, 26 Jul 2010 22:50:21 +0000 Subject: [PATCH 001/370] Simple example showing that filter properties can be set the same way as appender properties. git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@979481 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Filter/FilterTest.cs | 90 +++++++++++++++++++++++++++ tests/src/log4net.Tests.vs2008.csproj | 1 + 2 files changed, 91 insertions(+) create mode 100644 tests/src/Filter/FilterTest.cs diff --git a/tests/src/Filter/FilterTest.cs b/tests/src/Filter/FilterTest.cs new file mode 100644 index 00000000..6d9e1d50 --- /dev/null +++ b/tests/src/Filter/FilterTest.cs @@ -0,0 +1,90 @@ +#if NET_2_0 +using System; +using System.Collections.Generic; +using System.Xml; +using log4net.Appender; +using log4net.Config; +using log4net.Core; +using log4net.Filter; +using log4net.Repository; +using NUnit.Framework; + +namespace log4net.Tests.Filter +{ + [TestFixture] + public class FilterTest + { + [Test] + public void FilterConfigurationTest() + { + XmlDocument log4netConfig = new XmlDocument(); + #region Load log4netConfig + log4netConfig.LoadXml(@" + + + + + + + + + + + + + + + + + + "); + #endregion + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + XmlConfigurator.Configure(rep, log4netConfig["log4net"]); + + IAppender[] appenders = LogManager.GetRepository(rep.Name).GetAppenders(); + Assert.IsTrue(appenders.Length == 1); + + IAppender appender = Array.Find(appenders, a => a.Name == "MemoryAppender"); + Assert.IsNotNull(appender); + + MultiplePropertyFilter multiplePropertyFilter = + ((AppenderSkeleton)appender).FilterHead as MultiplePropertyFilter; + + var conditions = multiplePropertyFilter.GetConditions(); + Assert.AreEqual(2, conditions.Length); + Assert.AreEqual("ABC", conditions[0].Key); + Assert.AreEqual("123", conditions[0].StringToMatch); + Assert.AreEqual("DEF", conditions[1].Key); + Assert.AreEqual("456", conditions[1].StringToMatch); + } + } + + public class MultiplePropertyFilter : FilterSkeleton + { + private readonly List _conditions = new List(); + + public override FilterDecision Decide(LoggingEvent loggingEvent) + { + return FilterDecision.Accept; + } + + public Condition[] GetConditions() + { + return _conditions.ToArray(); + } + + public void AddCondition(Condition condition) + { + _conditions.Add(condition); + } + + public class Condition + { + public string Key { get; set; } + public string StringToMatch { get; set; } + } + } +} +#endif diff --git a/tests/src/log4net.Tests.vs2008.csproj b/tests/src/log4net.Tests.vs2008.csproj index 55f2070e..bd4f1660 100644 --- a/tests/src/log4net.Tests.vs2008.csproj +++ b/tests/src/log4net.Tests.vs2008.csproj @@ -149,6 +149,7 @@ Code + Code From 49046d1976cd69ddba15f81fa3da5435ce3a8696 Mon Sep 17 00:00:00 2001 From: Ron Grabowski Date: Wed, 13 Oct 2010 03:20:03 +0000 Subject: [PATCH 002/370] Removed old Visual Studio 2003 and 2005 project/solution files. git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1021980 13f79535-47bb-0310-9956-ffa450edef68 --- src/log4net.vs2003.csproj | 1146 ------------------------------------- src/log4net.vs2003.sln | 29 - 2 files changed, 1175 deletions(-) delete mode 100644 src/log4net.vs2003.csproj delete mode 100644 src/log4net.vs2003.sln diff --git a/src/log4net.vs2003.csproj b/src/log4net.vs2003.csproj deleted file mode 100644 index c8e0434f..00000000 --- a/src/log4net.vs2003.csproj +++ /dev/null @@ -1,1146 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/log4net.vs2003.sln b/src/log4net.vs2003.sln deleted file mode 100644 index 85ca6657..00000000 --- a/src/log4net.vs2003.sln +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.vs2003", "log4net.vs2003.csproj", "{F6A02431-167E-4347-BC43-65532C31CDB7}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Tests.vs2003", "..\tests\src\log4net.Tests.vs2003.csproj", "{4B68B77E-0C8B-4296-930D-6AC2787170B8}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {F6A02431-167E-4347-BC43-65532C31CDB7}.Debug.ActiveCfg = Debug|.NET - {F6A02431-167E-4347-BC43-65532C31CDB7}.Debug.Build.0 = Debug|.NET - {F6A02431-167E-4347-BC43-65532C31CDB7}.Release.ActiveCfg = Release|.NET - {F6A02431-167E-4347-BC43-65532C31CDB7}.Release.Build.0 = Release|.NET - {4B68B77E-0C8B-4296-930D-6AC2787170B8}.Debug.ActiveCfg = Debug|.NET - {4B68B77E-0C8B-4296-930D-6AC2787170B8}.Debug.Build.0 = Debug|.NET - {4B68B77E-0C8B-4296-930D-6AC2787170B8}.Release.ActiveCfg = Release|.NET - {4B68B77E-0C8B-4296-930D-6AC2787170B8}.Release.Build.0 = Release|.NET - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal From c5d98eb182301ac4d710ad3f620141bcaa21c835 Mon Sep 17 00:00:00 2001 From: Ron Grabowski Date: Wed, 13 Oct 2010 03:26:57 +0000 Subject: [PATCH 003/370] Additional fix for LOG4NET-59 to ensure correct call to System.IO.File.GetLastWriteTime or GetLastWriteTimeUtc git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1021982 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/RollingFileAppender.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs index 0f636c75..830982fc 100755 --- a/src/Appender/RollingFileAppender.cs +++ b/src/Appender/RollingFileAppender.cs @@ -778,7 +778,14 @@ private void RollOverIfDateBoundaryCrossing() DateTime last; using(SecurityContext.Impersonate(this)) { - last = System.IO.File.GetLastWriteTime(m_baseFileName); + if (DateTimeStrategy is UniversalDateTime) + { + last = System.IO.File.GetLastWriteTimeUtc(m_baseFileName); + } + else + { + last = System.IO.File.GetLastWriteTime(m_baseFileName); + } } LogLog.Debug(declaringType, "["+last.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo)+"] vs. ["+m_now.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo)+"]"); From 0638d553f4f365ac33b7b575d2cd37342846b789 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 17 Aug 2011 05:57:00 +0000 Subject: [PATCH 004/370] fix a bunch of svn properties, in particular eol-style git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1158529 13f79535-47bb-0310-9956-ffa450edef68 --- build.cmd | 222 +-- doc/css/site.css | 0 doc/css/style.css | 0 .../1.0/Performance/NotLogging/cs/nant.build | 0 .../1.0/Performance/NotLogging/cs/nant.config | 0 .../NotLogging/cs/src/AssemblyInfo.cs | 0 .../NotLogging/cs/src/NotLogging.cs | 0 .../1.0/Performance/NotLogging/nant.build | 0 .../1.0/Performance/NotLogging/nant.config | 0 examples/mono/1.0/Performance/nant.build | 0 examples/mono/1.0/Performance/nant.config | 0 .../1.0/Repository/SharedModule/cs/nant.build | 0 .../Repository/SharedModule/cs/nant.config | 0 .../SharedModule/cs/src/AssemblyInfo.cs | 0 .../Repository/SharedModule/cs/src/Math.cs | 0 .../1.0/Repository/SharedModule/nant.build | 0 .../1.0/Repository/SharedModule/nant.config | 0 .../1.0/Repository/SimpleApp/cs/nant.build | 0 .../1.0/Repository/SimpleApp/cs/nant.config | 0 .../Repository/SimpleApp/cs/src/App.config | 0 .../SimpleApp/cs/src/AssemblyInfo.cs | 0 .../Repository/SimpleApp/cs/src/EntryPoint.cs | 0 .../mono/1.0/Repository/SimpleApp/nant.build | 0 .../mono/1.0/Repository/SimpleApp/nant.config | 0 .../1.0/Repository/SimpleModule/cs/nant.build | 0 .../Repository/SimpleModule/cs/nant.config | 0 .../SimpleModule/cs/src/AssemblyInfo.cs | 0 .../Repository/SimpleModule/cs/src/Math.cs | 0 .../1.0/Repository/SimpleModule/nant.build | 0 .../1.0/Repository/SimpleModule/nant.config | 0 examples/mono/1.0/Repository/nant.build | 0 examples/mono/1.0/Repository/nant.config | 0 .../1.0/Tutorials/ConsoleApp/cs/nant.build | 0 .../1.0/Tutorials/ConsoleApp/cs/nant.config | 0 .../Tutorials/ConsoleApp/cs/src/App.config | 0 .../ConsoleApp/cs/src/AssemblyInfo.cs | 0 .../ConsoleApp/cs/src/LoggingExample.cs | 0 .../mono/1.0/Tutorials/ConsoleApp/nant.build | 0 .../mono/1.0/Tutorials/ConsoleApp/nant.config | 0 examples/mono/1.0/Tutorials/nant.build | 0 examples/mono/1.0/Tutorials/nant.config | 0 examples/mono/1.0/nant.build | 0 examples/mono/1.0/nant.config | 0 examples/mono/nant.build | 0 examples/mono/nant.config | 0 examples/nant.build | 0 examples/nant.config | 0 .../1.1/Repository/SharedModule/js/nant.build | 0 .../Repository/SharedModule/js/nant.config | 0 .../1.1/Repository/SharedModule/nant.build | 0 .../1.1/Repository/SharedModule/nant.config | 0 .../1.1/Repository/SimpleApp/js/nant.build | 0 .../1.1/Repository/SimpleApp/js/nant.config | 0 .../Repository/SimpleApp/js/src/App.config | 0 .../net/1.1/Repository/SimpleApp/nant.build | 0 .../net/1.1/Repository/SimpleApp/nant.config | 0 .../1.1/Repository/SimpleModule/js/nant.build | 0 .../Repository/SimpleModule/js/nant.config | 0 .../1.1/Repository/SimpleModule/nant.build | 0 .../1.1/Repository/SimpleModule/nant.config | 0 examples/net/1.1/Repository/nant.build | 0 examples/net/1.1/Repository/nant.config | 0 .../1.1/Tutorials/ConsoleApp/cpp/nant.build | 0 .../1.1/Tutorials/ConsoleApp/cpp/nant.config | 0 .../Tutorials/ConsoleApp/cpp/src/App.config | 0 .../ConsoleApp/cpp/src/ConsoleApp.vcproj | 0 .../1.1/Tutorials/ConsoleApp/js/nant.build | 0 .../1.1/Tutorials/ConsoleApp/js/nant.config | 0 .../Tutorials/ConsoleApp/js/src/App.config | 0 .../net/1.1/Tutorials/ConsoleApp/nant.build | 0 .../net/1.1/Tutorials/ConsoleApp/nant.config | 0 examples/net/1.1/Tutorials/nant.build | 0 examples/net/1.1/Tutorials/nant.config | 0 examples/net/1.1/cpp-examples.sln | 0 examples/net/1.1/nant.build | 0 examples/net/1.1/nant.config | 0 .../SampleAppendersApp/cs/nant.build | 0 .../SampleAppendersApp/cs/nant.config | 0 .../SampleAppendersApp/cs/src/App.config | 0 .../cs/src/Appender/AsyncAppender.cs | 0 .../cs/src/Appender/FastDbAppender.cs | 0 .../cs/src/Appender/FireEventAppender.cs | 0 .../cs/src/Appender/MessageBoxAppender.cs | 0 .../Appender/MessageObjectExpanderAppender.cs | 0 .../cs/src/Appender/MsmqAppender.cs | 0 .../cs/src/Appender/PatternFileAppender.cs | 0 .../Appender/PatternLayoutAdoNetAppender.cs | 170 +- .../PatternLayoutAdoNetAppenderParameter.cs | 68 +- .../cs/src/SampleAppendersApp.csproj | 0 .../Appenders/SampleAppendersApp/nant.build | 0 .../Appenders/SampleAppendersApp/nant.config | 0 .../2.0/Appenders/WmiAppender/cs/nant.config | 46 +- .../WmiAppender/cs/src/AssemblyInfo.cs | 134 +- .../WmiAppender/cs/src/IWmiBoundEvent.cs | 106 +- .../WmiAppender/cs/src/WmiAppender.cs | 510 +++--- .../WmiAppender/cs/src/WmiAppender.csproj | 222 +-- .../WmiAppender/cs/src/WmiInstaller.cs | 64 +- .../Appenders/WmiAppender/cs/src/WmiLayout.cs | 200 +-- .../WmiAppender/cs/src/WmiLoggingEvent.cs | 94 +- .../net/2.0/Appenders/WmiAppender/nant.config | 42 +- examples/net/2.0/Appenders/nant.build | 0 examples/net/2.0/Appenders/nant.config | 0 .../cs/src/Layout/LevelConversionPattern.cs | 80 +- .../cs/src/Layout/LevelPatternLayout.cs | 100 +- .../NotLogging/vb/src/AssemblyInfo.vb | 0 .../NotLogging/vb/src/NotLogging.vb | 0 .../SharedModule/vb/src/AssemblyInfo.vb | 0 .../Repository/SharedModule/vb/src/Math.vb | 0 .../SimpleApp/vb/src/AssemblyInfo.vb | 0 .../Repository/SimpleApp/vb/src/EntryPoint.vb | 0 .../SimpleModule/vb/src/AssemblyInfo.vb | 0 .../Repository/SimpleModule/vb/src/Math.vb | 0 .../ConsoleApp/vb/src/AssemblyInfo.vb | 0 .../ConsoleApp/vb/src/LoggingExample.vb | 0 .../2.0/Tutorials/WebApp/cs/src/Global.asax | 0 .../2.0/Tutorials/WebApp/cs/src/WebForm1.aspx | 0 .../Tutorials/WebApp/vb/src/AssemblyInfo.vb | 0 .../WebApp/vb/src/AssemblyVersionInfo.vb | 0 .../2.0/Tutorials/WebApp/vb/src/Global.asax | 0 .../Tutorials/WebApp/vb/src/Global.asax.vb | 0 .../2.0/Tutorials/WebApp/vb/src/WebForm1.aspx | 0 .../Tutorials/WebApp/vb/src/WebForm1.aspx.vb | 0 examples/net/2.0/cs-examples.sln | 0 examples/net/2.0/vb-examples.sln | 0 .../ConsoleApp/vb/src/AssemblyInfo.vb | 0 .../Tutorials/ConsoleApp/vb/src/EntryPoint.vb | 0 .../ConsoleApp/vb/src/LoggingExample.vb | 0 examples/netcf/1.0/cs-examples.sln | 0 examples/netcf/1.0/vb-examples.sln | 0 extensions/net/1.0/cs-extensions.sln | 0 src/AssemblyVersionInfo.vb | 0 src/Core/ExceptionEvaluator.cs | 260 +-- src/Core/TimeEvaluator.cs | 294 ++-- .../Pattern/AspNetCachePatternConverter.cs | 152 +- .../Pattern/AspNetContextPatternConverter.cs | 134 +- src/Layout/Pattern/AspNetPatternConverter.cs | 128 +- .../Pattern/AspNetRequestPatternConverter.cs | 150 +- .../Pattern/AspNetSessionPatternConverter.cs | 152 +- .../StackTraceDetailPatternConverter.cs | 180 +- .../Pattern/StackTracePatternConverter.cs | 298 ++-- .../ConfigurationChangedEventArgs.cs | 58 +- src/Util/ConverterInfo.cs | 146 +- .../EnvironmentFolderPathPatternConverter.cs | 194 +-- src/Util/PropertyEntry.cs | 118 +- src/Util/SystemStringFormat.cs | 462 +++--- src/assembly/bin.xml | 10 +- src/log4net.vs2008.csproj | 1450 ++++++++--------- src/log4net.vs2008.sln | 50 +- tests/lib/prerequisites.txt | 74 +- tests/src/Appender/AdoNet/Log4NetCommand.cs | 246 +-- .../src/Appender/AdoNet/Log4NetConnection.cs | 180 +- tests/src/Appender/AdoNet/Log4NetParameter.cs | 164 +- .../AdoNet/Log4NetParameterCollection.cs | 96 +- .../src/Appender/AdoNet/Log4NetTransaction.cs | 82 +- tests/src/Appender/AdoNetAppenderTest.cs | 384 ++--- tests/src/Appender/TraceAppenderTest.cs | 178 +- tests/src/Core/EvaluatorTest.cs | 242 +-- tests/src/Core/FixingTest.cs | 270 +-- tests/src/Core/StringFormatTest.cs | 1376 ++++++++-------- tests/src/Filter/FilterTest.cs | 180 +- tests/src/Hierarchy/Hierarchy.cs | 152 +- .../LoggerRepository/ConfigurationMessages.cs | 146 +- .../Util/EnvironmentPatternConverterTest.cs | 182 +-- tests/src/Util/LogLogTest.cs | 164 +- tests/src/Util/PatternConverterTest.cs | 342 ++-- tests/src/Util/PatternStringTest.cs | 60 +- tests/src/log4net.Tests.vs2003.csproj | 512 +++--- tests/src/log4net.Tests.vs2008.csproj | 370 ++--- 168 files changed, 5847 insertions(+), 5847 deletions(-) mode change 100755 => 100644 doc/css/site.css mode change 100755 => 100644 doc/css/style.css mode change 100755 => 100644 examples/mono/1.0/Performance/NotLogging/cs/nant.build mode change 100755 => 100644 examples/mono/1.0/Performance/NotLogging/cs/nant.config mode change 100755 => 100644 examples/mono/1.0/Performance/NotLogging/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/mono/1.0/Performance/NotLogging/cs/src/NotLogging.cs mode change 100755 => 100644 examples/mono/1.0/Performance/NotLogging/nant.build mode change 100755 => 100644 examples/mono/1.0/Performance/NotLogging/nant.config mode change 100755 => 100644 examples/mono/1.0/Performance/nant.build mode change 100755 => 100644 examples/mono/1.0/Performance/nant.config mode change 100755 => 100644 examples/mono/1.0/Repository/SharedModule/cs/nant.build mode change 100755 => 100644 examples/mono/1.0/Repository/SharedModule/cs/nant.config mode change 100755 => 100644 examples/mono/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/mono/1.0/Repository/SharedModule/cs/src/Math.cs mode change 100755 => 100644 examples/mono/1.0/Repository/SharedModule/nant.build mode change 100755 => 100644 examples/mono/1.0/Repository/SharedModule/nant.config mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleApp/cs/nant.build mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleApp/cs/nant.config mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleApp/cs/src/App.config mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleApp/nant.build mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleApp/nant.config mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleModule/cs/nant.build mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleModule/cs/nant.config mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleModule/cs/src/Math.cs mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleModule/nant.build mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleModule/nant.config mode change 100755 => 100644 examples/mono/1.0/Repository/nant.build mode change 100755 => 100644 examples/mono/1.0/Repository/nant.config mode change 100755 => 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.build mode change 100755 => 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.config mode change 100755 => 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config mode change 100755 => 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs mode change 100755 => 100644 examples/mono/1.0/Tutorials/ConsoleApp/nant.build mode change 100755 => 100644 examples/mono/1.0/Tutorials/ConsoleApp/nant.config mode change 100755 => 100644 examples/mono/1.0/Tutorials/nant.build mode change 100755 => 100644 examples/mono/1.0/Tutorials/nant.config mode change 100755 => 100644 examples/mono/1.0/nant.build mode change 100755 => 100644 examples/mono/1.0/nant.config mode change 100755 => 100644 examples/mono/nant.build mode change 100755 => 100644 examples/mono/nant.config mode change 100755 => 100644 examples/nant.build mode change 100755 => 100644 examples/nant.config mode change 100755 => 100644 examples/net/1.1/Repository/SharedModule/js/nant.build mode change 100755 => 100644 examples/net/1.1/Repository/SharedModule/js/nant.config mode change 100755 => 100644 examples/net/1.1/Repository/SharedModule/nant.build mode change 100755 => 100644 examples/net/1.1/Repository/SharedModule/nant.config mode change 100755 => 100644 examples/net/1.1/Repository/SimpleApp/js/nant.build mode change 100755 => 100644 examples/net/1.1/Repository/SimpleApp/js/nant.config mode change 100755 => 100644 examples/net/1.1/Repository/SimpleApp/js/src/App.config mode change 100755 => 100644 examples/net/1.1/Repository/SimpleApp/nant.build mode change 100755 => 100644 examples/net/1.1/Repository/SimpleApp/nant.config mode change 100755 => 100644 examples/net/1.1/Repository/SimpleModule/js/nant.build mode change 100755 => 100644 examples/net/1.1/Repository/SimpleModule/js/nant.config mode change 100755 => 100644 examples/net/1.1/Repository/SimpleModule/nant.build mode change 100755 => 100644 examples/net/1.1/Repository/SimpleModule/nant.config mode change 100755 => 100644 examples/net/1.1/Repository/nant.build mode change 100755 => 100644 examples/net/1.1/Repository/nant.config mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/nant.build mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/nant.config mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/src/App.config mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/src/ConsoleApp.vcproj mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/js/nant.build mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/js/nant.config mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/js/src/App.config mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/nant.build mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/nant.config mode change 100755 => 100644 examples/net/1.1/Tutorials/nant.build mode change 100755 => 100644 examples/net/1.1/Tutorials/nant.config mode change 100755 => 100644 examples/net/1.1/cpp-examples.sln mode change 100755 => 100644 examples/net/1.1/nant.build mode change 100755 => 100644 examples/net/1.1/nant.config mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/App.config mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/AsyncAppender.cs mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/FastDbAppender.cs mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/FireEventAppender.cs mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MessageBoxAppender.cs mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MessageObjectExpanderAppender.cs mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MsmqAppender.cs mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternFileAppender.cs mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/SampleAppendersApp.csproj mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/nant.build mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/nant.config mode change 100755 => 100644 examples/net/2.0/Appenders/nant.build mode change 100755 => 100644 examples/net/2.0/Appenders/nant.config mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/vb/src/AssemblyInfo.vb mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vb mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/vb/src/AssemblyInfo.vb mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/vb/src/Math.vb mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/vb/src/AssemblyInfo.vb mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/vb/src/EntryPoint.vb mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/vb/src/AssemblyInfo.vb mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/vb/src/Math.vb mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/src/AssemblyInfo.vb mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/src/LoggingExample.vb mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyInfo.vb mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyVersionInfo.vb mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.vb mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.vb mode change 100755 => 100644 examples/net/2.0/cs-examples.sln mode change 100755 => 100644 examples/net/2.0/vb-examples.sln mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/AssemblyInfo.vb mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/EntryPoint.vb mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/LoggingExample.vb mode change 100755 => 100644 examples/netcf/1.0/cs-examples.sln mode change 100755 => 100644 examples/netcf/1.0/vb-examples.sln mode change 100755 => 100644 extensions/net/1.0/cs-extensions.sln mode change 100755 => 100644 src/AssemblyVersionInfo.vb diff --git a/build.cmd b/build.cmd index e82ef1ab..fff48943 100755 --- a/build.cmd +++ b/build.cmd @@ -1,111 +1,111 @@ -@ECHO OFF - -REM We are going to change the environment variables, so protect the current settings. -SETLOCAL ENABLEDELAYEDEXPANSION - -IF "%1"=="-?" GOTO CommandLineOptions - -REM Figure out the path to the log4net directory -CALL :ComputeBase %~f0 -SET LOG4NET_DIR=%RESULT% -ECHO LOG4NET_DIR is %LOG4NET_DIR% - -REM Get path to NAnt.exe - -REM Try and determine if NAnt is in the PATH -SET NANTEXE_PATH=nant.exe -"%NANTEXE_PATH%" -help >NUL: 2>NUL: -IF NOT ERRORLEVEL 1 goto FoundNAnt - -REM Try hard coded path for NAnt -SET NANTEXE_PATH=C:\Program Files\NAnt\nant-0.85\bin\nant.exe -"%NANTEXE_PATH%" -help >NUL: 2>NUL: -IF NOT ERRORLEVEL 1 goto FoundNAnt - -REM We have not found NAnt -ECHO. -ECHO NAnt does not appear to be installed. NAnt.exe failed to execute. -ECHO Please ensure NAnt is installed and can be found in the PATH. -GOTO EndError - - -:FoundNAnt -ECHO NANTEXE_PATH is %NANTEXE_PATH% - -REM Setup the build file -IF EXIST nant.build ( - SET BUILD_FILE=nant.build -) ELSE ( - SET BUILD_FILE=%LOG4NET_DIR%\log4net.build -) - -ECHO BUILD_FILE is %BUILD_FILE% - - -IF "%1"=="package" GOTO Package - -"%NANTEXE_PATH%" "-buildfile:%BUILD_FILE%" %1 %2 %3 %4 %5 %6 %7 %8 -GOTO EndOk - -:Package -IF "%2"=="" GOTO NoProjectVersion - -"%NANTEXE_PATH%" "-buildfile:%BUILD_FILE%" package "-D:package.version=%2" %3 %4 %5 %6 %7 %8 -GOTO EndOk - -:NoProjectVersion -ECHO. -ECHO SYNTAX ERROR: Missing Version String. -ECHO Please specify the version number of log4net that you want to package. -GOTO CommandLineOptions - -:CommandLineOptions -ECHO. -ECHO Use the following command line syntax: -ECHO. -ECHO build.cmd -? -ECHO build.cmd -projecthelp -ECHO build.cmd [nant target] -ECHO build.cmd package [version string] -ECHO. -ECHO To get a list of all NAnt build targets run build.cmd with the -projecthelp option. -ECHO If no NAnt target is specified then the default target is 'compile-all'. This will compile all configurations on all available frameworks. -ECHO When using the 'package' command the version label for the package must be specified. -ECHO. -ECHO Examples: -ECHO. -ECHO build.cmd compile-mono-1.0 -ECHO build.cmd compile-all -ECHO build.cmd package 1.3.0 -ECHO build.cmd package 2.1.0-alpha -ECHO. -GOTO EndError - - -REM ------------------------------------------ -REM Expand a string to a full path -REM ------------------------------------------ -:FullPath -SET RESULT=%~f1 -GOTO :EOF - -REM ------------------------------------------ -REM Compute the current directory -REM given a path to this batch script. -REM ------------------------------------------ -:ComputeBase -SET RESULT=%~dp1 -REM Remove the trailing \ -SET RESULT=%RESULT:~0,-1% -CALL :FullPath %RESULT% -GOTO :EOF - - -:EndOk -ENDLOCAL -EXIT /B 0 - -:EndError -ENDLOCAL -EXIT /B 1 - +@ECHO OFF + +REM We are going to change the environment variables, so protect the current settings. +SETLOCAL ENABLEDELAYEDEXPANSION + +IF "%1"=="-?" GOTO CommandLineOptions + +REM Figure out the path to the log4net directory +CALL :ComputeBase %~f0 +SET LOG4NET_DIR=%RESULT% +ECHO LOG4NET_DIR is %LOG4NET_DIR% + +REM Get path to NAnt.exe + +REM Try and determine if NAnt is in the PATH +SET NANTEXE_PATH=nant.exe +"%NANTEXE_PATH%" -help >NUL: 2>NUL: +IF NOT ERRORLEVEL 1 goto FoundNAnt + +REM Try hard coded path for NAnt +SET NANTEXE_PATH=C:\Program Files\NAnt\nant-0.85\bin\nant.exe +"%NANTEXE_PATH%" -help >NUL: 2>NUL: +IF NOT ERRORLEVEL 1 goto FoundNAnt + +REM We have not found NAnt +ECHO. +ECHO NAnt does not appear to be installed. NAnt.exe failed to execute. +ECHO Please ensure NAnt is installed and can be found in the PATH. +GOTO EndError + + +:FoundNAnt +ECHO NANTEXE_PATH is %NANTEXE_PATH% + +REM Setup the build file +IF EXIST nant.build ( + SET BUILD_FILE=nant.build +) ELSE ( + SET BUILD_FILE=%LOG4NET_DIR%\log4net.build +) + +ECHO BUILD_FILE is %BUILD_FILE% + + +IF "%1"=="package" GOTO Package + +"%NANTEXE_PATH%" "-buildfile:%BUILD_FILE%" %1 %2 %3 %4 %5 %6 %7 %8 +GOTO EndOk + +:Package +IF "%2"=="" GOTO NoProjectVersion + +"%NANTEXE_PATH%" "-buildfile:%BUILD_FILE%" package "-D:package.version=%2" %3 %4 %5 %6 %7 %8 +GOTO EndOk + +:NoProjectVersion +ECHO. +ECHO SYNTAX ERROR: Missing Version String. +ECHO Please specify the version number of log4net that you want to package. +GOTO CommandLineOptions + +:CommandLineOptions +ECHO. +ECHO Use the following command line syntax: +ECHO. +ECHO build.cmd -? +ECHO build.cmd -projecthelp +ECHO build.cmd [nant target] +ECHO build.cmd package [version string] +ECHO. +ECHO To get a list of all NAnt build targets run build.cmd with the -projecthelp option. +ECHO If no NAnt target is specified then the default target is 'compile-all'. This will compile all configurations on all available frameworks. +ECHO When using the 'package' command the version label for the package must be specified. +ECHO. +ECHO Examples: +ECHO. +ECHO build.cmd compile-mono-1.0 +ECHO build.cmd compile-all +ECHO build.cmd package 1.3.0 +ECHO build.cmd package 2.1.0-alpha +ECHO. +GOTO EndError + + +REM ------------------------------------------ +REM Expand a string to a full path +REM ------------------------------------------ +:FullPath +SET RESULT=%~f1 +GOTO :EOF + +REM ------------------------------------------ +REM Compute the current directory +REM given a path to this batch script. +REM ------------------------------------------ +:ComputeBase +SET RESULT=%~dp1 +REM Remove the trailing \ +SET RESULT=%RESULT:~0,-1% +CALL :FullPath %RESULT% +GOTO :EOF + + +:EndOk +ENDLOCAL +EXIT /B 0 + +:EndError +ENDLOCAL +EXIT /B 1 + diff --git a/doc/css/site.css b/doc/css/site.css old mode 100755 new mode 100644 diff --git a/doc/css/style.css b/doc/css/style.css old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Performance/NotLogging/cs/nant.build b/examples/mono/1.0/Performance/NotLogging/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Performance/NotLogging/cs/nant.config b/examples/mono/1.0/Performance/NotLogging/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Performance/NotLogging/cs/src/AssemblyInfo.cs b/examples/mono/1.0/Performance/NotLogging/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Performance/NotLogging/cs/src/NotLogging.cs b/examples/mono/1.0/Performance/NotLogging/cs/src/NotLogging.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Performance/NotLogging/nant.build b/examples/mono/1.0/Performance/NotLogging/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Performance/NotLogging/nant.config b/examples/mono/1.0/Performance/NotLogging/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Performance/nant.build b/examples/mono/1.0/Performance/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Performance/nant.config b/examples/mono/1.0/Performance/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SharedModule/cs/nant.build b/examples/mono/1.0/Repository/SharedModule/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SharedModule/cs/nant.config b/examples/mono/1.0/Repository/SharedModule/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs b/examples/mono/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SharedModule/cs/src/Math.cs b/examples/mono/1.0/Repository/SharedModule/cs/src/Math.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SharedModule/nant.build b/examples/mono/1.0/Repository/SharedModule/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SharedModule/nant.config b/examples/mono/1.0/Repository/SharedModule/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/nant.build b/examples/mono/1.0/Repository/SimpleApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/nant.config b/examples/mono/1.0/Repository/SimpleApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/src/App.config b/examples/mono/1.0/Repository/SimpleApp/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs b/examples/mono/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs b/examples/mono/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleApp/nant.build b/examples/mono/1.0/Repository/SimpleApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleApp/nant.config b/examples/mono/1.0/Repository/SimpleApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/nant.build b/examples/mono/1.0/Repository/SimpleModule/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/nant.config b/examples/mono/1.0/Repository/SimpleModule/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs b/examples/mono/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/src/Math.cs b/examples/mono/1.0/Repository/SimpleModule/cs/src/Math.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleModule/nant.build b/examples/mono/1.0/Repository/SimpleModule/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleModule/nant.config b/examples/mono/1.0/Repository/SimpleModule/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/nant.build b/examples/mono/1.0/Repository/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/nant.config b/examples/mono/1.0/Repository/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.build b/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.config b/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config b/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs b/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs b/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/nant.build b/examples/mono/1.0/Tutorials/ConsoleApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/nant.config b/examples/mono/1.0/Tutorials/ConsoleApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Tutorials/nant.build b/examples/mono/1.0/Tutorials/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Tutorials/nant.config b/examples/mono/1.0/Tutorials/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/nant.build b/examples/mono/1.0/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/nant.config b/examples/mono/1.0/nant.config old mode 100755 new mode 100644 diff --git a/examples/mono/nant.build b/examples/mono/nant.build old mode 100755 new mode 100644 diff --git a/examples/mono/nant.config b/examples/mono/nant.config old mode 100755 new mode 100644 diff --git a/examples/nant.build b/examples/nant.build old mode 100755 new mode 100644 diff --git a/examples/nant.config b/examples/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SharedModule/js/nant.build b/examples/net/1.1/Repository/SharedModule/js/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SharedModule/js/nant.config b/examples/net/1.1/Repository/SharedModule/js/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SharedModule/nant.build b/examples/net/1.1/Repository/SharedModule/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SharedModule/nant.config b/examples/net/1.1/Repository/SharedModule/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleApp/js/nant.build b/examples/net/1.1/Repository/SimpleApp/js/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleApp/js/nant.config b/examples/net/1.1/Repository/SimpleApp/js/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleApp/js/src/App.config b/examples/net/1.1/Repository/SimpleApp/js/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleApp/nant.build b/examples/net/1.1/Repository/SimpleApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleApp/nant.config b/examples/net/1.1/Repository/SimpleApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleModule/js/nant.build b/examples/net/1.1/Repository/SimpleModule/js/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleModule/js/nant.config b/examples/net/1.1/Repository/SimpleModule/js/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleModule/nant.build b/examples/net/1.1/Repository/SimpleModule/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleModule/nant.config b/examples/net/1.1/Repository/SimpleModule/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/nant.build b/examples/net/1.1/Repository/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/nant.config b/examples/net/1.1/Repository/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/cpp/nant.build b/examples/net/1.1/Tutorials/ConsoleApp/cpp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/cpp/nant.config b/examples/net/1.1/Tutorials/ConsoleApp/cpp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/App.config b/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/ConsoleApp.vcproj b/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/ConsoleApp.vcproj old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/js/nant.build b/examples/net/1.1/Tutorials/ConsoleApp/js/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/js/nant.config b/examples/net/1.1/Tutorials/ConsoleApp/js/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/js/src/App.config b/examples/net/1.1/Tutorials/ConsoleApp/js/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/nant.build b/examples/net/1.1/Tutorials/ConsoleApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/nant.config b/examples/net/1.1/Tutorials/ConsoleApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/nant.build b/examples/net/1.1/Tutorials/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/nant.config b/examples/net/1.1/Tutorials/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/1.1/cpp-examples.sln b/examples/net/1.1/cpp-examples.sln old mode 100755 new mode 100644 diff --git a/examples/net/1.1/nant.build b/examples/net/1.1/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/1.1/nant.config b/examples/net/1.1/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/nant.build b/examples/net/2.0/Appenders/SampleAppendersApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/nant.config b/examples/net/2.0/Appenders/SampleAppendersApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/App.config b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/AsyncAppender.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/AsyncAppender.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/FastDbAppender.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/FastDbAppender.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/FireEventAppender.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/FireEventAppender.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MessageBoxAppender.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MessageBoxAppender.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MessageObjectExpanderAppender.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MessageObjectExpanderAppender.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MsmqAppender.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MsmqAppender.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternFileAppender.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternFileAppender.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppender.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppender.cs index 1c28e626..08f074b1 100644 --- a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppender.cs +++ b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppender.cs @@ -1,86 +1,86 @@ -#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; -using log4net.Appender; -using log4net.Layout; -using log4net.Util; - -namespace SampleAppendersApp.Appender -{ - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// ]]> - /// - /// - public class PatternLayoutAdoNetAppender : AdoNetAppender - { - private readonly ArrayList m_converters = new ArrayList(); - - public void AddConverter(ConverterInfo converterInfo) - { - m_converters.Add(converterInfo); - } - - public void AddPatternLayoutParameter(PatternLayoutAdoNetAppenderParameter parameter) - { - PatternLayout patternLayout = new PatternLayout(parameter.ConversionPattern); - addConveters(patternLayout); - patternLayout.ActivateOptions(); - - parameter.Layout = new Layout2RawLayoutAdapter(patternLayout); - m_parameters.Add(parameter); - } - - private void addConveters(PatternLayout patternLayout) - { - foreach (ConverterInfo conveterInfo in m_converters) - { - patternLayout.AddConverter(conveterInfo); - } - } - } +#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; +using log4net.Appender; +using log4net.Layout; +using log4net.Util; + +namespace SampleAppendersApp.Appender +{ + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// ]]> + /// + /// + public class PatternLayoutAdoNetAppender : AdoNetAppender + { + private readonly ArrayList m_converters = new ArrayList(); + + public void AddConverter(ConverterInfo converterInfo) + { + m_converters.Add(converterInfo); + } + + public void AddPatternLayoutParameter(PatternLayoutAdoNetAppenderParameter parameter) + { + PatternLayout patternLayout = new PatternLayout(parameter.ConversionPattern); + addConveters(patternLayout); + patternLayout.ActivateOptions(); + + parameter.Layout = new Layout2RawLayoutAdapter(patternLayout); + m_parameters.Add(parameter); + } + + private void addConveters(PatternLayout patternLayout) + { + foreach (ConverterInfo conveterInfo in m_converters) + { + patternLayout.AddConverter(conveterInfo); + } + } + } } \ No newline at end of file diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppenderParameter.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppenderParameter.cs index d7e22886..6cf95ff8 100644 --- a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppenderParameter.cs +++ b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppenderParameter.cs @@ -1,34 +1,34 @@ -#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 log4net.Appender; - -namespace SampleAppendersApp.Appender -{ - public class PatternLayoutAdoNetAppenderParameter : AdoNetAppenderParameter - { - private string conversionPattern; - - public string ConversionPattern - { - get { return conversionPattern; } - set { conversionPattern = value; } - } - } -} +#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 log4net.Appender; + +namespace SampleAppendersApp.Appender +{ + public class PatternLayoutAdoNetAppenderParameter : AdoNetAppenderParameter + { + private string conversionPattern; + + public string ConversionPattern + { + get { return conversionPattern; } + set { conversionPattern = value; } + } + } +} diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/SampleAppendersApp.csproj b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/SampleAppendersApp.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/nant.build b/examples/net/2.0/Appenders/SampleAppendersApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/nant.config b/examples/net/2.0/Appenders/SampleAppendersApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/WmiAppender/cs/nant.config b/examples/net/2.0/Appenders/WmiAppender/cs/nant.config index b0553a7f..52613e83 100644 --- a/examples/net/2.0/Appenders/WmiAppender/cs/nant.config +++ b/examples/net/2.0/Appenders/WmiAppender/cs/nant.config @@ -1,23 +1,23 @@ - - - - - - - - + + + + + + + + diff --git a/examples/net/2.0/Appenders/WmiAppender/cs/src/AssemblyInfo.cs b/examples/net/2.0/Appenders/WmiAppender/cs/src/AssemblyInfo.cs index 9105dfe5..16c39de3 100644 --- a/examples/net/2.0/Appenders/WmiAppender/cs/src/AssemblyInfo.cs +++ b/examples/net/2.0/Appenders/WmiAppender/cs/src/AssemblyInfo.cs @@ -1,67 +1,67 @@ -#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.Reflection; -using System.Runtime.CompilerServices; - -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// -[assembly: AssemblyTitle("log4net.Appender.WmiAppender")] -[assembly: AssemblyDescription("The Apache Software Foundation log4net Logging Framework - WmiAppender")] - -#if DEBUG -[assembly: AssemblyConfiguration("Debug")] -#else -[assembly: AssemblyConfiguration("Retail")] -#endif - -[assembly: AssemblyProduct("log4net")] -[assembly: AssemblyCulture("")] - -// -// In order to sign your assembly you must specify a key to use. Refer to the -// Microsoft .NET Framework documentation for more information on assembly signing. -// -// Use the attributes below to control which key is used for signing. -// -// Notes: -// (*) If no key is specified, the assembly is not signed. -// (*) KeyName refers to a key that has been installed in the Crypto Service -// Provider (CSP) on your machine. KeyFile refers to a file which contains -// a key. -// (*) If the KeyFile and the KeyName values are both specified, the -// following processing occurs: -// (1) If the KeyName can be found in the CSP, that key is used. -// (2) If the KeyName does not exist and the KeyFile does exist, the key -// in the KeyFile is installed into the CSP and used. -// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. -// When specifying the KeyFile, the location of the KeyFile should be -// relative to the project output directory which is -// %Project Directory%\obj\. For example, if your KeyFile is -// located in the project directory, you would specify the AssemblyKeyFile -// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] -// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework -// documentation for more information on this. -// -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile("")] -[assembly: AssemblyKeyName("")] +#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.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("log4net.Appender.WmiAppender")] +[assembly: AssemblyDescription("The Apache Software Foundation log4net Logging Framework - WmiAppender")] + +#if DEBUG +[assembly: AssemblyConfiguration("Debug")] +#else +[assembly: AssemblyConfiguration("Retail")] +#endif + +[assembly: AssemblyProduct("log4net")] +[assembly: AssemblyCulture("")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/examples/net/2.0/Appenders/WmiAppender/cs/src/IWmiBoundEvent.cs b/examples/net/2.0/Appenders/WmiAppender/cs/src/IWmiBoundEvent.cs index 90445119..0ccd376e 100644 --- a/examples/net/2.0/Appenders/WmiAppender/cs/src/IWmiBoundEvent.cs +++ b/examples/net/2.0/Appenders/WmiAppender/cs/src/IWmiBoundEvent.cs @@ -1,53 +1,53 @@ -#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 System.Management.Instrumentation; - -namespace log4net.Appender -{ - /// - /// Subclass of for events that need to bind to a - /// - /// - /// - /// If the . is - /// a then the default behavior of the - /// is to call the method passing the . - /// This allows the event object to capture additional data from the - /// before it is fired. - /// - /// - public interface IWmiBoundEvent : IEvent - { - /// - /// This method is called before this instance is fired - /// - /// the containing the data - /// - /// - /// The calls this method passing the - /// object. Implementors should capture any required data from the - /// and store it in their instance prior to firing to WMI. - /// - /// - void Bind(LoggingEvent loggingEvent); - } -} +#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 System.Management.Instrumentation; + +namespace log4net.Appender +{ + /// + /// Subclass of for events that need to bind to a + /// + /// + /// + /// If the . is + /// a then the default behavior of the + /// is to call the method passing the . + /// This allows the event object to capture additional data from the + /// before it is fired. + /// + /// + public interface IWmiBoundEvent : IEvent + { + /// + /// This method is called before this instance is fired + /// + /// the containing the data + /// + /// + /// The calls this method passing the + /// object. Implementors should capture any required data from the + /// and store it in their instance prior to firing to WMI. + /// + /// + void Bind(LoggingEvent loggingEvent); + } +} diff --git a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.cs b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.cs index 5e563b38..a2398838 100644 --- a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.cs +++ b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.cs @@ -1,255 +1,255 @@ -#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 System.Threading; -using log4net.Appender; -using log4net.Core; -using System.Management.Instrumentation; - -// This is the WMI namespace for event objects in this assembly -[assembly: Instrumented("root/log4net")] - -namespace log4net.Appender -{ - /// - /// fires instrumented events for each - /// - /// - /// - /// This appender fires Windows Management Instrumentation (WMI) events for - /// each . - /// - /// - /// By default this appender fires objects, however - /// this can be overridden by specifying a custom or by setting - /// the . to an - /// instance. - /// - /// - /// This assembly must be registered with WMI. Use the InstallUtil tool - /// shipped with the .NET framework to install this assembly. This will register - /// the root/log4net WMI namespace. - /// - /// - public sealed class WmiAppender : IAppender, IOptionHandler - { - #region Private Instance Fields - - /// - /// The layout of this appender. - /// - /// - /// See for more information. - /// - private WmiLayout m_layout; - - /// - /// The name of this appender. - /// - /// - /// See for more information. - /// - private string m_name; - - /// - /// The level threshold of this appender. - /// - /// - /// - /// There is no level threshold filtering by default. - /// - /// - /// See for more information. - /// - /// - private Level m_threshold; - - /// - /// It is assumed and enforced that errorHandler is never null. - /// - /// - /// - /// It is assumed and enforced that errorHandler is never null. - /// - /// - /// See for more information. - /// - /// - private IErrorHandler m_errorHandler = new log4net.Util.OnlyOnceErrorHandler("WmiAppender"); - - #endregion - - #region Public Instance Properties - - /// - /// Gets or sets the name of this appender. - /// - /// The name of the appender. - /// - /// - /// The name uniquely identifies the appender. - /// - /// - public string Name - { - get { return m_name; } - set { m_name = value; } - } - - /// - /// Gets or sets the threshold of this appender. - /// - /// - /// The threshold of the appender. - /// - /// - /// - /// All log events with lower level than the threshold level are ignored - /// by the appender. - /// - /// - /// In configuration files this option is specified by setting the - /// value of the option to a level - /// string, such as "DEBUG", "INFO" and so on. - /// - /// - public Level Threshold - { - get { return m_threshold; } - set { m_threshold = value; } - } - - /// - /// Gets or sets the for this appender. - /// - /// The layout of the appender. - /// - /// - /// The to use to format the - /// as an . - /// - /// - public WmiLayout Layout - { - get { return m_layout; } - set { m_layout = value; } - } - - /// - /// Gets or sets the for this appender. - /// - /// The of the appender - /// - /// - /// The default value is a . - /// - /// - public IErrorHandler ErrorHandler - { - get { return m_errorHandler; } - set - { - if (value == null) - { - // We do not throw exception here since the cause is probably a - // bad config file. - log4net.Util.LogLog.Warn(GetType(), "WmiAppender: You have tried to set a null error-handler."); - } - else - { - m_errorHandler = value; - } - } - } - - #endregion Public Instance Properties - - /// - /// Activate this appender - /// - /// - /// - /// If a has not been specified then this - /// method will create a default instance. - /// - /// - public void ActivateOptions() - { - if (m_layout == null) - { - m_layout = new WmiLayout(); - } - } - - /// - /// Close this appender - /// - public void Close() - { - } - - /// - /// Process a - /// - /// the containing the data - /// - /// - /// Uses the to format the - /// as an . This is then fired. - /// - /// - public void DoAppend(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - try - { - if (IsAsSevereAsThreshold(loggingEvent.Level)) - { - IEvent instrumentationEvent = m_layout.Format(loggingEvent); - if (instrumentationEvent != null) - { - instrumentationEvent.Fire(); - } - } - } - catch(Exception ex) - { - ErrorHandler.Error("Failed in DoAppend", ex); - } - catch - { - // Catch handler for non System.Exception types - ErrorHandler.Error("Failed in DoAppend (unknown exception)"); - } - } - - /// - /// Checks if the message level is below this appender's threshold. - /// - private bool IsAsSevereAsThreshold(Level level) - { - return ((m_threshold == null) || level >= m_threshold); - } - } -} +#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 System.Threading; +using log4net.Appender; +using log4net.Core; +using System.Management.Instrumentation; + +// This is the WMI namespace for event objects in this assembly +[assembly: Instrumented("root/log4net")] + +namespace log4net.Appender +{ + /// + /// fires instrumented events for each + /// + /// + /// + /// This appender fires Windows Management Instrumentation (WMI) events for + /// each . + /// + /// + /// By default this appender fires objects, however + /// this can be overridden by specifying a custom or by setting + /// the . to an + /// instance. + /// + /// + /// This assembly must be registered with WMI. Use the InstallUtil tool + /// shipped with the .NET framework to install this assembly. This will register + /// the root/log4net WMI namespace. + /// + /// + public sealed class WmiAppender : IAppender, IOptionHandler + { + #region Private Instance Fields + + /// + /// The layout of this appender. + /// + /// + /// See for more information. + /// + private WmiLayout m_layout; + + /// + /// The name of this appender. + /// + /// + /// See for more information. + /// + private string m_name; + + /// + /// The level threshold of this appender. + /// + /// + /// + /// There is no level threshold filtering by default. + /// + /// + /// See for more information. + /// + /// + private Level m_threshold; + + /// + /// It is assumed and enforced that errorHandler is never null. + /// + /// + /// + /// It is assumed and enforced that errorHandler is never null. + /// + /// + /// See for more information. + /// + /// + private IErrorHandler m_errorHandler = new log4net.Util.OnlyOnceErrorHandler("WmiAppender"); + + #endregion + + #region Public Instance Properties + + /// + /// Gets or sets the name of this appender. + /// + /// The name of the appender. + /// + /// + /// The name uniquely identifies the appender. + /// + /// + public string Name + { + get { return m_name; } + set { m_name = value; } + } + + /// + /// Gets or sets the threshold of this appender. + /// + /// + /// The threshold of the appender. + /// + /// + /// + /// All log events with lower level than the threshold level are ignored + /// by the appender. + /// + /// + /// In configuration files this option is specified by setting the + /// value of the option to a level + /// string, such as "DEBUG", "INFO" and so on. + /// + /// + public Level Threshold + { + get { return m_threshold; } + set { m_threshold = value; } + } + + /// + /// Gets or sets the for this appender. + /// + /// The layout of the appender. + /// + /// + /// The to use to format the + /// as an . + /// + /// + public WmiLayout Layout + { + get { return m_layout; } + set { m_layout = value; } + } + + /// + /// Gets or sets the for this appender. + /// + /// The of the appender + /// + /// + /// The default value is a . + /// + /// + public IErrorHandler ErrorHandler + { + get { return m_errorHandler; } + set + { + if (value == null) + { + // We do not throw exception here since the cause is probably a + // bad config file. + log4net.Util.LogLog.Warn(GetType(), "WmiAppender: You have tried to set a null error-handler."); + } + else + { + m_errorHandler = value; + } + } + } + + #endregion Public Instance Properties + + /// + /// Activate this appender + /// + /// + /// + /// If a has not been specified then this + /// method will create a default instance. + /// + /// + public void ActivateOptions() + { + if (m_layout == null) + { + m_layout = new WmiLayout(); + } + } + + /// + /// Close this appender + /// + public void Close() + { + } + + /// + /// Process a + /// + /// the containing the data + /// + /// + /// Uses the to format the + /// as an . This is then fired. + /// + /// + public void DoAppend(LoggingEvent loggingEvent) + { + if (loggingEvent == null) + { + throw new ArgumentNullException("loggingEvent"); + } + + try + { + if (IsAsSevereAsThreshold(loggingEvent.Level)) + { + IEvent instrumentationEvent = m_layout.Format(loggingEvent); + if (instrumentationEvent != null) + { + instrumentationEvent.Fire(); + } + } + } + catch(Exception ex) + { + ErrorHandler.Error("Failed in DoAppend", ex); + } + catch + { + // Catch handler for non System.Exception types + ErrorHandler.Error("Failed in DoAppend (unknown exception)"); + } + } + + /// + /// Checks if the message level is below this appender's threshold. + /// + private bool IsAsSevereAsThreshold(Level level) + { + return ((m_threshold == null) || level >= m_threshold); + } + } +} diff --git a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.csproj b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.csproj index 036cd2b1..644ea9c5 100644 --- a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.csproj +++ b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.csproj @@ -1,112 +1,112 @@ - - - Local - 8.0.50727 - 2.0 - {BE56F892-37BA-489C-A91D-F2761FDB96EF} - Debug - AnyCPU - - - - - log4net.Appender.WmiAppender - - - JScript - Grid - IE50 - false - Library - log4net.Appender.WmiAppender - - - - - - - - - ..\bin\Debug\ - false - 285212672 - false - - - DEBUG;TRACE - - - true - 4096 - false - false - false - false - 4 - full - prompt - - - ..\bin\Release\ - false - 285212672 - false - - - TRACE - - - false - 4096 - true - false - false - false - 4 - none - prompt - - - - False - ..\..\..\..\..\..\..\bin\net\2.0\debug\log4net.dll - - - System - - - System.Configuration.Install - - - System.Management - - - - - AssemblyVersionInfo.cs - - - - Code - - - Code - - - Component - - - Code - - - Code - - - - - - - - - + + + Local + 8.0.50727 + 2.0 + {BE56F892-37BA-489C-A91D-F2761FDB96EF} + Debug + AnyCPU + + + + + log4net.Appender.WmiAppender + + + JScript + Grid + IE50 + false + Library + log4net.Appender.WmiAppender + + + + + + + + + ..\bin\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + + + true + 4096 + false + false + false + false + 4 + full + prompt + + + ..\bin\Release\ + false + 285212672 + false + + + TRACE + + + false + 4096 + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\..\..\..\..\bin\net\2.0\debug\log4net.dll + + + System + + + System.Configuration.Install + + + System.Management + + + + + AssemblyVersionInfo.cs + + + + Code + + + Code + + + Component + + + Code + + + Code + + + + + + + + + \ No newline at end of file diff --git a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiInstaller.cs b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiInstaller.cs index 347ec16b..03bb8653 100644 --- a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiInstaller.cs +++ b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiInstaller.cs @@ -1,32 +1,32 @@ -#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 System.Management.Instrumentation; - -namespace log4net.Appender -{ - /// - /// Register this assembly with WMI - /// - [System.ComponentModel.RunInstaller(true)] - public class WmiInstaller : DefaultManagementProjectInstaller - { - } -} +#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 System.Management.Instrumentation; + +namespace log4net.Appender +{ + /// + /// Register this assembly with WMI + /// + [System.ComponentModel.RunInstaller(true)] + public class WmiInstaller : DefaultManagementProjectInstaller + { + } +} diff --git a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLayout.cs b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLayout.cs index 68e0bee5..eaf51d8c 100644 --- a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLayout.cs +++ b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLayout.cs @@ -1,100 +1,100 @@ -#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 System.Management.Instrumentation; - -namespace log4net.Appender -{ - public class WmiLayout - { - /// - /// Formats a for instrumentation - /// - /// the containing the data - /// an instrumentation event that can be fired - /// - /// - /// If the of the - /// is an then - /// that instance is returned. If the instance also implements the - /// interface then the - /// method will be called on the instance with the - /// parameter. - /// - /// - /// If the of the - /// is not an - /// then the method will be called - /// to create an appropriate instrumentation event object. - /// - /// - public virtual IEvent Format(LoggingEvent loggingEvent) - { - // See if the caller gave us an Instrumentation Event - IEvent instrumentationEvent = loggingEvent.MessageObject as IEvent; - if (instrumentationEvent != null) - { - // See if the caller gave us a Bound Instrumentation Event - IWmiBoundEvent boundEvent = instrumentationEvent as IWmiBoundEvent; - if (boundEvent != null) - { - // Attach the logging event to the bound instrumentation event - boundEvent.Bind(loggingEvent); - } - - return instrumentationEvent; - } - - // We must create our own IEvent - return CreateEvent(loggingEvent); - } - - /// - /// Create the instance that should be fired - /// - /// the containing the data - /// an instrumentation event that can be fired - /// - /// - /// The default implementation of this method creates a - /// instance using the data from the . - /// - /// - /// Subclasses should override this method to return their own custom - /// instrumentation event object. - /// - /// - protected virtual IEvent CreateEvent(LoggingEvent loggingEvent) - { - WmiLoggingEvent wmiEvent = new WmiLoggingEvent(); - - wmiEvent.TimeStamp = loggingEvent.TimeStamp; - wmiEvent.LoggerName = loggingEvent.LoggerName; - wmiEvent.Level = loggingEvent.Level.DisplayName; - wmiEvent.Message = loggingEvent.RenderedMessage; - wmiEvent.ThreadName = loggingEvent.ThreadName; - wmiEvent.ExceptionString = loggingEvent.GetExceptionString(); - wmiEvent.Domain = loggingEvent.Domain; - - return wmiEvent; - } - } -} +#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 System.Management.Instrumentation; + +namespace log4net.Appender +{ + public class WmiLayout + { + /// + /// Formats a for instrumentation + /// + /// the containing the data + /// an instrumentation event that can be fired + /// + /// + /// If the of the + /// is an then + /// that instance is returned. If the instance also implements the + /// interface then the + /// method will be called on the instance with the + /// parameter. + /// + /// + /// If the of the + /// is not an + /// then the method will be called + /// to create an appropriate instrumentation event object. + /// + /// + public virtual IEvent Format(LoggingEvent loggingEvent) + { + // See if the caller gave us an Instrumentation Event + IEvent instrumentationEvent = loggingEvent.MessageObject as IEvent; + if (instrumentationEvent != null) + { + // See if the caller gave us a Bound Instrumentation Event + IWmiBoundEvent boundEvent = instrumentationEvent as IWmiBoundEvent; + if (boundEvent != null) + { + // Attach the logging event to the bound instrumentation event + boundEvent.Bind(loggingEvent); + } + + return instrumentationEvent; + } + + // We must create our own IEvent + return CreateEvent(loggingEvent); + } + + /// + /// Create the instance that should be fired + /// + /// the containing the data + /// an instrumentation event that can be fired + /// + /// + /// The default implementation of this method creates a + /// instance using the data from the . + /// + /// + /// Subclasses should override this method to return their own custom + /// instrumentation event object. + /// + /// + protected virtual IEvent CreateEvent(LoggingEvent loggingEvent) + { + WmiLoggingEvent wmiEvent = new WmiLoggingEvent(); + + wmiEvent.TimeStamp = loggingEvent.TimeStamp; + wmiEvent.LoggerName = loggingEvent.LoggerName; + wmiEvent.Level = loggingEvent.Level.DisplayName; + wmiEvent.Message = loggingEvent.RenderedMessage; + wmiEvent.ThreadName = loggingEvent.ThreadName; + wmiEvent.ExceptionString = loggingEvent.GetExceptionString(); + wmiEvent.Domain = loggingEvent.Domain; + + return wmiEvent; + } + } +} diff --git a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLoggingEvent.cs b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLoggingEvent.cs index 0d4e69ae..72efdc80 100644 --- a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLoggingEvent.cs +++ b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLoggingEvent.cs @@ -1,47 +1,47 @@ -#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 System.Management.Instrumentation; - -namespace log4net.Appender -{ - /// - /// The default instrumented event raised by the - /// - /// - /// - /// This is the default event fired by the . - /// To fire a custom event set the to a - /// subclass of that overrides the - /// method. - /// - /// - public class WmiLoggingEvent : BaseEvent - { - public DateTime TimeStamp; - public string LoggerName; - public string Level; - public string Message; - public string ThreadName; - public string ExceptionString; - public string Domain; - } -} +#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 System.Management.Instrumentation; + +namespace log4net.Appender +{ + /// + /// The default instrumented event raised by the + /// + /// + /// + /// This is the default event fired by the . + /// To fire a custom event set the to a + /// subclass of that overrides the + /// method. + /// + /// + public class WmiLoggingEvent : BaseEvent + { + public DateTime TimeStamp; + public string LoggerName; + public string Level; + public string Message; + public string ThreadName; + public string ExceptionString; + public string Domain; + } +} diff --git a/examples/net/2.0/Appenders/WmiAppender/nant.config b/examples/net/2.0/Appenders/WmiAppender/nant.config index d7014bbc..ba0a7243 100644 --- a/examples/net/2.0/Appenders/WmiAppender/nant.config +++ b/examples/net/2.0/Appenders/WmiAppender/nant.config @@ -1,21 +1,21 @@ - - - - - - + + + + + + diff --git a/examples/net/2.0/Appenders/nant.build b/examples/net/2.0/Appenders/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/nant.config b/examples/net/2.0/Appenders/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelConversionPattern.cs b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelConversionPattern.cs index 65d621fa..d4d729de 100644 --- a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelConversionPattern.cs +++ b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelConversionPattern.cs @@ -1,41 +1,41 @@ -#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 log4net.Core; - -namespace SampleLayoutsApp.Layout -{ - public class LevelConversionPattern - { - private Level level; - private string conversionPattern; - - public Level Level - { - get { return level; } - set { level = value; } - } - - public string ConversionPattern - { - get { return conversionPattern; } - set { conversionPattern = value; } - } - } +#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 log4net.Core; + +namespace SampleLayoutsApp.Layout +{ + public class LevelConversionPattern + { + private Level level; + private string conversionPattern; + + public Level Level + { + get { return level; } + set { level = value; } + } + + public string ConversionPattern + { + get { return conversionPattern; } + set { conversionPattern = value; } + } + } } \ No newline at end of file diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelPatternLayout.cs b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelPatternLayout.cs index 0c1317dd..2176b915 100644 --- a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelPatternLayout.cs +++ b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelPatternLayout.cs @@ -1,50 +1,50 @@ -#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; -using System.IO; -using log4net.Core; -using log4net.Layout; - -namespace SampleLayoutsApp.Layout -{ - public class LevelPatternLayout : PatternLayout - { - private readonly Hashtable m_levelToPatternLayout = new Hashtable(); - - public override void Format(TextWriter writer, LoggingEvent loggingEvent) - { - PatternLayout patternLayout = m_levelToPatternLayout[loggingEvent.Level] as PatternLayout; - - if (patternLayout == null) - { - base.Format(writer, loggingEvent); - } - else - { - patternLayout.Format(writer, loggingEvent); - } - } - - public void AddLevelConversionPattern(LevelConversionPattern levelLayout) - { - m_levelToPatternLayout[levelLayout.Level] = new PatternLayout(levelLayout.ConversionPattern); - } - } -} +#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; +using System.IO; +using log4net.Core; +using log4net.Layout; + +namespace SampleLayoutsApp.Layout +{ + public class LevelPatternLayout : PatternLayout + { + private readonly Hashtable m_levelToPatternLayout = new Hashtable(); + + public override void Format(TextWriter writer, LoggingEvent loggingEvent) + { + PatternLayout patternLayout = m_levelToPatternLayout[loggingEvent.Level] as PatternLayout; + + if (patternLayout == null) + { + base.Format(writer, loggingEvent); + } + else + { + patternLayout.Format(writer, loggingEvent); + } + } + + public void AddLevelConversionPattern(LevelConversionPattern levelLayout) + { + m_levelToPatternLayout[levelLayout.Level] = new PatternLayout(levelLayout.ConversionPattern); + } + } +} diff --git a/examples/net/2.0/Performance/NotLogging/vb/src/AssemblyInfo.vb b/examples/net/2.0/Performance/NotLogging/vb/src/AssemblyInfo.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vb b/examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/vb/src/AssemblyInfo.vb b/examples/net/2.0/Repository/SharedModule/vb/src/AssemblyInfo.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/vb/src/Math.vb b/examples/net/2.0/Repository/SharedModule/vb/src/Math.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/vb/src/AssemblyInfo.vb b/examples/net/2.0/Repository/SimpleApp/vb/src/AssemblyInfo.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/vb/src/EntryPoint.vb b/examples/net/2.0/Repository/SimpleApp/vb/src/EntryPoint.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/vb/src/AssemblyInfo.vb b/examples/net/2.0/Repository/SimpleModule/vb/src/AssemblyInfo.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/vb/src/Math.vb b/examples/net/2.0/Repository/SimpleModule/vb/src/Math.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/vb/src/AssemblyInfo.vb b/examples/net/2.0/Tutorials/ConsoleApp/vb/src/AssemblyInfo.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/vb/src/LoggingExample.vb b/examples/net/2.0/Tutorials/ConsoleApp/vb/src/LoggingExample.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax b/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx b/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyInfo.vb b/examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyInfo.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyVersionInfo.vb b/examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyVersionInfo.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax b/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.vb b/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx b/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.vb b/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.vb old mode 100755 new mode 100644 diff --git a/examples/net/2.0/cs-examples.sln b/examples/net/2.0/cs-examples.sln old mode 100755 new mode 100644 diff --git a/examples/net/2.0/vb-examples.sln b/examples/net/2.0/vb-examples.sln old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/AssemblyInfo.vb b/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/AssemblyInfo.vb old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/EntryPoint.vb b/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/EntryPoint.vb old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/LoggingExample.vb b/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/LoggingExample.vb old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/cs-examples.sln b/examples/netcf/1.0/cs-examples.sln old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/vb-examples.sln b/examples/netcf/1.0/vb-examples.sln old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/cs-extensions.sln b/extensions/net/1.0/cs-extensions.sln old mode 100755 new mode 100644 diff --git a/src/AssemblyVersionInfo.vb b/src/AssemblyVersionInfo.vb old mode 100755 new mode 100644 diff --git a/src/Core/ExceptionEvaluator.cs b/src/Core/ExceptionEvaluator.cs index 106e453d..d06365ed 100644 --- a/src/Core/ExceptionEvaluator.cs +++ b/src/Core/ExceptionEvaluator.cs @@ -1,130 +1,130 @@ -#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; - -namespace log4net.Core -{ - /// - /// An evaluator that triggers on an Exception type - /// - /// - /// - /// This evaluator will trigger if the type of the Exception - /// passed to - /// is equal to a Type in . /// - /// - /// - /// Drew Schaeffer - public class ExceptionEvaluator : ITriggeringEventEvaluator - { - /// - /// The type that causes the trigger to fire. - /// - private Type m_type; - - /// - /// Causes subclasses of to cause the trigger to fire. - /// - private bool m_triggerOnSubclass; - - /// - /// Default ctor to allow dynamic creation through a configurator. - /// - public ExceptionEvaluator() - { - // empty - } - - /// - /// Constructs an evaluator and initializes to trigger on - /// - /// the type that triggers this evaluator. - /// If true, this evaluator will trigger on subclasses of . - public ExceptionEvaluator(Type exType, bool triggerOnSubClass) - { - if (exType == null) - { - throw new ArgumentNullException("exType"); - } - - m_type = exType; - m_triggerOnSubclass = triggerOnSubClass; - } - - /// - /// The type that triggers this evaluator. - /// - public Type ExceptionType - { - get { return m_type; } - set { m_type = value; } - } - - /// - /// If true, this evaluator will trigger on subclasses of . - /// - public bool TriggerOnSubclass - { - get { return m_triggerOnSubclass; } - set { m_triggerOnSubclass = value; } - } - - #region ITriggeringEventEvaluator Members - - /// - /// Is this the triggering event? - /// - /// The event to check - /// This method returns true, if the logging event Exception - /// Type is . - /// Otherwise it returns false - /// - /// - /// This evaluator will trigger if the Exception Type of the event - /// passed to - /// is . - /// - /// - public bool IsTriggeringEvent(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - if (m_triggerOnSubclass && loggingEvent.ExceptionObject != null) - { - // check if loggingEvent.ExceptionObject is of type ExceptionType or subclass of ExceptionType - Type exceptionObjectType = loggingEvent.ExceptionObject.GetType(); - return exceptionObjectType == m_type || exceptionObjectType.IsSubclassOf(m_type); - } - else if (!m_triggerOnSubclass && loggingEvent.ExceptionObject != null) - { // check if loggingEvent.ExceptionObject is of type ExceptionType - return loggingEvent.ExceptionObject.GetType() == m_type; - } - else - { // loggingEvent.ExceptionObject is null - return false; - } - } - - #endregion - } -} +#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; + +namespace log4net.Core +{ + /// + /// An evaluator that triggers on an Exception type + /// + /// + /// + /// This evaluator will trigger if the type of the Exception + /// passed to + /// is equal to a Type in . /// + /// + /// + /// Drew Schaeffer + public class ExceptionEvaluator : ITriggeringEventEvaluator + { + /// + /// The type that causes the trigger to fire. + /// + private Type m_type; + + /// + /// Causes subclasses of to cause the trigger to fire. + /// + private bool m_triggerOnSubclass; + + /// + /// Default ctor to allow dynamic creation through a configurator. + /// + public ExceptionEvaluator() + { + // empty + } + + /// + /// Constructs an evaluator and initializes to trigger on + /// + /// the type that triggers this evaluator. + /// If true, this evaluator will trigger on subclasses of . + public ExceptionEvaluator(Type exType, bool triggerOnSubClass) + { + if (exType == null) + { + throw new ArgumentNullException("exType"); + } + + m_type = exType; + m_triggerOnSubclass = triggerOnSubClass; + } + + /// + /// The type that triggers this evaluator. + /// + public Type ExceptionType + { + get { return m_type; } + set { m_type = value; } + } + + /// + /// If true, this evaluator will trigger on subclasses of . + /// + public bool TriggerOnSubclass + { + get { return m_triggerOnSubclass; } + set { m_triggerOnSubclass = value; } + } + + #region ITriggeringEventEvaluator Members + + /// + /// Is this the triggering event? + /// + /// The event to check + /// This method returns true, if the logging event Exception + /// Type is . + /// Otherwise it returns false + /// + /// + /// This evaluator will trigger if the Exception Type of the event + /// passed to + /// is . + /// + /// + public bool IsTriggeringEvent(LoggingEvent loggingEvent) + { + if (loggingEvent == null) + { + throw new ArgumentNullException("loggingEvent"); + } + + if (m_triggerOnSubclass && loggingEvent.ExceptionObject != null) + { + // check if loggingEvent.ExceptionObject is of type ExceptionType or subclass of ExceptionType + Type exceptionObjectType = loggingEvent.ExceptionObject.GetType(); + return exceptionObjectType == m_type || exceptionObjectType.IsSubclassOf(m_type); + } + else if (!m_triggerOnSubclass && loggingEvent.ExceptionObject != null) + { // check if loggingEvent.ExceptionObject is of type ExceptionType + return loggingEvent.ExceptionObject.GetType() == m_type; + } + else + { // loggingEvent.ExceptionObject is null + return false; + } + } + + #endregion + } +} diff --git a/src/Core/TimeEvaluator.cs b/src/Core/TimeEvaluator.cs index bfa60dd8..9c1e0012 100644 --- a/src/Core/TimeEvaluator.cs +++ b/src/Core/TimeEvaluator.cs @@ -1,147 +1,147 @@ -#region Copyright & License -// -// Copyright 2001-2005 The Apache Software Foundation -// -// Licensed 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; - -namespace log4net.Core -{ - /// - /// An evaluator that triggers after specified number of seconds. - /// - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - /// Robert Sevcik - public class TimeEvaluator : ITriggeringEventEvaluator - { - /// - /// The time threshold for triggering in seconds. Zero means it won't trigger at all. - /// - private int m_interval; - - /// - /// The time of last check. This gets updated when the object is created and when the evaluator triggers. - /// - private DateTime m_lasttime; - - /// - /// The default time threshold for triggering in seconds. Zero means it won't trigger at all. - /// - const int DEFAULT_INTERVAL = 0; - - /// - /// Create a new evaluator using the time threshold in seconds. - /// - /// - /// - /// Create a new evaluator using the time threshold in seconds. - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - public TimeEvaluator() - : this(DEFAULT_INTERVAL) - { - } - - /// - /// Create a new evaluator using the specified time threshold in seconds. - /// - /// - /// The time threshold in seconds to trigger after. - /// Zero means it won't trigger at all. - /// - /// - /// - /// Create a new evaluator using the specified time threshold in seconds. - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - public TimeEvaluator(int interval) - { - m_interval = interval; - m_lasttime = DateTime.Now; - } - - /// - /// The time threshold in seconds to trigger after - /// - /// - /// The time threshold in seconds to trigger after. - /// Zero means it won't trigger at all. - /// - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - public int Interval - { - get { return m_interval; } - set { m_interval = value; } - } - - /// - /// Is this the triggering event? - /// - /// The event to check - /// This method returns true, if the specified time period - /// has passed since last check.. - /// Otherwise it returns false - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - public bool IsTriggeringEvent(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - // disable the evaluator if threshold is zero - if (m_interval == 0) return false; - - lock (this) // avoid triggering multiple times - { - TimeSpan passed = DateTime.Now.Subtract(m_lasttime); - - if (passed.TotalSeconds > m_interval) - { - m_lasttime = DateTime.Now; - return true; - } - else - { - return false; - } - } - } - } -} +#region Copyright & License +// +// Copyright 2001-2005 The Apache Software Foundation +// +// Licensed 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; + +namespace log4net.Core +{ + /// + /// An evaluator that triggers after specified number of seconds. + /// + /// + /// + /// This evaluator will trigger if the specified time period + /// has passed since last check. + /// + /// + /// Robert Sevcik + public class TimeEvaluator : ITriggeringEventEvaluator + { + /// + /// The time threshold for triggering in seconds. Zero means it won't trigger at all. + /// + private int m_interval; + + /// + /// The time of last check. This gets updated when the object is created and when the evaluator triggers. + /// + private DateTime m_lasttime; + + /// + /// The default time threshold for triggering in seconds. Zero means it won't trigger at all. + /// + const int DEFAULT_INTERVAL = 0; + + /// + /// Create a new evaluator using the time threshold in seconds. + /// + /// + /// + /// Create a new evaluator using the time threshold in seconds. + /// + /// + /// This evaluator will trigger if the specified time period + /// has passed since last check. + /// + /// + public TimeEvaluator() + : this(DEFAULT_INTERVAL) + { + } + + /// + /// Create a new evaluator using the specified time threshold in seconds. + /// + /// + /// The time threshold in seconds to trigger after. + /// Zero means it won't trigger at all. + /// + /// + /// + /// Create a new evaluator using the specified time threshold in seconds. + /// + /// + /// This evaluator will trigger if the specified time period + /// has passed since last check. + /// + /// + public TimeEvaluator(int interval) + { + m_interval = interval; + m_lasttime = DateTime.Now; + } + + /// + /// The time threshold in seconds to trigger after + /// + /// + /// The time threshold in seconds to trigger after. + /// Zero means it won't trigger at all. + /// + /// + /// + /// This evaluator will trigger if the specified time period + /// has passed since last check. + /// + /// + public int Interval + { + get { return m_interval; } + set { m_interval = value; } + } + + /// + /// Is this the triggering event? + /// + /// The event to check + /// This method returns true, if the specified time period + /// has passed since last check.. + /// Otherwise it returns false + /// + /// + /// This evaluator will trigger if the specified time period + /// has passed since last check. + /// + /// + public bool IsTriggeringEvent(LoggingEvent loggingEvent) + { + if (loggingEvent == null) + { + throw new ArgumentNullException("loggingEvent"); + } + + // disable the evaluator if threshold is zero + if (m_interval == 0) return false; + + lock (this) // avoid triggering multiple times + { + TimeSpan passed = DateTime.Now.Subtract(m_lasttime); + + if (passed.TotalSeconds > m_interval) + { + m_lasttime = DateTime.Now; + return true; + } + else + { + return false; + } + } + } + } +} diff --git a/src/Layout/Pattern/AspNetCachePatternConverter.cs b/src/Layout/Pattern/AspNetCachePatternConverter.cs index a8905fc8..78564677 100644 --- a/src/Layout/Pattern/AspNetCachePatternConverter.cs +++ b/src/Layout/Pattern/AspNetCachePatternConverter.cs @@ -1,77 +1,77 @@ -#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 - -// .NET Compact Framework 1.0 has no support for ASP.NET -// SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI - -using System.IO; -using System.Web; -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter for items in the ASP.Net Cache. - /// - /// - /// - /// Outputs an item from the . - /// - /// - /// Ron Grabowski - internal sealed class AspNetCachePatternConverter : AspNetPatternLayoutConverter - { - /// - /// Write the ASP.Net Cache item to the output - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. If no property has been set, all key value pairs from the Cache will - /// be written to the output. - /// - /// - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) - { - if (HttpRuntime.Cache != null) - { - if (Option != null) - { - WriteObject(writer, loggingEvent.Repository, HttpRuntime.Cache[Option]); - } - else - { - WriteObject(writer, loggingEvent.Repository, HttpRuntime.Cache.GetEnumerator()); - } - } - else - { - writer.Write(SystemInfo.NotAvailableText); - } - } - } -} - +#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 + +// .NET Compact Framework 1.0 has no support for ASP.NET +// SSCLI 1.0 has no support for ASP.NET +#if !NETCF && !SSCLI + +using System.IO; +using System.Web; +using log4net.Core; +using log4net.Util; + +namespace log4net.Layout.Pattern +{ + /// + /// Converter for items in the ASP.Net Cache. + /// + /// + /// + /// Outputs an item from the . + /// + /// + /// Ron Grabowski + internal sealed class AspNetCachePatternConverter : AspNetPatternLayoutConverter + { + /// + /// Write the ASP.Net Cache item to the output + /// + /// that will receive the formatted result. + /// The on which the pattern converter should be executed. + /// The under which the ASP.Net request is running. + /// + /// + /// Writes out the value of a named property. The property name + /// should be set in the + /// property. If no property has been set, all key value pairs from the Cache will + /// be written to the output. + /// + /// + protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) + { + if (HttpRuntime.Cache != null) + { + if (Option != null) + { + WriteObject(writer, loggingEvent.Repository, HttpRuntime.Cache[Option]); + } + else + { + WriteObject(writer, loggingEvent.Repository, HttpRuntime.Cache.GetEnumerator()); + } + } + else + { + writer.Write(SystemInfo.NotAvailableText); + } + } + } +} + #endif \ No newline at end of file diff --git a/src/Layout/Pattern/AspNetContextPatternConverter.cs b/src/Layout/Pattern/AspNetContextPatternConverter.cs index 0075f357..b0d8ccac 100644 --- a/src/Layout/Pattern/AspNetContextPatternConverter.cs +++ b/src/Layout/Pattern/AspNetContextPatternConverter.cs @@ -1,68 +1,68 @@ -#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 - -// .NET Compact Framework 1.0 has no support for ASP.NET -// SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI - -using System.IO; -using System.Web; -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter for items in the . - /// - /// - /// - /// Outputs an item from the . - /// - /// - /// Ron Grabowski - internal sealed class AspNetContextPatternConverter : AspNetPatternLayoutConverter - { - /// - /// Write the ASP.Net HttpContext item to the output - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. - /// - /// - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) - { - if (Option != null) - { - WriteObject(writer, loggingEvent.Repository, httpContext.Items[Option]); - } - else - { - WriteObject(writer, loggingEvent.Repository, httpContext.Items); - } - } - } -} - +#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 + +// .NET Compact Framework 1.0 has no support for ASP.NET +// SSCLI 1.0 has no support for ASP.NET +#if !NETCF && !SSCLI + +using System.IO; +using System.Web; +using log4net.Core; + +namespace log4net.Layout.Pattern +{ + /// + /// Converter for items in the . + /// + /// + /// + /// Outputs an item from the . + /// + /// + /// Ron Grabowski + internal sealed class AspNetContextPatternConverter : AspNetPatternLayoutConverter + { + /// + /// Write the ASP.Net HttpContext item to the output + /// + /// that will receive the formatted result. + /// The on which the pattern converter should be executed. + /// The under which the ASP.Net request is running. + /// + /// + /// Writes out the value of a named property. The property name + /// should be set in the + /// property. + /// + /// + protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) + { + if (Option != null) + { + WriteObject(writer, loggingEvent.Repository, httpContext.Items[Option]); + } + else + { + WriteObject(writer, loggingEvent.Repository, httpContext.Items); + } + } + } +} + #endif \ No newline at end of file diff --git a/src/Layout/Pattern/AspNetPatternConverter.cs b/src/Layout/Pattern/AspNetPatternConverter.cs index 9499ef1f..6bf756e5 100644 --- a/src/Layout/Pattern/AspNetPatternConverter.cs +++ b/src/Layout/Pattern/AspNetPatternConverter.cs @@ -1,65 +1,65 @@ -#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 - -// .NET Compact Framework 1.0 has no support for ASP.NET -// SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI - -using System.IO; -using System.Web; -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout.Pattern -{ - /// - /// Abstract class that provides access to the current HttpContext () that - /// derived classes need. - /// - /// - /// This class handles the case when HttpContext.Current is null by writing - /// to the writer. - /// - /// Ron Grabowski - internal abstract class AspNetPatternLayoutConverter : PatternLayoutConverter - { - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - if (HttpContext.Current == null) - { - writer.Write(SystemInfo.NotAvailableText); - } - else - { - Convert(writer, loggingEvent, HttpContext.Current); - } - } - - /// - /// Derived pattern converters must override this method in order to - /// convert conversion specifiers in the correct way. - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - protected abstract void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext); - } -} - +#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 + +// .NET Compact Framework 1.0 has no support for ASP.NET +// SSCLI 1.0 has no support for ASP.NET +#if !NETCF && !SSCLI + +using System.IO; +using System.Web; +using log4net.Core; +using log4net.Util; + +namespace log4net.Layout.Pattern +{ + /// + /// Abstract class that provides access to the current HttpContext () that + /// derived classes need. + /// + /// + /// This class handles the case when HttpContext.Current is null by writing + /// to the writer. + /// + /// Ron Grabowski + internal abstract class AspNetPatternLayoutConverter : PatternLayoutConverter + { + protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) + { + if (HttpContext.Current == null) + { + writer.Write(SystemInfo.NotAvailableText); + } + else + { + Convert(writer, loggingEvent, HttpContext.Current); + } + } + + /// + /// Derived pattern converters must override this method in order to + /// convert conversion specifiers in the correct way. + /// + /// that will receive the formatted result. + /// The on which the pattern converter should be executed. + /// The under which the ASP.Net request is running. + protected abstract void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext); + } +} + #endif \ No newline at end of file diff --git a/src/Layout/Pattern/AspNetRequestPatternConverter.cs b/src/Layout/Pattern/AspNetRequestPatternConverter.cs index 912ab545..8a601ade 100644 --- a/src/Layout/Pattern/AspNetRequestPatternConverter.cs +++ b/src/Layout/Pattern/AspNetRequestPatternConverter.cs @@ -1,76 +1,76 @@ -#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 - -// .NET Compact Framework 1.0 has no support for ASP.NET -// SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI - -using System.IO; -using System.Web; -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter for items in the ASP.Net Cache. - /// - /// - /// - /// Outputs an item from the . - /// - /// - /// Ron Grabowski - internal sealed class AspNetRequestPatternConverter : AspNetPatternLayoutConverter - { - /// - /// Write the ASP.Net Cache item to the output - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. - /// - /// - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) - { - if (httpContext.Request != null) - { - if (Option != null) - { - WriteObject(writer, loggingEvent.Repository, httpContext.Request.Params[Option]); - } - else - { - WriteObject(writer, loggingEvent.Repository, httpContext.Request.Params); - } - } - else - { - writer.Write(SystemInfo.NotAvailableText); - } - } - } -} - +#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 + +// .NET Compact Framework 1.0 has no support for ASP.NET +// SSCLI 1.0 has no support for ASP.NET +#if !NETCF && !SSCLI + +using System.IO; +using System.Web; +using log4net.Core; +using log4net.Util; + +namespace log4net.Layout.Pattern +{ + /// + /// Converter for items in the ASP.Net Cache. + /// + /// + /// + /// Outputs an item from the . + /// + /// + /// Ron Grabowski + internal sealed class AspNetRequestPatternConverter : AspNetPatternLayoutConverter + { + /// + /// Write the ASP.Net Cache item to the output + /// + /// that will receive the formatted result. + /// The on which the pattern converter should be executed. + /// The under which the ASP.Net request is running. + /// + /// + /// Writes out the value of a named property. The property name + /// should be set in the + /// property. + /// + /// + protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) + { + if (httpContext.Request != null) + { + if (Option != null) + { + WriteObject(writer, loggingEvent.Repository, httpContext.Request.Params[Option]); + } + else + { + WriteObject(writer, loggingEvent.Repository, httpContext.Request.Params); + } + } + else + { + writer.Write(SystemInfo.NotAvailableText); + } + } + } +} + #endif \ No newline at end of file diff --git a/src/Layout/Pattern/AspNetSessionPatternConverter.cs b/src/Layout/Pattern/AspNetSessionPatternConverter.cs index 52fb2d0e..a83dad5d 100644 --- a/src/Layout/Pattern/AspNetSessionPatternConverter.cs +++ b/src/Layout/Pattern/AspNetSessionPatternConverter.cs @@ -1,77 +1,77 @@ -#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 - -// .NET Compact Framework 1.0 has no support for ASP.NET -// SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI - -using System.IO; -using System.Web; -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter for items in the ASP.Net Cache. - /// - /// - /// - /// Outputs an item from the . - /// - /// - /// Ron Grabowski - internal sealed class AspNetSessionPatternConverter : AspNetPatternLayoutConverter - { - /// - /// Write the ASP.Net Cache item to the output - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. If no property has been set, all key value pairs from the Session will - /// be written to the output. - /// - /// - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) - { - if (httpContext.Session != null) - { - if (Option != null) - { - WriteObject(writer, loggingEvent.Repository, httpContext.Session.Contents[Option]); - } - else - { - WriteObject(writer, loggingEvent.Repository, httpContext.Session); - } - } - else - { - writer.Write(SystemInfo.NotAvailableText); - } - } - } -} - +#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 + +// .NET Compact Framework 1.0 has no support for ASP.NET +// SSCLI 1.0 has no support for ASP.NET +#if !NETCF && !SSCLI + +using System.IO; +using System.Web; +using log4net.Core; +using log4net.Util; + +namespace log4net.Layout.Pattern +{ + /// + /// Converter for items in the ASP.Net Cache. + /// + /// + /// + /// Outputs an item from the . + /// + /// + /// Ron Grabowski + internal sealed class AspNetSessionPatternConverter : AspNetPatternLayoutConverter + { + /// + /// Write the ASP.Net Cache item to the output + /// + /// that will receive the formatted result. + /// The on which the pattern converter should be executed. + /// The under which the ASP.Net request is running. + /// + /// + /// Writes out the value of a named property. The property name + /// should be set in the + /// property. If no property has been set, all key value pairs from the Session will + /// be written to the output. + /// + /// + protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) + { + if (httpContext.Session != null) + { + if (Option != null) + { + WriteObject(writer, loggingEvent.Repository, httpContext.Session.Contents[Option]); + } + else + { + WriteObject(writer, loggingEvent.Repository, httpContext.Session); + } + } + else + { + writer.Write(SystemInfo.NotAvailableText); + } + } + } +} + #endif \ No newline at end of file diff --git a/src/Layout/Pattern/StackTraceDetailPatternConverter.cs b/src/Layout/Pattern/StackTraceDetailPatternConverter.cs index 6fec5f20..2277505b 100644 --- a/src/Layout/Pattern/StackTraceDetailPatternConverter.cs +++ b/src/Layout/Pattern/StackTraceDetailPatternConverter.cs @@ -1,90 +1,90 @@ -using System; -using System.Collections; -using System.Text; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the caller stack frames to the output - /// - /// - /// - /// Writes the to the output writer, using format: - /// type3.MethodCall3(type param,...) > type2.MethodCall2(type param,...) > type1.MethodCall1(type param,...) - /// - /// - /// Adam Davies - internal class StackTraceDetailPatternConverter : StackTracePatternConverter - { - internal override string GetMethodInformation(System.Reflection.MethodBase method) - { - string returnValue=""; - - try - { - string param = ""; - string[] names = GetMethodParameterNames(method); - StringBuilder sb = new StringBuilder(); - if (names != null && names.GetUpperBound(0) > 0) - { - for (int i = 0; i <= names.GetUpperBound(0); i++) - { - sb.AppendFormat("{0}, ", names[i]); - } - } - - if (sb.Length > 0) - { - sb.Remove(sb.Length - 2, 2); - param = sb.ToString(); - } - - returnValue=base.GetMethodInformation(method) + "(" + param + ")"; - } - catch (Exception ex) - { - LogLog.Error(declaringType, "An exception ocurred while retreiving method information.", ex); - } - - return returnValue; - } - - private string[] GetMethodParameterNames(System.Reflection.MethodBase methodBase) - { - ArrayList methodParameterNames = new ArrayList(); - try - { - System.Reflection.ParameterInfo[] methodBaseGetParameters = methodBase.GetParameters(); - - int methodBaseGetParametersCount = methodBaseGetParameters.GetUpperBound(0); - - for (int i = 0; i <= methodBaseGetParametersCount; i++) - { - methodParameterNames.Add(methodBaseGetParameters[i].ParameterType + " " + methodBaseGetParameters[i].Name); - } - } - catch (Exception ex) - { - LogLog.Error(declaringType, "An exception ocurred while retreiving method parameters.", ex); - } - - return (string[])methodParameterNames.ToArray(typeof (string)); - } - - #region Private Static Fields - - /// - /// The fully qualified type of the StackTraceDetailPatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(StackTracePatternConverter); - - #endregion Private Static Fields - } -} +using System; +using System.Collections; +using System.Text; + +using log4net.Util; +using log4net.Core; + +namespace log4net.Layout.Pattern +{ + /// + /// Write the caller stack frames to the output + /// + /// + /// + /// Writes the to the output writer, using format: + /// type3.MethodCall3(type param,...) > type2.MethodCall2(type param,...) > type1.MethodCall1(type param,...) + /// + /// + /// Adam Davies + internal class StackTraceDetailPatternConverter : StackTracePatternConverter + { + internal override string GetMethodInformation(System.Reflection.MethodBase method) + { + string returnValue=""; + + try + { + string param = ""; + string[] names = GetMethodParameterNames(method); + StringBuilder sb = new StringBuilder(); + if (names != null && names.GetUpperBound(0) > 0) + { + for (int i = 0; i <= names.GetUpperBound(0); i++) + { + sb.AppendFormat("{0}, ", names[i]); + } + } + + if (sb.Length > 0) + { + sb.Remove(sb.Length - 2, 2); + param = sb.ToString(); + } + + returnValue=base.GetMethodInformation(method) + "(" + param + ")"; + } + catch (Exception ex) + { + LogLog.Error(declaringType, "An exception ocurred while retreiving method information.", ex); + } + + return returnValue; + } + + private string[] GetMethodParameterNames(System.Reflection.MethodBase methodBase) + { + ArrayList methodParameterNames = new ArrayList(); + try + { + System.Reflection.ParameterInfo[] methodBaseGetParameters = methodBase.GetParameters(); + + int methodBaseGetParametersCount = methodBaseGetParameters.GetUpperBound(0); + + for (int i = 0; i <= methodBaseGetParametersCount; i++) + { + methodParameterNames.Add(methodBaseGetParameters[i].ParameterType + " " + methodBaseGetParameters[i].Name); + } + } + catch (Exception ex) + { + LogLog.Error(declaringType, "An exception ocurred while retreiving method parameters.", ex); + } + + return (string[])methodParameterNames.ToArray(typeof (string)); + } + + #region Private Static Fields + + /// + /// The fully qualified type of the StackTraceDetailPatternConverter class. + /// + /// + /// Used by the internal logger to record the Type of the + /// log message. + /// + private readonly static Type declaringType = typeof(StackTracePatternConverter); + + #endregion Private Static Fields + } +} diff --git a/src/Layout/Pattern/StackTracePatternConverter.cs b/src/Layout/Pattern/StackTracePatternConverter.cs index 6e57242a..1fa83d73 100644 --- a/src/Layout/Pattern/StackTracePatternConverter.cs +++ b/src/Layout/Pattern/StackTracePatternConverter.cs @@ -1,149 +1,149 @@ -#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 System.IO; -using System.Diagnostics; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the caller stack frames to the output - /// - /// - /// - /// Writes the to the output writer, using format: - /// type3.MethodCall3 > type2.MethodCall2 > type1.MethodCall1 - /// - /// - /// Michael Cromwell - internal class StackTracePatternConverter : PatternLayoutConverter, IOptionHandler - { - private int m_stackFrameLevel = 1; - - /// - /// Initialize the converter - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - public void ActivateOptions() - { - if (Option == null) - return; - - string optStr = Option.Trim(); - if (optStr.Length != 0) - { - int stackLevelVal; - if (SystemInfo.TryParse(optStr, out stackLevelVal)) - { - if (stackLevelVal <= 0) - { - LogLog.Error(declaringType, "StackTracePatternConverter: StackeFrameLevel option (" + optStr + ") isn't a positive integer."); - } - else - { - m_stackFrameLevel = stackLevelVal; - } - } - else - { - LogLog.Error(declaringType, "StackTracePatternConverter: StackFrameLevel option \"" + optStr + "\" not a decimal integer."); - } - } - } - - /// - /// Write the strack frames to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the to the output writer. - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - StackFrame[] stackframes = loggingEvent.LocationInformation.StackFrames; - if ((stackframes == null) || (stackframes.Length <= 0)) - { - LogLog.Error(declaringType, "loggingEvent.LocationInformation.StackFrames was null or empty."); - return; - } - - int stackFrameIndex = m_stackFrameLevel - 1; - while (stackFrameIndex >= 0) - { - if (stackFrameIndex > stackframes.Length) - { - stackFrameIndex--; - continue; - } - - StackFrame stackFrame = stackframes[stackFrameIndex]; - writer.Write("{0}.{1}", stackFrame.GetMethod().DeclaringType.Name, GetMethodInformation(stackFrame.GetMethod())); - if (stackFrameIndex > 0) - { - // TODO: make this user settable? - writer.Write(" > "); - } - stackFrameIndex--; - } - } - - /// - /// Returns the Name of the method - /// - /// - /// This method was created, so this class could be used as a base class for StackTraceDetailPatternConverter - /// string - internal virtual string GetMethodInformation(System.Reflection.MethodBase method) - { - return method.Name; - } - - #region Private Static Fields - - /// - /// The fully qualified type of the StackTracePatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(StackTracePatternConverter); - - #endregion Private Static Fields - } -} +#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 System.IO; +using System.Diagnostics; + +using log4net.Util; +using log4net.Core; + +namespace log4net.Layout.Pattern +{ + /// + /// Write the caller stack frames to the output + /// + /// + /// + /// Writes the to the output writer, using format: + /// type3.MethodCall3 > type2.MethodCall2 > type1.MethodCall1 + /// + /// + /// Michael Cromwell + internal class StackTracePatternConverter : PatternLayoutConverter, IOptionHandler + { + private int m_stackFrameLevel = 1; + + /// + /// Initialize the converter + /// + /// + /// + /// This is part of the delayed object + /// activation scheme. The method must + /// be called on this object after the configuration properties have + /// been set. Until is called this + /// object is in an undefined state and must not be used. + /// + /// + /// If any of the configuration properties are modified then + /// must be called again. + /// + /// + public void ActivateOptions() + { + if (Option == null) + return; + + string optStr = Option.Trim(); + if (optStr.Length != 0) + { + int stackLevelVal; + if (SystemInfo.TryParse(optStr, out stackLevelVal)) + { + if (stackLevelVal <= 0) + { + LogLog.Error(declaringType, "StackTracePatternConverter: StackeFrameLevel option (" + optStr + ") isn't a positive integer."); + } + else + { + m_stackFrameLevel = stackLevelVal; + } + } + else + { + LogLog.Error(declaringType, "StackTracePatternConverter: StackFrameLevel option \"" + optStr + "\" not a decimal integer."); + } + } + } + + /// + /// Write the strack frames to the output + /// + /// that will receive the formatted result. + /// the event being logged + /// + /// + /// Writes the to the output writer. + /// + /// + override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) + { + StackFrame[] stackframes = loggingEvent.LocationInformation.StackFrames; + if ((stackframes == null) || (stackframes.Length <= 0)) + { + LogLog.Error(declaringType, "loggingEvent.LocationInformation.StackFrames was null or empty."); + return; + } + + int stackFrameIndex = m_stackFrameLevel - 1; + while (stackFrameIndex >= 0) + { + if (stackFrameIndex > stackframes.Length) + { + stackFrameIndex--; + continue; + } + + StackFrame stackFrame = stackframes[stackFrameIndex]; + writer.Write("{0}.{1}", stackFrame.GetMethod().DeclaringType.Name, GetMethodInformation(stackFrame.GetMethod())); + if (stackFrameIndex > 0) + { + // TODO: make this user settable? + writer.Write(" > "); + } + stackFrameIndex--; + } + } + + /// + /// Returns the Name of the method + /// + /// + /// This method was created, so this class could be used as a base class for StackTraceDetailPatternConverter + /// string + internal virtual string GetMethodInformation(System.Reflection.MethodBase method) + { + return method.Name; + } + + #region Private Static Fields + + /// + /// The fully qualified type of the StackTracePatternConverter class. + /// + /// + /// Used by the internal logger to record the Type of the + /// log message. + /// + private readonly static Type declaringType = typeof(StackTracePatternConverter); + + #endregion Private Static Fields + } +} diff --git a/src/Repository/ConfigurationChangedEventArgs.cs b/src/Repository/ConfigurationChangedEventArgs.cs index 47bf36fb..ded98531 100644 --- a/src/Repository/ConfigurationChangedEventArgs.cs +++ b/src/Repository/ConfigurationChangedEventArgs.cs @@ -1,30 +1,30 @@ -using System; -using System.Collections; - -namespace log4net.Repository -{ - /// - /// - /// - public class ConfigurationChangedEventArgs : EventArgs - { - private readonly ICollection configurationMessages; - - /// - /// - /// - /// - public ConfigurationChangedEventArgs(ICollection configurationMessages) - { - this.configurationMessages = configurationMessages; - } - - /// - /// - /// - public ICollection ConfigurationMessages - { - get { return configurationMessages; } - } - } +using System; +using System.Collections; + +namespace log4net.Repository +{ + /// + /// + /// + public class ConfigurationChangedEventArgs : EventArgs + { + private readonly ICollection configurationMessages; + + /// + /// + /// + /// + public ConfigurationChangedEventArgs(ICollection configurationMessages) + { + this.configurationMessages = configurationMessages; + } + + /// + /// + /// + public ICollection ConfigurationMessages + { + get { return configurationMessages; } + } + } } \ No newline at end of file diff --git a/src/Util/ConverterInfo.cs b/src/Util/ConverterInfo.cs index f2919d59..efab75fd 100644 --- a/src/Util/ConverterInfo.cs +++ b/src/Util/ConverterInfo.cs @@ -1,73 +1,73 @@ -using System; - -namespace log4net.Util -{ - /// - /// Wrapper class used to map converter names to converter types - /// - /// - /// - /// Pattern converter info class used during configuration by custom - /// PatternString and PatternLayer converters. - /// - /// - public sealed class ConverterInfo - { - private string m_name; - private Type m_type; - private readonly PropertiesDictionary properties = new PropertiesDictionary(); - - /// - /// default constructor - /// - public ConverterInfo() - { - } - - /// - /// Gets or sets the name of the conversion pattern - /// - /// - /// - /// The name of the pattern in the format string - /// - /// - public string Name - { - get { return m_name; } - set { m_name = value; } - } - - /// - /// Gets or sets the type of the converter - /// - /// - /// - /// The value specified must extend the - /// type. - /// - /// - public Type Type - { - get { return m_type; } - set { m_type = value; } - } - - /// - /// - /// - /// - public void AddProperty(PropertyEntry entry) - { - properties[entry.Key] = entry.Value; - } - - /// - /// - /// - public PropertiesDictionary Properties - { - get { return properties; } - } - } -} +using System; + +namespace log4net.Util +{ + /// + /// Wrapper class used to map converter names to converter types + /// + /// + /// + /// Pattern converter info class used during configuration by custom + /// PatternString and PatternLayer converters. + /// + /// + public sealed class ConverterInfo + { + private string m_name; + private Type m_type; + private readonly PropertiesDictionary properties = new PropertiesDictionary(); + + /// + /// default constructor + /// + public ConverterInfo() + { + } + + /// + /// Gets or sets the name of the conversion pattern + /// + /// + /// + /// The name of the pattern in the format string + /// + /// + public string Name + { + get { return m_name; } + set { m_name = value; } + } + + /// + /// Gets or sets the type of the converter + /// + /// + /// + /// The value specified must extend the + /// type. + /// + /// + public Type Type + { + get { return m_type; } + set { m_type = value; } + } + + /// + /// + /// + /// + public void AddProperty(PropertyEntry entry) + { + properties[entry.Key] = entry.Value; + } + + /// + /// + /// + public PropertiesDictionary Properties + { + get { return properties; } + } + } +} diff --git a/src/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs b/src/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs index d23b8a14..a6dd2216 100644 --- a/src/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs +++ b/src/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs @@ -1,98 +1,98 @@ -#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 - -#if !NETCF - -using System; -using System.IO; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Write an folder path to the output - /// - /// - /// - /// Write an special path environment folder path to the output writer. - /// The value of the determines - /// the name of the variable to output. - /// should be a value in the enumeration. - /// - /// - /// Ron Grabowski - internal sealed class EnvironmentFolderPathPatternConverter : PatternConverter - { - /// - /// Write an special path environment folder path to the output - /// - /// the writer to write to - /// null, state is not set - /// - /// - /// Writes the special path environment folder path to the output . - /// The name of the special path environment folder path to output must be set - /// using the - /// property. - /// - /// - override protected void Convert(TextWriter writer, object state) - { - try - { - if (Option != null && Option.Length > 0) - { - Environment.SpecialFolder specialFolder = - (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), Option, true); - - string envFolderPathValue = Environment.GetFolderPath(specialFolder); - if (envFolderPathValue != null && envFolderPathValue.Length > 0) - { - writer.Write(envFolderPathValue); - } - } - } - catch (System.Security.SecurityException secEx) - { - // This security exception will occur if the caller does not have - // unrestricted environment permission. If this occurs the expansion - // will be skipped with the following warning message. - LogLog.Debug(declaringType, "Security exception while trying to expand environment variables. Error Ignored. No Expansion.", secEx); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Error occurred while converting environment variable.", ex); - } - } - - #region Private Static Fields - - /// - /// The fully qualified type of the EnvironmentFolderPathPatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(EnvironmentFolderPathPatternConverter); - - #endregion Private Static Fields - } -} - +#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 + +#if !NETCF + +using System; +using System.IO; + +namespace log4net.Util.PatternStringConverters +{ + /// + /// Write an folder path to the output + /// + /// + /// + /// Write an special path environment folder path to the output writer. + /// The value of the determines + /// the name of the variable to output. + /// should be a value in the enumeration. + /// + /// + /// Ron Grabowski + internal sealed class EnvironmentFolderPathPatternConverter : PatternConverter + { + /// + /// Write an special path environment folder path to the output + /// + /// the writer to write to + /// null, state is not set + /// + /// + /// Writes the special path environment folder path to the output . + /// The name of the special path environment folder path to output must be set + /// using the + /// property. + /// + /// + override protected void Convert(TextWriter writer, object state) + { + try + { + if (Option != null && Option.Length > 0) + { + Environment.SpecialFolder specialFolder = + (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), Option, true); + + string envFolderPathValue = Environment.GetFolderPath(specialFolder); + if (envFolderPathValue != null && envFolderPathValue.Length > 0) + { + writer.Write(envFolderPathValue); + } + } + } + catch (System.Security.SecurityException secEx) + { + // This security exception will occur if the caller does not have + // unrestricted environment permission. If this occurs the expansion + // will be skipped with the following warning message. + LogLog.Debug(declaringType, "Security exception while trying to expand environment variables. Error Ignored. No Expansion.", secEx); + } + catch (Exception ex) + { + LogLog.Error(declaringType, "Error occurred while converting environment variable.", ex); + } + } + + #region Private Static Fields + + /// + /// The fully qualified type of the EnvironmentFolderPathPatternConverter class. + /// + /// + /// Used by the internal logger to record the Type of the + /// log message. + /// + private readonly static Type declaringType = typeof(EnvironmentFolderPathPatternConverter); + + #endregion Private Static Fields + } +} + #endif // !NETCF \ No newline at end of file diff --git a/src/Util/PropertyEntry.cs b/src/Util/PropertyEntry.cs index 3ef83a1d..d11f58df 100644 --- a/src/Util/PropertyEntry.cs +++ b/src/Util/PropertyEntry.cs @@ -1,59 +1,59 @@ -namespace log4net.Util -{ - /// - /// A class to hold the key and data for a property set in the config file - /// - /// - /// - /// A class to hold the key and data for a property set in the config file - /// - /// - public class PropertyEntry - { - private string m_key = null; - private object m_value = null; - - /// - /// Property Key - /// - /// - /// Property Key - /// - /// - /// - /// Property Key. - /// - /// - public string Key - { - get { return m_key; } - set { m_key = value; } - } - - /// - /// Property Value - /// - /// - /// Property Value - /// - /// - /// - /// Property Value. - /// - /// - public object Value - { - get { return m_value; } - set { m_value = value; } - } - - /// - /// Override Object.ToString to return sensible debug info - /// - /// string info about this object - public override string ToString() - { - return "PropertyEntry(Key=" + m_key + ", Value=" + m_value + ")"; - } - } -} +namespace log4net.Util +{ + /// + /// A class to hold the key and data for a property set in the config file + /// + /// + /// + /// A class to hold the key and data for a property set in the config file + /// + /// + public class PropertyEntry + { + private string m_key = null; + private object m_value = null; + + /// + /// Property Key + /// + /// + /// Property Key + /// + /// + /// + /// Property Key. + /// + /// + public string Key + { + get { return m_key; } + set { m_key = value; } + } + + /// + /// Property Value + /// + /// + /// Property Value + /// + /// + /// + /// Property Value. + /// + /// + public object Value + { + get { return m_value; } + set { m_value = value; } + } + + /// + /// Override Object.ToString to return sensible debug info + /// + /// string info about this object + public override string ToString() + { + return "PropertyEntry(Key=" + m_key + ", Value=" + m_value + ")"; + } + } +} diff --git a/src/Util/SystemStringFormat.cs b/src/Util/SystemStringFormat.cs index 2df2f31b..8e022fe2 100644 --- a/src/Util/SystemStringFormat.cs +++ b/src/Util/SystemStringFormat.cs @@ -1,231 +1,231 @@ -#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 System.Text; -using System.Xml; -using System.Text.RegularExpressions; - -namespace log4net.Util -{ - /// - /// Utility class that represents a format string. - /// - /// - /// - /// Utility class that represents a format string. - /// - /// - /// Nicko Cadell - public sealed class SystemStringFormat - { - private readonly IFormatProvider m_provider; - private readonly string m_format; - private readonly object[] m_args; - - #region Constructor - - /// - /// Initialise the - /// - /// An that supplies culture-specific formatting information. - /// A containing zero or more format items. - /// An array containing zero or more objects to format. - public SystemStringFormat(IFormatProvider provider, string format, params object[] args) - { - m_provider = provider; - m_format = format; - m_args = args; - } - - #endregion Constructor - - /// - /// Format the string and arguments - /// - /// the formatted string - public override string ToString() - { - return StringFormat(m_provider, m_format, m_args); - } - - #region StringFormat - - /// - /// Replaces the format item in a specified with the text equivalent - /// of the value of a corresponding instance in a specified array. - /// A specified parameter supplies culture-specific formatting information. - /// - /// An that supplies culture-specific formatting information. - /// A containing zero or more format items. - /// An array containing zero or more objects to format. - /// - /// A copy of format in which the format items have been replaced by the - /// equivalent of the corresponding instances of in args. - /// - /// - /// - /// This method does not throw exceptions. If an exception thrown while formatting the result the - /// exception and arguments are returned in the result string. - /// - /// - private static string StringFormat(IFormatProvider provider, string format, params object[] args) - { - try - { - // The format is missing, log null value - if (format == null) - { - return null; - } - - // The args are missing - should not happen unless we are called explicitly with a null array - if (args == null) - { - return format; - } - - // Try to format the string - return String.Format(provider, format, args); - } - catch(Exception ex) - { - log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]", ex); - return StringFormatError(ex, format, args); - } - catch - { - log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]"); - return StringFormatError(null, format, args); - } - } - - /// - /// Process an error during StringFormat - /// - private static string StringFormatError(Exception formatException, string format, object[] args) - { - try - { - StringBuilder buf = new StringBuilder(""); - - if (formatException != null) - { - buf.Append("Exception during StringFormat: ").Append(formatException.Message); - } - else - { - buf.Append("Exception during StringFormat"); - } - buf.Append(" ").Append(format).Append(""); - buf.Append(""); - RenderArray(args, buf); - buf.Append(""); - buf.Append(""); - - return buf.ToString(); - } - catch(Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex); - return "Exception during StringFormat. See Internal Log."; - } - catch - { - log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling"); - return "Exception during StringFormat. See Internal Log."; - } - } - - /// - /// Dump the contents of an array into a string builder - /// - private static void RenderArray(Array array, StringBuilder buffer) - { - if (array == null) - { - buffer.Append(SystemInfo.NullText); - } - else - { - if (array.Rank != 1) - { - buffer.Append(array.ToString()); - } - else - { - buffer.Append("{"); - int len = array.Length; - - if (len > 0) - { - RenderObject(array.GetValue(0), buffer); - for (int i = 1; i < len; i++) - { - buffer.Append(", "); - RenderObject(array.GetValue(i), buffer); - } - } - buffer.Append("}"); - } - } - } - - /// - /// Dump an object to a string - /// - private static void RenderObject(Object obj, StringBuilder buffer) - { - if (obj == null) - { - buffer.Append(SystemInfo.NullText); - } - else - { - try - { - buffer.Append(obj); - } - catch(Exception ex) - { - buffer.Append(""); - } - catch - { - buffer.Append(""); - } - } - } - - #endregion StringFormat - - #region Private Static Fields - - /// - /// The fully qualified type of the SystemStringFormat class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(SystemStringFormat); - - #endregion Private Static Fields - } -} +#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 System.Text; +using System.Xml; +using System.Text.RegularExpressions; + +namespace log4net.Util +{ + /// + /// Utility class that represents a format string. + /// + /// + /// + /// Utility class that represents a format string. + /// + /// + /// Nicko Cadell + public sealed class SystemStringFormat + { + private readonly IFormatProvider m_provider; + private readonly string m_format; + private readonly object[] m_args; + + #region Constructor + + /// + /// Initialise the + /// + /// An that supplies culture-specific formatting information. + /// A containing zero or more format items. + /// An array containing zero or more objects to format. + public SystemStringFormat(IFormatProvider provider, string format, params object[] args) + { + m_provider = provider; + m_format = format; + m_args = args; + } + + #endregion Constructor + + /// + /// Format the string and arguments + /// + /// the formatted string + public override string ToString() + { + return StringFormat(m_provider, m_format, m_args); + } + + #region StringFormat + + /// + /// Replaces the format item in a specified with the text equivalent + /// of the value of a corresponding instance in a specified array. + /// A specified parameter supplies culture-specific formatting information. + /// + /// An that supplies culture-specific formatting information. + /// A containing zero or more format items. + /// An array containing zero or more objects to format. + /// + /// A copy of format in which the format items have been replaced by the + /// equivalent of the corresponding instances of in args. + /// + /// + /// + /// This method does not throw exceptions. If an exception thrown while formatting the result the + /// exception and arguments are returned in the result string. + /// + /// + private static string StringFormat(IFormatProvider provider, string format, params object[] args) + { + try + { + // The format is missing, log null value + if (format == null) + { + return null; + } + + // The args are missing - should not happen unless we are called explicitly with a null array + if (args == null) + { + return format; + } + + // Try to format the string + return String.Format(provider, format, args); + } + catch(Exception ex) + { + log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]", ex); + return StringFormatError(ex, format, args); + } + catch + { + log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]"); + return StringFormatError(null, format, args); + } + } + + /// + /// Process an error during StringFormat + /// + private static string StringFormatError(Exception formatException, string format, object[] args) + { + try + { + StringBuilder buf = new StringBuilder(""); + + if (formatException != null) + { + buf.Append("Exception during StringFormat: ").Append(formatException.Message); + } + else + { + buf.Append("Exception during StringFormat"); + } + buf.Append(" ").Append(format).Append(""); + buf.Append(""); + RenderArray(args, buf); + buf.Append(""); + buf.Append(""); + + return buf.ToString(); + } + catch(Exception ex) + { + log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex); + return "Exception during StringFormat. See Internal Log."; + } + catch + { + log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling"); + return "Exception during StringFormat. See Internal Log."; + } + } + + /// + /// Dump the contents of an array into a string builder + /// + private static void RenderArray(Array array, StringBuilder buffer) + { + if (array == null) + { + buffer.Append(SystemInfo.NullText); + } + else + { + if (array.Rank != 1) + { + buffer.Append(array.ToString()); + } + else + { + buffer.Append("{"); + int len = array.Length; + + if (len > 0) + { + RenderObject(array.GetValue(0), buffer); + for (int i = 1; i < len; i++) + { + buffer.Append(", "); + RenderObject(array.GetValue(i), buffer); + } + } + buffer.Append("}"); + } + } + } + + /// + /// Dump an object to a string + /// + private static void RenderObject(Object obj, StringBuilder buffer) + { + if (obj == null) + { + buffer.Append(SystemInfo.NullText); + } + else + { + try + { + buffer.Append(obj); + } + catch(Exception ex) + { + buffer.Append(""); + } + catch + { + buffer.Append(""); + } + } + } + + #endregion StringFormat + + #region Private Static Fields + + /// + /// The fully qualified type of the SystemStringFormat class. + /// + /// + /// Used by the internal logger to record the Type of the + /// log message. + /// + private readonly static Type declaringType = typeof(SystemStringFormat); + + #endregion Private Static Fields + } +} diff --git a/src/assembly/bin.xml b/src/assembly/bin.xml index 4090576e..c52bf0de 100644 --- a/src/assembly/bin.xml +++ b/src/assembly/bin.xml @@ -33,7 +33,7 @@ KEYS LICENSE NOTICE - contribs/** + contribs/** examples/** src/assembly/** src/changes/** @@ -41,10 +41,10 @@ src/ntdll/** src/performance/** src/site/** - tests/README - tests/*.xml - tests/*.sample - tests/*.bat + tests/README + tests/*.xml + tests/*.sample + tests/*.bat tests/input/** tests/resources/** tests/src/** diff --git a/src/log4net.vs2008.csproj b/src/log4net.vs2008.csproj index edfd7d95..46c85553 100644 --- a/src/log4net.vs2008.csproj +++ b/src/log4net.vs2008.csproj @@ -1,726 +1,726 @@ - - - Local - 9.0.30729 - 2.0 - {181FE707-E161-4722-9F38-6AAAB6FAA106} - Debug - AnyCPU - - - - - log4net - - - JScript - Grid - IE50 - false - Library - log4net - - - - - - - 2.0 - - - ..\build\bin\net\2.0\debug\ - false - 285212672 - false - - - TRACE;DEBUG;NET;NET_2_0 - log4net.xml - true - 4096 - false - false - false - false - 4 - full - prompt - - - ..\build\bin\net\1.0\release\ - false - 285212672 - false - - - TRACE;STRONG;NET;NET_1_0; - log4net.xml - false - 4096 - true - false - false - false - 4 - none - prompt - - - - System - - - - System.Data - - - System.Web - - - System.XML - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - - - - - + + + Local + 9.0.30729 + 2.0 + {181FE707-E161-4722-9F38-6AAAB6FAA106} + Debug + AnyCPU + + + + + log4net + + + JScript + Grid + IE50 + false + Library + log4net + + + + + + + 2.0 + + + ..\build\bin\net\2.0\debug\ + false + 285212672 + false + + + TRACE;DEBUG;NET;NET_2_0 + log4net.xml + true + 4096 + false + false + false + false + 4 + full + prompt + + + ..\build\bin\net\1.0\release\ + false + 285212672 + false + + + TRACE;STRONG;NET;NET_1_0; + log4net.xml + false + 4096 + true + false + false + false + 4 + none + prompt + + + + System + + + + System.Data + + + System.Web + + + System.XML + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + \ No newline at end of file diff --git a/src/log4net.vs2008.sln b/src/log4net.vs2008.sln index 11a6af3a..74193889 100644 --- a/src/log4net.vs2008.sln +++ b/src/log4net.vs2008.sln @@ -1,25 +1,25 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.vs2008", "log4net.vs2008.csproj", "{181FE707-E161-4722-9F38-6AAAB6FAA106}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Tests.vs2008", "..\tests\src\log4net.Tests.vs2008.csproj", "{B0530F10-0238-49A9-93B0-8EF412E90BCF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.Build.0 = Debug|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.ActiveCfg = Release|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.Build.0 = Release|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.vs2008", "log4net.vs2008.csproj", "{181FE707-E161-4722-9F38-6AAAB6FAA106}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Tests.vs2008", "..\tests\src\log4net.Tests.vs2008.csproj", "{B0530F10-0238-49A9-93B0-8EF412E90BCF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.Build.0 = Debug|Any CPU + {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.ActiveCfg = Release|Any CPU + {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.Build.0 = Release|Any CPU + {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tests/lib/prerequisites.txt b/tests/lib/prerequisites.txt index a2e49c6c..a9a65c4c 100644 --- a/tests/lib/prerequisites.txt +++ b/tests/lib/prerequisites.txt @@ -1,37 +1,37 @@ -Prerequisites for log4net tests -=============================== - - -The nunit.framework.dll assembly version 2.2.7 is required to build -the log4net tests. - -NAnt 0.85 includes the 2.2.7 version of the nunit.framework.dll. - -The nunit.framework.dll is available as different builds for each -version of the .net runtime. To build multiple versions of the -log4net tests you will need several different copies of the -nunit.framework.dll. - -The log4net tests are currently built for the following runtimes: - -Microsoft .NET Framework 1.0 -Microsoft .NET Framework 1.1 -Microsoft .NET Framework 2.0 -Mono Framework 2.0 - -Under the tests/lib directory you must create the following directory -structure containing the nunit.framework.dll assembly built for the -appropriate version of the runtime: - -lib\ - net\ - 1.0\ - nunit.framework.dll - 1.1\ - nunit.framework.dll - 2.0\ - nunit.framework.dll - mono\ - 2.0\ - nunit.framework.dll - +Prerequisites for log4net tests +=============================== + + +The nunit.framework.dll assembly version 2.2.7 is required to build +the log4net tests. + +NAnt 0.85 includes the 2.2.7 version of the nunit.framework.dll. + +The nunit.framework.dll is available as different builds for each +version of the .net runtime. To build multiple versions of the +log4net tests you will need several different copies of the +nunit.framework.dll. + +The log4net tests are currently built for the following runtimes: + +Microsoft .NET Framework 1.0 +Microsoft .NET Framework 1.1 +Microsoft .NET Framework 2.0 +Mono Framework 2.0 + +Under the tests/lib directory you must create the following directory +structure containing the nunit.framework.dll assembly built for the +appropriate version of the runtime: + +lib\ + net\ + 1.0\ + nunit.framework.dll + 1.1\ + nunit.framework.dll + 2.0\ + nunit.framework.dll + mono\ + 2.0\ + nunit.framework.dll + diff --git a/tests/src/Appender/AdoNet/Log4NetCommand.cs b/tests/src/Appender/AdoNet/Log4NetCommand.cs index fef5e612..d7d41a43 100644 --- a/tests/src/Appender/AdoNet/Log4NetCommand.cs +++ b/tests/src/Appender/AdoNet/Log4NetCommand.cs @@ -1,123 +1,123 @@ -using System; -using System.Data; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetCommand : IDbCommand - { - #region AdoNetAppender - - private static Log4NetCommand mostRecentInstance; - - private IDbTransaction transaction; - private string commandText; - private readonly IDataParameterCollection parameters; - private CommandType commandType; - private int executeNonQueryCount; - - public Log4NetCommand() - { - mostRecentInstance = this; - - parameters = new Log4NetParameterCollection(); - } - - public void Dispose() - { - // empty - } - - public IDbTransaction Transaction - { - get { return transaction; } - set { transaction = value; } - } - - public int ExecuteNonQuery() - { - executeNonQueryCount++; - return 0; - } - - public int ExecuteNonQueryCount - { - get { return executeNonQueryCount; } - } - - public IDbDataParameter CreateParameter() - { - return new Log4NetParameter(); - } - - public string CommandText - { - get { return commandText; } - set { commandText = value; } - } - - public CommandType CommandType - { - get { return commandType; } - set { commandType = value; } - } - - public void Prepare() - { - // empty - } - - public IDataParameterCollection Parameters - { - get { return parameters; } - } - - public static Log4NetCommand MostRecentInstance - { - get { return mostRecentInstance; } - } - - #endregion - - #region Not Implemented - - public void Cancel() - { - throw new NotImplementedException(); - } - - public IDataReader ExecuteReader() - { - throw new NotImplementedException(); - } - - public IDataReader ExecuteReader(CommandBehavior behavior) - { - throw new NotImplementedException(); - } - - public object ExecuteScalar() - { - throw new NotImplementedException(); - } - - public IDbConnection Connection - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - public int CommandTimeout - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - public UpdateRowSource UpdatedRowSource - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - #endregion - } -} +using System; +using System.Data; + +namespace log4net.Tests.Appender.AdoNet +{ + public class Log4NetCommand : IDbCommand + { + #region AdoNetAppender + + private static Log4NetCommand mostRecentInstance; + + private IDbTransaction transaction; + private string commandText; + private readonly IDataParameterCollection parameters; + private CommandType commandType; + private int executeNonQueryCount; + + public Log4NetCommand() + { + mostRecentInstance = this; + + parameters = new Log4NetParameterCollection(); + } + + public void Dispose() + { + // empty + } + + public IDbTransaction Transaction + { + get { return transaction; } + set { transaction = value; } + } + + public int ExecuteNonQuery() + { + executeNonQueryCount++; + return 0; + } + + public int ExecuteNonQueryCount + { + get { return executeNonQueryCount; } + } + + public IDbDataParameter CreateParameter() + { + return new Log4NetParameter(); + } + + public string CommandText + { + get { return commandText; } + set { commandText = value; } + } + + public CommandType CommandType + { + get { return commandType; } + set { commandType = value; } + } + + public void Prepare() + { + // empty + } + + public IDataParameterCollection Parameters + { + get { return parameters; } + } + + public static Log4NetCommand MostRecentInstance + { + get { return mostRecentInstance; } + } + + #endregion + + #region Not Implemented + + public void Cancel() + { + throw new NotImplementedException(); + } + + public IDataReader ExecuteReader() + { + throw new NotImplementedException(); + } + + public IDataReader ExecuteReader(CommandBehavior behavior) + { + throw new NotImplementedException(); + } + + public object ExecuteScalar() + { + throw new NotImplementedException(); + } + + public IDbConnection Connection + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + public int CommandTimeout + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + public UpdateRowSource UpdatedRowSource + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + #endregion + } +} diff --git a/tests/src/Appender/AdoNet/Log4NetConnection.cs b/tests/src/Appender/AdoNet/Log4NetConnection.cs index 5cbb98c4..4c3b0db5 100644 --- a/tests/src/Appender/AdoNet/Log4NetConnection.cs +++ b/tests/src/Appender/AdoNet/Log4NetConnection.cs @@ -1,90 +1,90 @@ -using System; -using System.Data; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetConnection : IDbConnection - { - #region AdoNetAppender - - private static Log4NetConnection mostRecentInstance; - - private bool open; - private string connectionString; - - public Log4NetConnection() - { - mostRecentInstance = this; - } - - public void Close() - { - open = false; - } - - public ConnectionState State - { - get - { - return open ? ConnectionState.Open : ConnectionState.Closed; - } - } - - public string ConnectionString - { - get { return connectionString; } - set { connectionString = value; } - } - - public IDbTransaction BeginTransaction() - { - return new Log4NetTransaction(); - } - - public IDbCommand CreateCommand() - { - return new Log4NetCommand(); - } - - public void Open() - { - open = true; - } - - public static Log4NetConnection MostRecentInstance - { - get { return mostRecentInstance; } - } - - #endregion - - #region Not Implemented - - public IDbTransaction BeginTransaction(IsolationLevel il) - { - throw new NotImplementedException(); - } - - public void ChangeDatabase(string databaseName) - { - throw new NotImplementedException(); - } - - public int ConnectionTimeout - { - get { throw new NotImplementedException(); } - } - - public string Database - { - get { throw new NotImplementedException(); } - } - - public void Dispose() - { - throw new NotImplementedException(); - } - - #endregion - } -} +using System; +using System.Data; + +namespace log4net.Tests.Appender.AdoNet +{ + public class Log4NetConnection : IDbConnection + { + #region AdoNetAppender + + private static Log4NetConnection mostRecentInstance; + + private bool open; + private string connectionString; + + public Log4NetConnection() + { + mostRecentInstance = this; + } + + public void Close() + { + open = false; + } + + public ConnectionState State + { + get + { + return open ? ConnectionState.Open : ConnectionState.Closed; + } + } + + public string ConnectionString + { + get { return connectionString; } + set { connectionString = value; } + } + + public IDbTransaction BeginTransaction() + { + return new Log4NetTransaction(); + } + + public IDbCommand CreateCommand() + { + return new Log4NetCommand(); + } + + public void Open() + { + open = true; + } + + public static Log4NetConnection MostRecentInstance + { + get { return mostRecentInstance; } + } + + #endregion + + #region Not Implemented + + public IDbTransaction BeginTransaction(IsolationLevel il) + { + throw new NotImplementedException(); + } + + public void ChangeDatabase(string databaseName) + { + throw new NotImplementedException(); + } + + public int ConnectionTimeout + { + get { throw new NotImplementedException(); } + } + + public string Database + { + get { throw new NotImplementedException(); } + } + + public void Dispose() + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/tests/src/Appender/AdoNet/Log4NetParameter.cs b/tests/src/Appender/AdoNet/Log4NetParameter.cs index b8ba06ee..11c206ea 100644 --- a/tests/src/Appender/AdoNet/Log4NetParameter.cs +++ b/tests/src/Appender/AdoNet/Log4NetParameter.cs @@ -1,82 +1,82 @@ -using System; -using System.Data; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetParameter : IDbDataParameter - { - #region AdoNetAppender - - private string parameterName; - private byte precision; - private byte scale; - private int size; - private DbType dbType; - private object value; - - public string ParameterName - { - get { return parameterName; } - set { parameterName = value; } - } - - public byte Precision - { - get { return precision; } - set { precision = value; } - } - - public byte Scale - { - get { return scale; } - set { scale = value; } - } - - public int Size - { - get { return size; } - set { size = value; } - } - - public DbType DbType - { - get { return dbType; } - set { dbType = value; } - } - - public object Value - { - get { return value; } - set { this.value = value; } - } - - #endregion - - #region Not Implemented - - public ParameterDirection Direction - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - public bool IsNullable - { - get { throw new NotImplementedException(); } - } - - public string SourceColumn - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - public DataRowVersion SourceVersion - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - #endregion - } -} +using System; +using System.Data; + +namespace log4net.Tests.Appender.AdoNet +{ + public class Log4NetParameter : IDbDataParameter + { + #region AdoNetAppender + + private string parameterName; + private byte precision; + private byte scale; + private int size; + private DbType dbType; + private object value; + + public string ParameterName + { + get { return parameterName; } + set { parameterName = value; } + } + + public byte Precision + { + get { return precision; } + set { precision = value; } + } + + public byte Scale + { + get { return scale; } + set { scale = value; } + } + + public int Size + { + get { return size; } + set { size = value; } + } + + public DbType DbType + { + get { return dbType; } + set { dbType = value; } + } + + public object Value + { + get { return value; } + set { this.value = value; } + } + + #endregion + + #region Not Implemented + + public ParameterDirection Direction + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + public bool IsNullable + { + get { throw new NotImplementedException(); } + } + + public string SourceColumn + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + public DataRowVersion SourceVersion + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + #endregion + } +} diff --git a/tests/src/Appender/AdoNet/Log4NetParameterCollection.cs b/tests/src/Appender/AdoNet/Log4NetParameterCollection.cs index 1c2790c9..e77ea121 100644 --- a/tests/src/Appender/AdoNet/Log4NetParameterCollection.cs +++ b/tests/src/Appender/AdoNet/Log4NetParameterCollection.cs @@ -1,48 +1,48 @@ -using System; -using System.Collections; -using System.Data; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetParameterCollection : CollectionBase, IDataParameterCollection - { - #region AdoNetAppender - - private readonly Hashtable parameterNameToIndex = new Hashtable(); - - protected override void OnInsertComplete(int index, object value) - { - base.OnInsertComplete(index, value); - - IDataParameter param = (IDataParameter)value; - parameterNameToIndex[param.ParameterName] = index; - } - - public int IndexOf(string parameterName) - { - return (int)parameterNameToIndex[parameterName]; - } - - public object this[string parameterName] - { - get { return InnerList[IndexOf(parameterName)]; } - set { InnerList[IndexOf(parameterName)] = value; } - } - - #endregion - - #region Not Implemented - - public void RemoveAt(string parameterName) - { - throw new NotImplementedException(); - } - - public bool Contains(string parameterName) - { - throw new NotImplementedException(); - } - - #endregion - } -} +using System; +using System.Collections; +using System.Data; + +namespace log4net.Tests.Appender.AdoNet +{ + public class Log4NetParameterCollection : CollectionBase, IDataParameterCollection + { + #region AdoNetAppender + + private readonly Hashtable parameterNameToIndex = new Hashtable(); + + protected override void OnInsertComplete(int index, object value) + { + base.OnInsertComplete(index, value); + + IDataParameter param = (IDataParameter)value; + parameterNameToIndex[param.ParameterName] = index; + } + + public int IndexOf(string parameterName) + { + return (int)parameterNameToIndex[parameterName]; + } + + public object this[string parameterName] + { + get { return InnerList[IndexOf(parameterName)]; } + set { InnerList[IndexOf(parameterName)] = value; } + } + + #endregion + + #region Not Implemented + + public void RemoveAt(string parameterName) + { + throw new NotImplementedException(); + } + + public bool Contains(string parameterName) + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/tests/src/Appender/AdoNet/Log4NetTransaction.cs b/tests/src/Appender/AdoNet/Log4NetTransaction.cs index 685f8dc8..0b09ac30 100644 --- a/tests/src/Appender/AdoNet/Log4NetTransaction.cs +++ b/tests/src/Appender/AdoNet/Log4NetTransaction.cs @@ -1,41 +1,41 @@ -using System; -using System.Data; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetTransaction : IDbTransaction - { - #region AdoNetAppender - - public void Commit() - { - // empty - } - - public void Rollback() - { - // empty - } - - #endregion - - #region Not Implemented - - public IDbConnection Connection - { - get { throw new NotImplementedException(); } - } - - public IsolationLevel IsolationLevel - { - get { throw new NotImplementedException(); } - } - - public void Dispose() - { - throw new NotImplementedException(); - } - - #endregion - } -} +using System; +using System.Data; + +namespace log4net.Tests.Appender.AdoNet +{ + public class Log4NetTransaction : IDbTransaction + { + #region AdoNetAppender + + public void Commit() + { + // empty + } + + public void Rollback() + { + // empty + } + + #endregion + + #region Not Implemented + + public IDbConnection Connection + { + get { throw new NotImplementedException(); } + } + + public IsolationLevel IsolationLevel + { + get { throw new NotImplementedException(); } + } + + public void Dispose() + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/tests/src/Appender/AdoNetAppenderTest.cs b/tests/src/Appender/AdoNetAppenderTest.cs index bd78bb4b..9f3ff399 100644 --- a/tests/src/Appender/AdoNetAppenderTest.cs +++ b/tests/src/Appender/AdoNetAppenderTest.cs @@ -1,192 +1,192 @@ -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.Tests.Appender.AdoNet; -using log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.Appender -{ - [TestFixture] - public class AdoNetAppenderTest - { - [Test] - public void NoBufferingTest() - { - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - - AdoNetAppender adoNetAppender = new AdoNetAppender(); - adoNetAppender.BufferSize = -1; - adoNetAppender.ConnectionType = "log4net.Tests.Appender.AdoNet.Log4NetConnection"; - adoNetAppender.ActivateOptions(); - - BasicConfigurator.Configure(rep, adoNetAppender); - - ILog log = LogManager.GetLogger(rep.Name, "NoBufferingTest"); - log.Debug("Message"); - Assert.AreEqual(1, Log4NetCommand.MostRecentInstance.ExecuteNonQueryCount); - } - - [Test] - public void WebsiteExample() - { - XmlDocument log4netConfig = new XmlDocument(); - #region Load log4netConfig - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "); - #endregion - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - ILog log = LogManager.GetLogger(rep.Name, "WebsiteExample"); - log.Debug("Message"); - - IDbCommand command = Log4NetCommand.MostRecentInstance; - - Assert.AreEqual( - "INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)", - command.CommandText); - - Assert.AreEqual(6, command.Parameters.Count); - - IDbDataParameter param = (IDbDataParameter)command.Parameters["@message"]; - Assert.AreEqual("Message", param.Value); - - param = (IDbDataParameter)command.Parameters["@log_level"]; - Assert.AreEqual(Level.Debug.ToString(), param.Value); - - param = (IDbDataParameter)command.Parameters["@logger"]; - Assert.AreEqual("WebsiteExample", param.Value); - - param = (IDbDataParameter)command.Parameters["@exception"]; - Assert.IsEmpty((string)param.Value); - } - - [Test] - public void NullPropertyXmlConfig() - { - XmlDocument log4netConfig = new XmlDocument(); - #region Load log4netConfig - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - - - "); - #endregion - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - ILog log = LogManager.GetLogger(rep.Name, "NullPropertyXmlConfig"); - - log.Debug("Message"); - IDbCommand command = Log4NetCommand.MostRecentInstance; - IDbDataParameter param = (IDbDataParameter)command.Parameters["@productId"]; - Assert.AreNotEqual(SystemInfo.NullText, param.Value); - Assert.AreEqual(DBNull.Value, param.Value); - } - - [Test] - public void NullPropertyProgmaticConfig() - { - AdoNetAppenderParameter productIdParam = new AdoNetAppenderParameter(); - productIdParam.ParameterName = "@productId"; - productIdParam.DbType = DbType.String; - productIdParam.Size = 50; - RawPropertyLayout rawPropertyLayout = new RawPropertyLayout(); - rawPropertyLayout.Key = "ProductId"; - productIdParam.Layout = rawPropertyLayout; - - AdoNetAppender appender = new AdoNetAppender(); - appender.ConnectionType = typeof(Log4NetConnection).FullName; - appender.BufferSize = -1; - appender.CommandText = "INSERT INTO Log ([productId]) VALUES (@productId)"; - appender.AddParameter(productIdParam); - appender.ActivateOptions(); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, appender); - ILog log = LogManager.GetLogger(rep.Name, "NullPropertyProgmaticConfig"); - - log.Debug("Message"); - IDbCommand command = Log4NetCommand.MostRecentInstance; - IDbDataParameter param = (IDbDataParameter)command.Parameters["@productId"]; - Assert.AreNotEqual(SystemInfo.NullText, param.Value); - Assert.AreEqual(DBNull.Value, param.Value); - } - } -} +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.Tests.Appender.AdoNet; +using log4net.Util; +using NUnit.Framework; + +namespace log4net.Tests.Appender +{ + [TestFixture] + public class AdoNetAppenderTest + { + [Test] + public void NoBufferingTest() + { + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + + AdoNetAppender adoNetAppender = new AdoNetAppender(); + adoNetAppender.BufferSize = -1; + adoNetAppender.ConnectionType = "log4net.Tests.Appender.AdoNet.Log4NetConnection"; + adoNetAppender.ActivateOptions(); + + BasicConfigurator.Configure(rep, adoNetAppender); + + ILog log = LogManager.GetLogger(rep.Name, "NoBufferingTest"); + log.Debug("Message"); + Assert.AreEqual(1, Log4NetCommand.MostRecentInstance.ExecuteNonQueryCount); + } + + [Test] + public void WebsiteExample() + { + XmlDocument log4netConfig = new XmlDocument(); + #region Load log4netConfig + log4netConfig.LoadXml(@" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "); + #endregion + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + XmlConfigurator.Configure(rep, log4netConfig["log4net"]); + ILog log = LogManager.GetLogger(rep.Name, "WebsiteExample"); + log.Debug("Message"); + + IDbCommand command = Log4NetCommand.MostRecentInstance; + + Assert.AreEqual( + "INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)", + command.CommandText); + + Assert.AreEqual(6, command.Parameters.Count); + + IDbDataParameter param = (IDbDataParameter)command.Parameters["@message"]; + Assert.AreEqual("Message", param.Value); + + param = (IDbDataParameter)command.Parameters["@log_level"]; + Assert.AreEqual(Level.Debug.ToString(), param.Value); + + param = (IDbDataParameter)command.Parameters["@logger"]; + Assert.AreEqual("WebsiteExample", param.Value); + + param = (IDbDataParameter)command.Parameters["@exception"]; + Assert.IsEmpty((string)param.Value); + } + + [Test] + public void NullPropertyXmlConfig() + { + XmlDocument log4netConfig = new XmlDocument(); + #region Load log4netConfig + log4netConfig.LoadXml(@" + + + + + + + + + + + + + + + + + + + + "); + #endregion + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + XmlConfigurator.Configure(rep, log4netConfig["log4net"]); + ILog log = LogManager.GetLogger(rep.Name, "NullPropertyXmlConfig"); + + log.Debug("Message"); + IDbCommand command = Log4NetCommand.MostRecentInstance; + IDbDataParameter param = (IDbDataParameter)command.Parameters["@productId"]; + Assert.AreNotEqual(SystemInfo.NullText, param.Value); + Assert.AreEqual(DBNull.Value, param.Value); + } + + [Test] + public void NullPropertyProgmaticConfig() + { + AdoNetAppenderParameter productIdParam = new AdoNetAppenderParameter(); + productIdParam.ParameterName = "@productId"; + productIdParam.DbType = DbType.String; + productIdParam.Size = 50; + RawPropertyLayout rawPropertyLayout = new RawPropertyLayout(); + rawPropertyLayout.Key = "ProductId"; + productIdParam.Layout = rawPropertyLayout; + + AdoNetAppender appender = new AdoNetAppender(); + appender.ConnectionType = typeof(Log4NetConnection).FullName; + appender.BufferSize = -1; + appender.CommandText = "INSERT INTO Log ([productId]) VALUES (@productId)"; + appender.AddParameter(productIdParam); + appender.ActivateOptions(); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, appender); + ILog log = LogManager.GetLogger(rep.Name, "NullPropertyProgmaticConfig"); + + log.Debug("Message"); + IDbCommand command = Log4NetCommand.MostRecentInstance; + IDbDataParameter param = (IDbDataParameter)command.Parameters["@productId"]; + Assert.AreNotEqual(SystemInfo.NullText, param.Value); + Assert.AreEqual(DBNull.Value, param.Value); + } + } +} diff --git a/tests/src/Appender/TraceAppenderTest.cs b/tests/src/Appender/TraceAppenderTest.cs index 5e10205d..3977d4b5 100644 --- a/tests/src/Appender/TraceAppenderTest.cs +++ b/tests/src/Appender/TraceAppenderTest.cs @@ -1,89 +1,89 @@ -using System; -using System.Diagnostics; -using log4net.Appender; -using log4net.Config; -using log4net.Layout; -using log4net.Repository; -using NUnit.Framework; - -namespace log4net.Tests.Appender -{ - [TestFixture] - public class TraceAppenderTest - { - [Test] - public void DefaultCategoryTest() - { - CategoryTraceListener categoryTraceListener = new CategoryTraceListener(); - Trace.Listeners.Clear(); - Trace.Listeners.Add(categoryTraceListener); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - - TraceAppender traceAppender = new TraceAppender(); - traceAppender.Layout = new SimpleLayout(); - traceAppender.ActivateOptions(); - - BasicConfigurator.Configure(rep, traceAppender); - - ILog log = LogManager.GetLogger(rep.Name, GetType()); - log.Debug("Message"); - - Assert.AreEqual( - GetType().ToString(), - categoryTraceListener.Category); - } - - [Test] - public void MethodNameCategoryTest() - { - CategoryTraceListener categoryTraceListener = new CategoryTraceListener(); - Trace.Listeners.Clear(); - Trace.Listeners.Add(categoryTraceListener); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - - TraceAppender traceAppender = new TraceAppender(); - PatternLayout methodLayout = new PatternLayout("%method"); - methodLayout.ActivateOptions(); - traceAppender.Category = methodLayout; - traceAppender.Layout = new SimpleLayout(); - traceAppender.ActivateOptions(); - - BasicConfigurator.Configure(rep, traceAppender); - - ILog log = LogManager.GetLogger(rep.Name, GetType()); - log.Debug("Message"); - - Assert.AreEqual( - System.Reflection.MethodInfo.GetCurrentMethod().Name, - categoryTraceListener.Category); - } - } - - public class CategoryTraceListener : TraceListener - { - private string lastCategory; - - public override void Write(string message) - { - // empty - } - - public override void WriteLine(string message) - { - Write(message); - } - - public override void Write(string message, string category) - { - lastCategory = category; - base.Write(message, category); - } - - public string Category - { - get { return lastCategory; } - } - } -} +using System; +using System.Diagnostics; +using log4net.Appender; +using log4net.Config; +using log4net.Layout; +using log4net.Repository; +using NUnit.Framework; + +namespace log4net.Tests.Appender +{ + [TestFixture] + public class TraceAppenderTest + { + [Test] + public void DefaultCategoryTest() + { + CategoryTraceListener categoryTraceListener = new CategoryTraceListener(); + Trace.Listeners.Clear(); + Trace.Listeners.Add(categoryTraceListener); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + + TraceAppender traceAppender = new TraceAppender(); + traceAppender.Layout = new SimpleLayout(); + traceAppender.ActivateOptions(); + + BasicConfigurator.Configure(rep, traceAppender); + + ILog log = LogManager.GetLogger(rep.Name, GetType()); + log.Debug("Message"); + + Assert.AreEqual( + GetType().ToString(), + categoryTraceListener.Category); + } + + [Test] + public void MethodNameCategoryTest() + { + CategoryTraceListener categoryTraceListener = new CategoryTraceListener(); + Trace.Listeners.Clear(); + Trace.Listeners.Add(categoryTraceListener); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + + TraceAppender traceAppender = new TraceAppender(); + PatternLayout methodLayout = new PatternLayout("%method"); + methodLayout.ActivateOptions(); + traceAppender.Category = methodLayout; + traceAppender.Layout = new SimpleLayout(); + traceAppender.ActivateOptions(); + + BasicConfigurator.Configure(rep, traceAppender); + + ILog log = LogManager.GetLogger(rep.Name, GetType()); + log.Debug("Message"); + + Assert.AreEqual( + System.Reflection.MethodInfo.GetCurrentMethod().Name, + categoryTraceListener.Category); + } + } + + public class CategoryTraceListener : TraceListener + { + private string lastCategory; + + public override void Write(string message) + { + // empty + } + + public override void WriteLine(string message) + { + Write(message); + } + + public override void Write(string message, string category) + { + lastCategory = category; + base.Write(message, category); + } + + public string Category + { + get { return lastCategory; } + } + } +} diff --git a/tests/src/Core/EvaluatorTest.cs b/tests/src/Core/EvaluatorTest.cs index f0d08f5a..5f61cb50 100644 --- a/tests/src/Core/EvaluatorTest.cs +++ b/tests/src/Core/EvaluatorTest.cs @@ -1,121 +1,121 @@ -using System; -using log4net.Appender; -using log4net.Core; -using log4net.Tests.Appender; -using NUnit.Framework; - -namespace log4net.Tests.Core -{ - [TestFixture] - public class EvaluatorTest - { - private BufferingForwardingAppender m_bufferingForwardingAppender; - private CountingAppender m_countingAppender; - private Repository.Hierarchy.Hierarchy m_hierarchy; - - [SetUp] - public void SetupRepository() - { - m_hierarchy = new Repository.Hierarchy.Hierarchy(); - - m_countingAppender = new CountingAppender(); - m_countingAppender.ActivateOptions(); - - m_bufferingForwardingAppender = new BufferingForwardingAppender(); - m_bufferingForwardingAppender.AddAppender(m_countingAppender); - - m_bufferingForwardingAppender.BufferSize = 5; - m_bufferingForwardingAppender.ClearFilters(); - m_bufferingForwardingAppender.Fix = FixFlags.Partial; - m_bufferingForwardingAppender.Lossy = false; - m_bufferingForwardingAppender.LossyEvaluator = null; - m_bufferingForwardingAppender.Threshold = Level.All; - } - - [Test] - public void TestLevelEvaluator() - { - m_bufferingForwardingAppender.Evaluator = new LevelEvaluator(Level.Info); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestLevelEvaluator"); - - logger.Log(typeof(EvaluatorTest), Level.Debug, "Debug message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Debug, "Debug message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Info, "Info message logged", null); - Assert.AreEqual(3, m_countingAppender.Counter, "Test 3 events flushed on Info message."); - } - - [Test] - public void TestExceptionEvaluator() - { - m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(ApplicationException), true); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluator"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); - Assert.AreEqual(3, m_countingAppender.Counter, "Test 3 events flushed on ApplicationException message."); - } - - [Test] - public void TestExceptionEvaluatorTriggerOnSubClass() - { - m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(Exception), true); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluatorTriggerOnSubClass"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); - Assert.AreEqual(3, m_countingAppender.Counter, "Test 3 events flushed on ApplicationException message."); - } - - [Test] - public void TestExceptionEvaluatorNoTriggerOnSubClass() - { - m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(Exception), false); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluatorNoTriggerOnSubClass"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 3 events buffered"); - } - - [Test] - public void TestInvalidExceptionEvaluator() - { - // warning: String is not a subclass of Exception - m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(String), false); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluatorNoTriggerOnSubClass"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 3 events buffered"); - } - } -} +using System; +using log4net.Appender; +using log4net.Core; +using log4net.Tests.Appender; +using NUnit.Framework; + +namespace log4net.Tests.Core +{ + [TestFixture] + public class EvaluatorTest + { + private BufferingForwardingAppender m_bufferingForwardingAppender; + private CountingAppender m_countingAppender; + private Repository.Hierarchy.Hierarchy m_hierarchy; + + [SetUp] + public void SetupRepository() + { + m_hierarchy = new Repository.Hierarchy.Hierarchy(); + + m_countingAppender = new CountingAppender(); + m_countingAppender.ActivateOptions(); + + m_bufferingForwardingAppender = new BufferingForwardingAppender(); + m_bufferingForwardingAppender.AddAppender(m_countingAppender); + + m_bufferingForwardingAppender.BufferSize = 5; + m_bufferingForwardingAppender.ClearFilters(); + m_bufferingForwardingAppender.Fix = FixFlags.Partial; + m_bufferingForwardingAppender.Lossy = false; + m_bufferingForwardingAppender.LossyEvaluator = null; + m_bufferingForwardingAppender.Threshold = Level.All; + } + + [Test] + public void TestLevelEvaluator() + { + m_bufferingForwardingAppender.Evaluator = new LevelEvaluator(Level.Info); + m_bufferingForwardingAppender.ActivateOptions(); + log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); + + ILogger logger = m_hierarchy.GetLogger("TestLevelEvaluator"); + + logger.Log(typeof(EvaluatorTest), Level.Debug, "Debug message logged", null); + logger.Log(typeof(EvaluatorTest), Level.Debug, "Debug message logged", null); + Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); + + logger.Log(typeof(EvaluatorTest), Level.Info, "Info message logged", null); + Assert.AreEqual(3, m_countingAppender.Counter, "Test 3 events flushed on Info message."); + } + + [Test] + public void TestExceptionEvaluator() + { + m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(ApplicationException), true); + m_bufferingForwardingAppender.ActivateOptions(); + log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); + + ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluator"); + + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); + Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); + + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); + Assert.AreEqual(3, m_countingAppender.Counter, "Test 3 events flushed on ApplicationException message."); + } + + [Test] + public void TestExceptionEvaluatorTriggerOnSubClass() + { + m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(Exception), true); + m_bufferingForwardingAppender.ActivateOptions(); + log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); + + ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluatorTriggerOnSubClass"); + + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); + Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); + + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); + Assert.AreEqual(3, m_countingAppender.Counter, "Test 3 events flushed on ApplicationException message."); + } + + [Test] + public void TestExceptionEvaluatorNoTriggerOnSubClass() + { + m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(Exception), false); + m_bufferingForwardingAppender.ActivateOptions(); + log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); + + ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluatorNoTriggerOnSubClass"); + + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); + Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); + + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); + Assert.AreEqual(0, m_countingAppender.Counter, "Test 3 events buffered"); + } + + [Test] + public void TestInvalidExceptionEvaluator() + { + // warning: String is not a subclass of Exception + m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(String), false); + m_bufferingForwardingAppender.ActivateOptions(); + log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); + + ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluatorNoTriggerOnSubClass"); + + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); + Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); + + logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); + Assert.AreEqual(0, m_countingAppender.Counter, "Test 3 events buffered"); + } + } +} diff --git a/tests/src/Core/FixingTest.cs b/tests/src/Core/FixingTest.cs index df152dec..fc319655 100644 --- a/tests/src/Core/FixingTest.cs +++ b/tests/src/Core/FixingTest.cs @@ -1,136 +1,136 @@ -#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 System.Threading; - -using log4net.Core; - -using NUnit.Framework; - -namespace log4net.Tests.Core -{ - /// - /// - [TestFixture] - public class FixingTest - { - static FixingTest() - { - LogManager.CreateRepository("Test Repository"); - - // write-once - if (Thread.CurrentThread.Name == null) - { - Thread.CurrentThread.Name = "Log4Net Test thread"; - } - } - - [Test] - public void TestUnfixedValues() - { - LoggingEventData loggingEventData = BuildStandardEventData(); - - // LoggingEvents occur at distinct points in time - LoggingEvent loggingEvent = new LoggingEvent( - loggingEventData.LocationInfo.GetType(), - LogManager.GetRepository("Test Repository"), - loggingEventData.LoggerName, - loggingEventData.Level, - loggingEventData.Message, - new Exception("This is the exception")); - - AssertExpectedLoggingEvent(loggingEvent, loggingEventData); - - Assert.AreEqual(FixFlags.None, loggingEvent.Fix, "Fixed Fields is incorrect"); - } - - [Test] - public void TestAllFixedValues() - { - LoggingEventData loggingEventData = BuildStandardEventData(); - - // LoggingEvents occur at distinct points in time - LoggingEvent loggingEvent = new LoggingEvent( - loggingEventData.LocationInfo.GetType(), - LogManager.GetRepository("Test Repository"), - loggingEventData.LoggerName, - loggingEventData.Level, - loggingEventData.Message, - new Exception("This is the exception")); - - AssertExpectedLoggingEvent(loggingEvent, loggingEventData); - - loggingEvent.Fix = FixFlags.All; - - Assert.AreEqual(FixFlags.LocationInfo | FixFlags.UserName | FixFlags.Identity | FixFlags.Partial | FixFlags.Message | FixFlags.ThreadName | FixFlags.Exception | FixFlags.Domain | FixFlags.Properties, loggingEvent.Fix, "Fixed Fields is incorrect"); - } - - [Test] - public void TestNoFixedValues() - { - LoggingEventData loggingEventData = BuildStandardEventData(); - - // LoggingEvents occur at distinct points in time - LoggingEvent loggingEvent = new LoggingEvent( - loggingEventData.LocationInfo.GetType(), - LogManager.GetRepository("Test Repository"), - loggingEventData.LoggerName, - loggingEventData.Level, - loggingEventData.Message, - new Exception("This is the exception")); - - AssertExpectedLoggingEvent(loggingEvent, loggingEventData); - - loggingEvent.Fix = FixFlags.None; - - Assert.AreEqual(FixFlags.None, loggingEvent.Fix, "Fixed Fields is incorrect"); - } - - private static LoggingEventData BuildStandardEventData() - { - LoggingEventData loggingEventData = new LoggingEventData(); - loggingEventData.LoggerName = typeof(FixingTest).FullName; - loggingEventData.Level = Level.Warn; - loggingEventData.Message = "Logging event works"; - loggingEventData.Domain = "ReallySimpleApp"; - loggingEventData.LocationInfo = new LocationInfo(typeof(FixingTest).Name, "Main", "Class1.cs", "29"); //Completely arbitary - loggingEventData.ThreadName = Thread.CurrentThread.Name; - loggingEventData.TimeStamp = DateTime.Today; - loggingEventData.ExceptionString = "Exception occured here"; - loggingEventData.UserName = "TestUser"; - return loggingEventData; - } - - private static void AssertExpectedLoggingEvent(LoggingEvent loggingEvent, LoggingEventData loggingEventData) - { - Assert.AreEqual("ReallySimpleApp", loggingEventData.Domain, "Domain is incorrect"); - Assert.AreEqual("System.Exception: This is the exception", loggingEvent.GetExceptionString(), "Exception is incorrect"); - Assert.AreEqual(null, loggingEventData.Identity, "Identity is incorrect"); - Assert.AreEqual(Level.Warn, loggingEventData.Level, "Level is incorrect"); - Assert.AreEqual("get_LocationInformation", loggingEvent.LocationInformation.MethodName, "Location Info is incorrect"); - Assert.AreEqual("log4net.Tests.Core.FixingTest", loggingEventData.LoggerName, "LoggerName is incorrect"); - Assert.AreEqual(LogManager.GetRepository("Test Repository"), loggingEvent.Repository, "Repository is incorrect"); - Assert.AreEqual(Thread.CurrentThread.Name, loggingEventData.ThreadName, "ThreadName is incorrect"); - Assert.IsNotNull(loggingEventData.TimeStamp, "TimeStamp is incorrect"); - Assert.AreEqual("TestUser", loggingEventData.UserName, "UserName is incorrect"); - Assert.AreEqual("Logging event works", loggingEvent.RenderedMessage, "Message is incorrect"); - } - } +#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 System.Threading; + +using log4net.Core; + +using NUnit.Framework; + +namespace log4net.Tests.Core +{ + /// + /// + [TestFixture] + public class FixingTest + { + static FixingTest() + { + LogManager.CreateRepository("Test Repository"); + + // write-once + if (Thread.CurrentThread.Name == null) + { + Thread.CurrentThread.Name = "Log4Net Test thread"; + } + } + + [Test] + public void TestUnfixedValues() + { + LoggingEventData loggingEventData = BuildStandardEventData(); + + // LoggingEvents occur at distinct points in time + LoggingEvent loggingEvent = new LoggingEvent( + loggingEventData.LocationInfo.GetType(), + LogManager.GetRepository("Test Repository"), + loggingEventData.LoggerName, + loggingEventData.Level, + loggingEventData.Message, + new Exception("This is the exception")); + + AssertExpectedLoggingEvent(loggingEvent, loggingEventData); + + Assert.AreEqual(FixFlags.None, loggingEvent.Fix, "Fixed Fields is incorrect"); + } + + [Test] + public void TestAllFixedValues() + { + LoggingEventData loggingEventData = BuildStandardEventData(); + + // LoggingEvents occur at distinct points in time + LoggingEvent loggingEvent = new LoggingEvent( + loggingEventData.LocationInfo.GetType(), + LogManager.GetRepository("Test Repository"), + loggingEventData.LoggerName, + loggingEventData.Level, + loggingEventData.Message, + new Exception("This is the exception")); + + AssertExpectedLoggingEvent(loggingEvent, loggingEventData); + + loggingEvent.Fix = FixFlags.All; + + Assert.AreEqual(FixFlags.LocationInfo | FixFlags.UserName | FixFlags.Identity | FixFlags.Partial | FixFlags.Message | FixFlags.ThreadName | FixFlags.Exception | FixFlags.Domain | FixFlags.Properties, loggingEvent.Fix, "Fixed Fields is incorrect"); + } + + [Test] + public void TestNoFixedValues() + { + LoggingEventData loggingEventData = BuildStandardEventData(); + + // LoggingEvents occur at distinct points in time + LoggingEvent loggingEvent = new LoggingEvent( + loggingEventData.LocationInfo.GetType(), + LogManager.GetRepository("Test Repository"), + loggingEventData.LoggerName, + loggingEventData.Level, + loggingEventData.Message, + new Exception("This is the exception")); + + AssertExpectedLoggingEvent(loggingEvent, loggingEventData); + + loggingEvent.Fix = FixFlags.None; + + Assert.AreEqual(FixFlags.None, loggingEvent.Fix, "Fixed Fields is incorrect"); + } + + private static LoggingEventData BuildStandardEventData() + { + LoggingEventData loggingEventData = new LoggingEventData(); + loggingEventData.LoggerName = typeof(FixingTest).FullName; + loggingEventData.Level = Level.Warn; + loggingEventData.Message = "Logging event works"; + loggingEventData.Domain = "ReallySimpleApp"; + loggingEventData.LocationInfo = new LocationInfo(typeof(FixingTest).Name, "Main", "Class1.cs", "29"); //Completely arbitary + loggingEventData.ThreadName = Thread.CurrentThread.Name; + loggingEventData.TimeStamp = DateTime.Today; + loggingEventData.ExceptionString = "Exception occured here"; + loggingEventData.UserName = "TestUser"; + return loggingEventData; + } + + private static void AssertExpectedLoggingEvent(LoggingEvent loggingEvent, LoggingEventData loggingEventData) + { + Assert.AreEqual("ReallySimpleApp", loggingEventData.Domain, "Domain is incorrect"); + Assert.AreEqual("System.Exception: This is the exception", loggingEvent.GetExceptionString(), "Exception is incorrect"); + Assert.AreEqual(null, loggingEventData.Identity, "Identity is incorrect"); + Assert.AreEqual(Level.Warn, loggingEventData.Level, "Level is incorrect"); + Assert.AreEqual("get_LocationInformation", loggingEvent.LocationInformation.MethodName, "Location Info is incorrect"); + Assert.AreEqual("log4net.Tests.Core.FixingTest", loggingEventData.LoggerName, "LoggerName is incorrect"); + Assert.AreEqual(LogManager.GetRepository("Test Repository"), loggingEvent.Repository, "Repository is incorrect"); + Assert.AreEqual(Thread.CurrentThread.Name, loggingEventData.ThreadName, "ThreadName is incorrect"); + Assert.IsNotNull(loggingEventData.TimeStamp, "TimeStamp is incorrect"); + Assert.AreEqual("TestUser", loggingEventData.UserName, "UserName is incorrect"); + Assert.AreEqual("Logging event works", loggingEvent.RenderedMessage, "Message is incorrect"); + } + } } \ No newline at end of file diff --git a/tests/src/Core/StringFormatTest.cs b/tests/src/Core/StringFormatTest.cs index 912e8b44..97729963 100644 --- a/tests/src/Core/StringFormatTest.cs +++ b/tests/src/Core/StringFormatTest.cs @@ -1,689 +1,689 @@ -#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 System.Globalization; - -using log4net.Config; -using log4net.Core; -using log4net.Layout; -using log4net.Repository; -using log4net.Tests.Appender; -using log4net.Tests.Layout; - -using NUnit.Framework; - -namespace log4net.Tests.Core -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class StringFormatTest - { - [Test] - public void TestFormatString() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestFormatString"); - - // *** - log1.Info("TestMessage"); - Assert.AreEqual("TestMessage", stringAppender.GetString(), "Test simple INFO event"); - stringAppender.Reset(); - - - // *** - log1.DebugFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted DEBUG event"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted INFO event"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted WARN event"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted ERROR event"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted FATAL event"); - stringAppender.Reset(); - - - // *** - log1.InfoFormat("Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("Before Middle After End", stringAppender.GetString(), "Test simple formatted INFO event 2"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("IGNORE THIS WARNING - EXCEPTION EXPECTED Before {0} After {1} {2}", "Middle", "End"); - Assert.AreEqual(STRING_FORMAT_ERROR, stringAppender.GetString(), "Test formatting error"); - stringAppender.Reset(); - } - - private const string STRING_FORMAT_ERROR = "Exception during StringFormat: Index (zero based) must be greater than or equal to zero and less than the size of the argument list. IGNORE THIS WARNING - EXCEPTION EXPECTED Before {0} After {1} {2}{Middle, End}"; - - - [Test] - public void TestLogFormatApi_Debug() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Debug"); - - // *** - log1.Debug("TestMessage"); - Assert.AreEqual("DEBUG:TestMessage", stringAppender.GetString(), "Test simple DEBUG event 1"); - stringAppender.Reset(); - - // *** - log1.Debug("TestMessage", null); - Assert.AreEqual("DEBUG:TestMessage", stringAppender.GetString(), "Test simple DEBUG event 2"); - stringAppender.Reset(); - - // *** - log1.Debug("TestMessage", new Exception("Exception message")); - Assert.AreEqual("DEBUG:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple DEBUG event 3"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}", "1"); - Assert.AreEqual("DEBUG:a1", stringAppender.GetString(), "Test formatted DEBUG event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("DEBUG:a1b2", stringAppender.GetString(), "Test formatted DEBUG event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("DEBUG:a1b2c3", stringAppender.GetString(), "Test formatted DEBUG event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.DebugFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("DEBUG:aQbWcEdReTf", stringAppender.GetString(), "Test formatted DEBUG event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.DebugFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("DEBUG:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.DebugFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("DEBUG:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoDebug() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Info; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Debug"); - - // *** - log1.Debug("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple DEBUG event 1"); - stringAppender.Reset(); - - // *** - log1.Debug("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple DEBUG event 2"); - stringAppender.Reset(); - - // *** - log1.Debug("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple DEBUG event 3"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.DebugFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.DebugFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.DebugFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - - [Test] - public void TestLogFormatApi_Info() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Info"); - - // *** - log1.Info("TestMessage"); - Assert.AreEqual("INFO:TestMessage", stringAppender.GetString(), "Test simple INFO event 1"); - stringAppender.Reset(); - - // *** - log1.Info("TestMessage", null); - Assert.AreEqual("INFO:TestMessage", stringAppender.GetString(), "Test simple INFO event 2"); - stringAppender.Reset(); - - // *** - log1.Info("TestMessage", new Exception("Exception message")); - Assert.AreEqual("INFO:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple INFO event 3"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}", "1"); - Assert.AreEqual("INFO:a1", stringAppender.GetString(), "Test formatted INFO event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("INFO:a1b2", stringAppender.GetString(), "Test formatted INFO event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("INFO:a1b2c3", stringAppender.GetString(), "Test formatted INFO event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.InfoFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("INFO:aQbWcEdReTf", stringAppender.GetString(), "Test formatted INFO event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.InfoFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("INFO:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.InfoFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("INFO:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoInfo() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Warn; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Info"); - - // *** - log1.Info("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple INFO event 1"); - stringAppender.Reset(); - - // *** - log1.Info("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple INFO event 2"); - stringAppender.Reset(); - - // *** - log1.Info("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple INFO event 3"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.InfoFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.InfoFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.InfoFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - - [Test] - public void TestLogFormatApi_Warn() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Warn"); - - // *** - log1.Warn("TestMessage"); - Assert.AreEqual("WARN:TestMessage", stringAppender.GetString(), "Test simple WARN event 1"); - stringAppender.Reset(); - - // *** - log1.Warn("TestMessage", null); - Assert.AreEqual("WARN:TestMessage", stringAppender.GetString(), "Test simple WARN event 2"); - stringAppender.Reset(); - - // *** - log1.Warn("TestMessage", new Exception("Exception message")); - Assert.AreEqual("WARN:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple WARN event 3"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}", "1"); - Assert.AreEqual("WARN:a1", stringAppender.GetString(), "Test formatted WARN event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("WARN:a1b2", stringAppender.GetString(), "Test formatted WARN event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("WARN:a1b2c3", stringAppender.GetString(), "Test formatted WARN event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.WarnFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("WARN:aQbWcEdReTf", stringAppender.GetString(), "Test formatted WARN event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.WarnFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("WARN:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.WarnFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("WARN:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoWarn() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Error; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Warn"); - - // *** - log1.Warn("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple WARN event 1"); - stringAppender.Reset(); - - // *** - log1.Warn("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple WARN event 2"); - stringAppender.Reset(); - - // *** - log1.Warn("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple WARN event 3"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.WarnFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.WarnFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.WarnFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - - [Test] - public void TestLogFormatApi_Error() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Error"); - - // *** - log1.Error("TestMessage"); - Assert.AreEqual("ERROR:TestMessage", stringAppender.GetString(), "Test simple ERROR event 1"); - stringAppender.Reset(); - - // *** - log1.Error("TestMessage", null); - Assert.AreEqual("ERROR:TestMessage", stringAppender.GetString(), "Test simple ERROR event 2"); - stringAppender.Reset(); - - // *** - log1.Error("TestMessage", new Exception("Exception message")); - Assert.AreEqual("ERROR:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple ERROR event 3"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}", "1"); - Assert.AreEqual("ERROR:a1", stringAppender.GetString(), "Test formatted ERROR event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("ERROR:a1b2", stringAppender.GetString(), "Test formatted ERROR event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("ERROR:a1b2c3", stringAppender.GetString(), "Test formatted ERROR event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.ErrorFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("ERROR:aQbWcEdReTf", stringAppender.GetString(), "Test formatted ERROR event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("ERROR:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("ERROR:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoError() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Fatal; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Error"); - - // *** - log1.Error("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple ERROR event 1"); - stringAppender.Reset(); - - // *** - log1.Error("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple ERROR event 2"); - stringAppender.Reset(); - - // *** - log1.Error("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple ERROR event 3"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.ErrorFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - - [Test] - public void TestLogFormatApi_Fatal() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Fatal"); - - // *** - log1.Fatal("TestMessage"); - Assert.AreEqual("FATAL:TestMessage", stringAppender.GetString(), "Test simple FATAL event 1"); - stringAppender.Reset(); - - // *** - log1.Fatal("TestMessage", null); - Assert.AreEqual("FATAL:TestMessage", stringAppender.GetString(), "Test simple FATAL event 2"); - stringAppender.Reset(); - - // *** - log1.Fatal("TestMessage", new Exception("Exception message")); - Assert.AreEqual("FATAL:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple FATAL event 3"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}", "1"); - Assert.AreEqual("FATAL:a1", stringAppender.GetString(), "Test formatted FATAL event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("FATAL:a1b2", stringAppender.GetString(), "Test formatted FATAL event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("FATAL:a1b2c3", stringAppender.GetString(), "Test formatted FATAL event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.FatalFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("FATAL:aQbWcEdReTf", stringAppender.GetString(), "Test formatted FATAL event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.FatalFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("FATAL:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.FatalFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("FATAL:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoFatal() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Off; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Fatal"); - - // *** - log1.Fatal("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple FATAL event 1"); - stringAppender.Reset(); - - // *** - log1.Fatal("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple FATAL event 2"); - stringAppender.Reset(); - - // *** - log1.Fatal("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple FATAL event 3"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.FatalFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.FatalFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.FatalFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - } +#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 System.Globalization; + +using log4net.Config; +using log4net.Core; +using log4net.Layout; +using log4net.Repository; +using log4net.Tests.Appender; +using log4net.Tests.Layout; + +using NUnit.Framework; + +namespace log4net.Tests.Core +{ + /// + /// Used for internal unit testing the class. + /// + /// + /// Used for internal unit testing the class. + /// + [TestFixture] + public class StringFormatTest + { + [Test] + public void TestFormatString() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Layout = new PatternLayout("%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestFormatString"); + + // *** + log1.Info("TestMessage"); + Assert.AreEqual("TestMessage", stringAppender.GetString(), "Test simple INFO event"); + stringAppender.Reset(); + + + // *** + log1.DebugFormat("Before {0} After", "Middle"); + Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted DEBUG event"); + stringAppender.Reset(); + + // *** + log1.InfoFormat("Before {0} After", "Middle"); + Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted INFO event"); + stringAppender.Reset(); + + // *** + log1.WarnFormat("Before {0} After", "Middle"); + Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted WARN event"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat("Before {0} After", "Middle"); + Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted ERROR event"); + stringAppender.Reset(); + + // *** + log1.FatalFormat("Before {0} After", "Middle"); + Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted FATAL event"); + stringAppender.Reset(); + + + // *** + log1.InfoFormat("Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("Before Middle After End", stringAppender.GetString(), "Test simple formatted INFO event 2"); + stringAppender.Reset(); + + // *** + log1.InfoFormat("IGNORE THIS WARNING - EXCEPTION EXPECTED Before {0} After {1} {2}", "Middle", "End"); + Assert.AreEqual(STRING_FORMAT_ERROR, stringAppender.GetString(), "Test formatting error"); + stringAppender.Reset(); + } + + private const string STRING_FORMAT_ERROR = "Exception during StringFormat: Index (zero based) must be greater than or equal to zero and less than the size of the argument list. IGNORE THIS WARNING - EXCEPTION EXPECTED Before {0} After {1} {2}{Middle, End}"; + + + [Test] + public void TestLogFormatApi_Debug() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Debug"); + + // *** + log1.Debug("TestMessage"); + Assert.AreEqual("DEBUG:TestMessage", stringAppender.GetString(), "Test simple DEBUG event 1"); + stringAppender.Reset(); + + // *** + log1.Debug("TestMessage", null); + Assert.AreEqual("DEBUG:TestMessage", stringAppender.GetString(), "Test simple DEBUG event 2"); + stringAppender.Reset(); + + // *** + log1.Debug("TestMessage", new Exception("Exception message")); + Assert.AreEqual("DEBUG:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple DEBUG event 3"); + stringAppender.Reset(); + + // *** + log1.DebugFormat("a{0}", "1"); + Assert.AreEqual("DEBUG:a1", stringAppender.GetString(), "Test formatted DEBUG event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.DebugFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("DEBUG:a1b2", stringAppender.GetString(), "Test formatted DEBUG event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.DebugFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("DEBUG:a1b2c3", stringAppender.GetString(), "Test formatted DEBUG event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.DebugFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("DEBUG:aQbWcEdReTf", stringAppender.GetString(), "Test formatted DEBUG event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.DebugFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("DEBUG:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.DebugFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("DEBUG:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + + [Test] + public void TestLogFormatApi_NoDebug() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Threshold = Level.Info; + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Debug"); + + // *** + log1.Debug("TestMessage"); + Assert.AreEqual("", stringAppender.GetString(), "Test simple DEBUG event 1"); + stringAppender.Reset(); + + // *** + log1.Debug("TestMessage", null); + Assert.AreEqual("", stringAppender.GetString(), "Test simple DEBUG event 2"); + stringAppender.Reset(); + + // *** + log1.Debug("TestMessage", new Exception("Exception message")); + Assert.AreEqual("", stringAppender.GetString(), "Test simple DEBUG event 3"); + stringAppender.Reset(); + + // *** + log1.DebugFormat("a{0}", "1"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.DebugFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.DebugFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.DebugFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.DebugFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.DebugFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + + + [Test] + public void TestLogFormatApi_Info() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Info"); + + // *** + log1.Info("TestMessage"); + Assert.AreEqual("INFO:TestMessage", stringAppender.GetString(), "Test simple INFO event 1"); + stringAppender.Reset(); + + // *** + log1.Info("TestMessage", null); + Assert.AreEqual("INFO:TestMessage", stringAppender.GetString(), "Test simple INFO event 2"); + stringAppender.Reset(); + + // *** + log1.Info("TestMessage", new Exception("Exception message")); + Assert.AreEqual("INFO:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple INFO event 3"); + stringAppender.Reset(); + + // *** + log1.InfoFormat("a{0}", "1"); + Assert.AreEqual("INFO:a1", stringAppender.GetString(), "Test formatted INFO event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.InfoFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("INFO:a1b2", stringAppender.GetString(), "Test formatted INFO event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.InfoFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("INFO:a1b2c3", stringAppender.GetString(), "Test formatted INFO event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.InfoFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("INFO:aQbWcEdReTf", stringAppender.GetString(), "Test formatted INFO event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.InfoFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("INFO:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.InfoFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("INFO:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + + [Test] + public void TestLogFormatApi_NoInfo() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Threshold = Level.Warn; + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Info"); + + // *** + log1.Info("TestMessage"); + Assert.AreEqual("", stringAppender.GetString(), "Test simple INFO event 1"); + stringAppender.Reset(); + + // *** + log1.Info("TestMessage", null); + Assert.AreEqual("", stringAppender.GetString(), "Test simple INFO event 2"); + stringAppender.Reset(); + + // *** + log1.Info("TestMessage", new Exception("Exception message")); + Assert.AreEqual("", stringAppender.GetString(), "Test simple INFO event 3"); + stringAppender.Reset(); + + // *** + log1.InfoFormat("a{0}", "1"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.InfoFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.InfoFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.InfoFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.InfoFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.InfoFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + + + [Test] + public void TestLogFormatApi_Warn() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Warn"); + + // *** + log1.Warn("TestMessage"); + Assert.AreEqual("WARN:TestMessage", stringAppender.GetString(), "Test simple WARN event 1"); + stringAppender.Reset(); + + // *** + log1.Warn("TestMessage", null); + Assert.AreEqual("WARN:TestMessage", stringAppender.GetString(), "Test simple WARN event 2"); + stringAppender.Reset(); + + // *** + log1.Warn("TestMessage", new Exception("Exception message")); + Assert.AreEqual("WARN:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple WARN event 3"); + stringAppender.Reset(); + + // *** + log1.WarnFormat("a{0}", "1"); + Assert.AreEqual("WARN:a1", stringAppender.GetString(), "Test formatted WARN event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.WarnFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("WARN:a1b2", stringAppender.GetString(), "Test formatted WARN event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.WarnFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("WARN:a1b2c3", stringAppender.GetString(), "Test formatted WARN event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.WarnFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("WARN:aQbWcEdReTf", stringAppender.GetString(), "Test formatted WARN event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.WarnFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("WARN:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.WarnFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("WARN:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + + [Test] + public void TestLogFormatApi_NoWarn() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Threshold = Level.Error; + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Warn"); + + // *** + log1.Warn("TestMessage"); + Assert.AreEqual("", stringAppender.GetString(), "Test simple WARN event 1"); + stringAppender.Reset(); + + // *** + log1.Warn("TestMessage", null); + Assert.AreEqual("", stringAppender.GetString(), "Test simple WARN event 2"); + stringAppender.Reset(); + + // *** + log1.Warn("TestMessage", new Exception("Exception message")); + Assert.AreEqual("", stringAppender.GetString(), "Test simple WARN event 3"); + stringAppender.Reset(); + + // *** + log1.WarnFormat("a{0}", "1"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.WarnFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.WarnFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.WarnFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.WarnFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.WarnFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + + + [Test] + public void TestLogFormatApi_Error() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Error"); + + // *** + log1.Error("TestMessage"); + Assert.AreEqual("ERROR:TestMessage", stringAppender.GetString(), "Test simple ERROR event 1"); + stringAppender.Reset(); + + // *** + log1.Error("TestMessage", null); + Assert.AreEqual("ERROR:TestMessage", stringAppender.GetString(), "Test simple ERROR event 2"); + stringAppender.Reset(); + + // *** + log1.Error("TestMessage", new Exception("Exception message")); + Assert.AreEqual("ERROR:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple ERROR event 3"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat("a{0}", "1"); + Assert.AreEqual("ERROR:a1", stringAppender.GetString(), "Test formatted ERROR event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("ERROR:a1b2", stringAppender.GetString(), "Test formatted ERROR event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("ERROR:a1b2c3", stringAppender.GetString(), "Test formatted ERROR event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.ErrorFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("ERROR:aQbWcEdReTf", stringAppender.GetString(), "Test formatted ERROR event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("ERROR:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("ERROR:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + + [Test] + public void TestLogFormatApi_NoError() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Threshold = Level.Fatal; + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Error"); + + // *** + log1.Error("TestMessage"); + Assert.AreEqual("", stringAppender.GetString(), "Test simple ERROR event 1"); + stringAppender.Reset(); + + // *** + log1.Error("TestMessage", null); + Assert.AreEqual("", stringAppender.GetString(), "Test simple ERROR event 2"); + stringAppender.Reset(); + + // *** + log1.Error("TestMessage", new Exception("Exception message")); + Assert.AreEqual("", stringAppender.GetString(), "Test simple ERROR event 3"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat("a{0}", "1"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.ErrorFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.ErrorFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + + + [Test] + public void TestLogFormatApi_Fatal() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Fatal"); + + // *** + log1.Fatal("TestMessage"); + Assert.AreEqual("FATAL:TestMessage", stringAppender.GetString(), "Test simple FATAL event 1"); + stringAppender.Reset(); + + // *** + log1.Fatal("TestMessage", null); + Assert.AreEqual("FATAL:TestMessage", stringAppender.GetString(), "Test simple FATAL event 2"); + stringAppender.Reset(); + + // *** + log1.Fatal("TestMessage", new Exception("Exception message")); + Assert.AreEqual("FATAL:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple FATAL event 3"); + stringAppender.Reset(); + + // *** + log1.FatalFormat("a{0}", "1"); + Assert.AreEqual("FATAL:a1", stringAppender.GetString(), "Test formatted FATAL event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.FatalFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("FATAL:a1b2", stringAppender.GetString(), "Test formatted FATAL event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.FatalFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("FATAL:a1b2c3", stringAppender.GetString(), "Test formatted FATAL event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.FatalFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("FATAL:aQbWcEdReTf", stringAppender.GetString(), "Test formatted FATAL event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.FatalFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("FATAL:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.FatalFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("FATAL:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + + [Test] + public void TestLogFormatApi_NoFatal() + { + StringAppender stringAppender = new StringAppender(); + stringAppender.Threshold = Level.Off; + stringAppender.Layout = new PatternLayout("%level:%message"); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + + ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Fatal"); + + // *** + log1.Fatal("TestMessage"); + Assert.AreEqual("", stringAppender.GetString(), "Test simple FATAL event 1"); + stringAppender.Reset(); + + // *** + log1.Fatal("TestMessage", null); + Assert.AreEqual("", stringAppender.GetString(), "Test simple FATAL event 2"); + stringAppender.Reset(); + + // *** + log1.Fatal("TestMessage", new Exception("Exception message")); + Assert.AreEqual("", stringAppender.GetString(), "Test simple FATAL event 3"); + stringAppender.Reset(); + + // *** + log1.FatalFormat("a{0}", "1"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 1 parm"); + stringAppender.Reset(); + + // *** + log1.FatalFormat("a{0}b{1}", "1", "2"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 2 parm"); + stringAppender.Reset(); + + // *** + log1.FatalFormat("a{0}b{1}c{2}", "1", "2", "3"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 3 parm"); + stringAppender.Reset(); + + + // *** + log1.FatalFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 5 parms (only 4 used)"); + stringAppender.Reset(); + + // *** + log1.FatalFormat(null, "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); + stringAppender.Reset(); + + // *** + log1.FatalFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); + Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); + stringAppender.Reset(); + } + } } \ No newline at end of file diff --git a/tests/src/Filter/FilterTest.cs b/tests/src/Filter/FilterTest.cs index 6d9e1d50..31900d62 100644 --- a/tests/src/Filter/FilterTest.cs +++ b/tests/src/Filter/FilterTest.cs @@ -1,90 +1,90 @@ -#if NET_2_0 -using System; -using System.Collections.Generic; -using System.Xml; -using log4net.Appender; -using log4net.Config; -using log4net.Core; -using log4net.Filter; -using log4net.Repository; -using NUnit.Framework; - -namespace log4net.Tests.Filter -{ - [TestFixture] - public class FilterTest - { - [Test] - public void FilterConfigurationTest() - { - XmlDocument log4netConfig = new XmlDocument(); - #region Load log4netConfig - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - "); - #endregion - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - IAppender[] appenders = LogManager.GetRepository(rep.Name).GetAppenders(); - Assert.IsTrue(appenders.Length == 1); - - IAppender appender = Array.Find(appenders, a => a.Name == "MemoryAppender"); - Assert.IsNotNull(appender); - - MultiplePropertyFilter multiplePropertyFilter = - ((AppenderSkeleton)appender).FilterHead as MultiplePropertyFilter; - - var conditions = multiplePropertyFilter.GetConditions(); - Assert.AreEqual(2, conditions.Length); - Assert.AreEqual("ABC", conditions[0].Key); - Assert.AreEqual("123", conditions[0].StringToMatch); - Assert.AreEqual("DEF", conditions[1].Key); - Assert.AreEqual("456", conditions[1].StringToMatch); - } - } - - public class MultiplePropertyFilter : FilterSkeleton - { - private readonly List _conditions = new List(); - - public override FilterDecision Decide(LoggingEvent loggingEvent) - { - return FilterDecision.Accept; - } - - public Condition[] GetConditions() - { - return _conditions.ToArray(); - } - - public void AddCondition(Condition condition) - { - _conditions.Add(condition); - } - - public class Condition - { - public string Key { get; set; } - public string StringToMatch { get; set; } - } - } -} -#endif +#if NET_2_0 +using System; +using System.Collections.Generic; +using System.Xml; +using log4net.Appender; +using log4net.Config; +using log4net.Core; +using log4net.Filter; +using log4net.Repository; +using NUnit.Framework; + +namespace log4net.Tests.Filter +{ + [TestFixture] + public class FilterTest + { + [Test] + public void FilterConfigurationTest() + { + XmlDocument log4netConfig = new XmlDocument(); + #region Load log4netConfig + log4netConfig.LoadXml(@" + + + + + + + + + + + + + + + + + + "); + #endregion + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + XmlConfigurator.Configure(rep, log4netConfig["log4net"]); + + IAppender[] appenders = LogManager.GetRepository(rep.Name).GetAppenders(); + Assert.IsTrue(appenders.Length == 1); + + IAppender appender = Array.Find(appenders, a => a.Name == "MemoryAppender"); + Assert.IsNotNull(appender); + + MultiplePropertyFilter multiplePropertyFilter = + ((AppenderSkeleton)appender).FilterHead as MultiplePropertyFilter; + + var conditions = multiplePropertyFilter.GetConditions(); + Assert.AreEqual(2, conditions.Length); + Assert.AreEqual("ABC", conditions[0].Key); + Assert.AreEqual("123", conditions[0].StringToMatch); + Assert.AreEqual("DEF", conditions[1].Key); + Assert.AreEqual("456", conditions[1].StringToMatch); + } + } + + public class MultiplePropertyFilter : FilterSkeleton + { + private readonly List _conditions = new List(); + + public override FilterDecision Decide(LoggingEvent loggingEvent) + { + return FilterDecision.Accept; + } + + public Condition[] GetConditions() + { + return _conditions.ToArray(); + } + + public void AddCondition(Condition condition) + { + _conditions.Add(condition); + } + + public class Condition + { + public string Key { get; set; } + public string StringToMatch { get; set; } + } + } +} +#endif diff --git a/tests/src/Hierarchy/Hierarchy.cs b/tests/src/Hierarchy/Hierarchy.cs index 1737a892..be834fc1 100644 --- a/tests/src/Hierarchy/Hierarchy.cs +++ b/tests/src/Hierarchy/Hierarchy.cs @@ -1,76 +1,76 @@ -using System; -using System.Xml; -using log4net.Config; -using log4net.Core; -using log4net.Repository; -using log4net.Repository.Hierarchy; -using log4net.Tests.Appender; -using NUnit.Framework; - -namespace log4net.Tests.Hierarchy -{ - [TestFixture] - public class Hierarchy - { - [Test] - public void SetRepositoryPropertiesInConfigFile() - { - // LOG4NET-53: Allow repository properties to be set in the config file - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - Assert.AreEqual("4", rep.Properties["two-plus-two"]); - Assert.IsNull(rep.Properties["one-plus-one"]); - } - - [Test] - public void AddingMultipleAppenders() - { - CountingAppender alpha = new CountingAppender(); - CountingAppender beta = new CountingAppender(); - - Repository.Hierarchy.Hierarchy hierarchy = - (Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); - hierarchy.Root.AddAppender(alpha); - hierarchy.Root.AddAppender(beta); - hierarchy.Configured = true; - - ILog log = LogManager.GetLogger(GetType()); - log.Debug("Hello World"); - - Assert.AreEqual(1, alpha.Counter); - Assert.AreEqual(1, beta.Counter); - } - - [Test] - public void AddingMultipleAppenders2() - { - CountingAppender alpha = new CountingAppender(); - CountingAppender beta = new CountingAppender(); - - BasicConfigurator.Configure(alpha, beta); - - ILog log = LogManager.GetLogger(GetType()); - log.Debug("Hello World"); - - Assert.AreEqual(1, alpha.Counter); - Assert.AreEqual(1, beta.Counter); - } - } -} +using System; +using System.Xml; +using log4net.Config; +using log4net.Core; +using log4net.Repository; +using log4net.Repository.Hierarchy; +using log4net.Tests.Appender; +using NUnit.Framework; + +namespace log4net.Tests.Hierarchy +{ + [TestFixture] + public class Hierarchy + { + [Test] + public void SetRepositoryPropertiesInConfigFile() + { + // LOG4NET-53: Allow repository properties to be set in the config file + XmlDocument log4netConfig = new XmlDocument(); + log4netConfig.LoadXml(@" + + + + + + + + + + + + + "); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + XmlConfigurator.Configure(rep, log4netConfig["log4net"]); + + Assert.AreEqual("4", rep.Properties["two-plus-two"]); + Assert.IsNull(rep.Properties["one-plus-one"]); + } + + [Test] + public void AddingMultipleAppenders() + { + CountingAppender alpha = new CountingAppender(); + CountingAppender beta = new CountingAppender(); + + Repository.Hierarchy.Hierarchy hierarchy = + (Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); + hierarchy.Root.AddAppender(alpha); + hierarchy.Root.AddAppender(beta); + hierarchy.Configured = true; + + ILog log = LogManager.GetLogger(GetType()); + log.Debug("Hello World"); + + Assert.AreEqual(1, alpha.Counter); + Assert.AreEqual(1, beta.Counter); + } + + [Test] + public void AddingMultipleAppenders2() + { + CountingAppender alpha = new CountingAppender(); + CountingAppender beta = new CountingAppender(); + + BasicConfigurator.Configure(alpha, beta); + + ILog log = LogManager.GetLogger(GetType()); + log.Debug("Hello World"); + + Assert.AreEqual(1, alpha.Counter); + Assert.AreEqual(1, beta.Counter); + } + } +} diff --git a/tests/src/LoggerRepository/ConfigurationMessages.cs b/tests/src/LoggerRepository/ConfigurationMessages.cs index 6eca2be2..67afe36e 100644 --- a/tests/src/LoggerRepository/ConfigurationMessages.cs +++ b/tests/src/LoggerRepository/ConfigurationMessages.cs @@ -1,74 +1,74 @@ -using System; -using System.Collections; -using System.Xml; -using log4net.Appender; -using log4net.Config; -using log4net.Core; -using log4net.Repository; -using log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.LoggerRepository -{ - [TestFixture] - public class ConfigurationMessages - { - [Test] - public void ConfigurationMessagesTest() - { - LogLog.EmitInternalMessages = false; - LogLog.InternalDebugging = true; - - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - rep.ConfigurationChanged += new LoggerRepositoryConfigurationChangedEventHandler(rep_ConfigurationChanged); - - ICollection configurationMessages = XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - Assert.IsTrue(configurationMessages.Count > 0); - } - - static void rep_ConfigurationChanged(object sender, EventArgs e) - { - ConfigurationChangedEventArgs configChanged = (ConfigurationChangedEventArgs)e; - - Assert.IsTrue(configChanged.ConfigurationMessages.Count > 0); - } - } - - public class LogLogAppender : AppenderSkeleton - { - private readonly static Type declaringType = typeof(LogLogAppender); - - public override void ActivateOptions() - { - LogLog.Debug(declaringType, "Debug - Activating options..."); - LogLog.Warn(declaringType, "Warn - Activating options..."); - LogLog.Error(declaringType, "Error - Activating options..."); - - base.ActivateOptions(); - } - - protected override void Append(LoggingEvent loggingEvent) - { - LogLog.Debug(declaringType, "Debug - Appending..."); - LogLog.Warn(declaringType, "Warn - Appending..."); - LogLog.Error(declaringType, "Error - Appending..."); - } - } +using System; +using System.Collections; +using System.Xml; +using log4net.Appender; +using log4net.Config; +using log4net.Core; +using log4net.Repository; +using log4net.Util; +using NUnit.Framework; + +namespace log4net.Tests.LoggerRepository +{ + [TestFixture] + public class ConfigurationMessages + { + [Test] + public void ConfigurationMessagesTest() + { + LogLog.EmitInternalMessages = false; + LogLog.InternalDebugging = true; + + XmlDocument log4netConfig = new XmlDocument(); + log4netConfig.LoadXml(@" + + + + + + + + + + + + + "); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + rep.ConfigurationChanged += new LoggerRepositoryConfigurationChangedEventHandler(rep_ConfigurationChanged); + + ICollection configurationMessages = XmlConfigurator.Configure(rep, log4netConfig["log4net"]); + + Assert.IsTrue(configurationMessages.Count > 0); + } + + static void rep_ConfigurationChanged(object sender, EventArgs e) + { + ConfigurationChangedEventArgs configChanged = (ConfigurationChangedEventArgs)e; + + Assert.IsTrue(configChanged.ConfigurationMessages.Count > 0); + } + } + + public class LogLogAppender : AppenderSkeleton + { + private readonly static Type declaringType = typeof(LogLogAppender); + + public override void ActivateOptions() + { + LogLog.Debug(declaringType, "Debug - Activating options..."); + LogLog.Warn(declaringType, "Warn - Activating options..."); + LogLog.Error(declaringType, "Error - Activating options..."); + + base.ActivateOptions(); + } + + protected override void Append(LoggingEvent loggingEvent) + { + LogLog.Debug(declaringType, "Debug - Appending..."); + LogLog.Warn(declaringType, "Warn - Appending..."); + LogLog.Error(declaringType, "Error - Appending..."); + } + } } \ No newline at end of file diff --git a/tests/src/Util/EnvironmentPatternConverterTest.cs b/tests/src/Util/EnvironmentPatternConverterTest.cs index 78505bb3..4995fbee 100644 --- a/tests/src/Util/EnvironmentPatternConverterTest.cs +++ b/tests/src/Util/EnvironmentPatternConverterTest.cs @@ -1,91 +1,91 @@ -// .NET Compact Framework 1.0 has no support for Environment.GetEnvironmentVariable() -// .NET Framework version 1.0 / 1.1 do not have support for SetEnvironmentVariable which is used in these tests. -#if !NETCF && NET_2_0 - -using System; -using System.IO; -using System.Text; -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - [TestFixture] - public class EnvironmentPatternConverterTest - { - private const string ENVIRONMENT_VARIABLE_NAME = "LOG4NET_TEST_TEMP"; - const string SYSTEM_LEVEL_VALUE = "SystemLevelEnvironmentValue"; - const string USER_LEVEL_VALUE = "UserLevelEnvironmentValue"; - const string PROCESS_LEVEL_VALUE = "ProcessLevelEnvironmentValue"; - - [Test] - public void SystemLevelEnvironmentVariable() - { - EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, SYSTEM_LEVEL_VALUE, EnvironmentVariableTarget.Machine); - - converter.Option = ENVIRONMENT_VARIABLE_NAME; - - StringWriter sw = new StringWriter(); - converter.Convert(sw, null); - - Assert.AreEqual(SYSTEM_LEVEL_VALUE, sw.ToString(), "System level environment variable not expended correctly."); - - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null, EnvironmentVariableTarget.Machine); - } - - [Test] - public void UserLevelEnvironmentVariable() - { - EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, USER_LEVEL_VALUE, EnvironmentVariableTarget.User); - - converter.Option = ENVIRONMENT_VARIABLE_NAME; - - StringWriter sw = new StringWriter(); - converter.Convert(sw, null); - - Assert.AreEqual(USER_LEVEL_VALUE, sw.ToString(), "User level environment variable not expended correctly."); - - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null, EnvironmentVariableTarget.User); - } - - [Test] - public void ProcessLevelEnvironmentVariable() - { - EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, PROCESS_LEVEL_VALUE); - - converter.Option = ENVIRONMENT_VARIABLE_NAME; - - StringWriter sw = new StringWriter(); - converter.Convert(sw, null); - - Assert.AreEqual(PROCESS_LEVEL_VALUE, sw.ToString(), "Process level environment variable not expended correctly."); - - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null); - } - - private class EnvironmentPatternConverter - { - private object target = null; - - public EnvironmentPatternConverter() - { - target = Utils.CreateInstance("log4net.Util.PatternStringConverters.EnvironmentPatternConverter,log4net"); - } - - public string Option - { - get { return Utils.GetProperty(target, "Option") as string; } - set { Utils.SetProperty(target, "Option", value); } - } - - public void Convert(TextWriter writer, object state) - { - Utils.InvokeMethod(target, "Convert", writer, state); - } - } - } -} - -#endif +// .NET Compact Framework 1.0 has no support for Environment.GetEnvironmentVariable() +// .NET Framework version 1.0 / 1.1 do not have support for SetEnvironmentVariable which is used in these tests. +#if !NETCF && NET_2_0 + +using System; +using System.IO; +using System.Text; +using NUnit.Framework; + +namespace log4net.Tests.Util +{ + [TestFixture] + public class EnvironmentPatternConverterTest + { + private const string ENVIRONMENT_VARIABLE_NAME = "LOG4NET_TEST_TEMP"; + const string SYSTEM_LEVEL_VALUE = "SystemLevelEnvironmentValue"; + const string USER_LEVEL_VALUE = "UserLevelEnvironmentValue"; + const string PROCESS_LEVEL_VALUE = "ProcessLevelEnvironmentValue"; + + [Test] + public void SystemLevelEnvironmentVariable() + { + EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); + Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, SYSTEM_LEVEL_VALUE, EnvironmentVariableTarget.Machine); + + converter.Option = ENVIRONMENT_VARIABLE_NAME; + + StringWriter sw = new StringWriter(); + converter.Convert(sw, null); + + Assert.AreEqual(SYSTEM_LEVEL_VALUE, sw.ToString(), "System level environment variable not expended correctly."); + + Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null, EnvironmentVariableTarget.Machine); + } + + [Test] + public void UserLevelEnvironmentVariable() + { + EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); + Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, USER_LEVEL_VALUE, EnvironmentVariableTarget.User); + + converter.Option = ENVIRONMENT_VARIABLE_NAME; + + StringWriter sw = new StringWriter(); + converter.Convert(sw, null); + + Assert.AreEqual(USER_LEVEL_VALUE, sw.ToString(), "User level environment variable not expended correctly."); + + Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null, EnvironmentVariableTarget.User); + } + + [Test] + public void ProcessLevelEnvironmentVariable() + { + EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); + Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, PROCESS_LEVEL_VALUE); + + converter.Option = ENVIRONMENT_VARIABLE_NAME; + + StringWriter sw = new StringWriter(); + converter.Convert(sw, null); + + Assert.AreEqual(PROCESS_LEVEL_VALUE, sw.ToString(), "Process level environment variable not expended correctly."); + + Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null); + } + + private class EnvironmentPatternConverter + { + private object target = null; + + public EnvironmentPatternConverter() + { + target = Utils.CreateInstance("log4net.Util.PatternStringConverters.EnvironmentPatternConverter,log4net"); + } + + public string Option + { + get { return Utils.GetProperty(target, "Option") as string; } + set { Utils.SetProperty(target, "Option", value); } + } + + public void Convert(TextWriter writer, object state) + { + Utils.InvokeMethod(target, "Convert", writer, state); + } + } + } +} + +#endif diff --git a/tests/src/Util/LogLogTest.cs b/tests/src/Util/LogLogTest.cs index 023fbd38..eb2ac3a9 100644 --- a/tests/src/Util/LogLogTest.cs +++ b/tests/src/Util/LogLogTest.cs @@ -1,83 +1,83 @@ -using System.Collections; -using System.Diagnostics; -using log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - [TestFixture] - public class LogLogTest - { - [Test] - public void TraceListenerCounterTest() - { - TraceListenerCounter listTraceListener = new TraceListenerCounter(); - - Trace.Listeners.Clear(); - Trace.Listeners.Add(listTraceListener); - - Trace.Write("Hello"); - Trace.Write("World"); - - Assert.AreEqual(2, listTraceListener.Count); - } - - [Test] - public void EmitInternalMessages() - { - TraceListenerCounter listTraceListener = new TraceListenerCounter(); - Trace.Listeners.Clear(); - Trace.Listeners.Add(listTraceListener); - LogLog.Error(GetType(), "Hello"); - LogLog.Error(GetType(), "World"); - Trace.Flush(); - Assert.AreEqual(2, listTraceListener.Count); - - LogLog.EmitInternalMessages = false; - - LogLog.Error(GetType(), "Hello"); - LogLog.Error(GetType(), "World"); - Assert.AreEqual(2, listTraceListener.Count); - } - - [Test] - public void LogReceivedAdapter() - { - ArrayList messages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(messages)) - { - LogLog.Debug(GetType(), "Won't be recorded"); - LogLog.Error(GetType(), "This will be recorded."); - LogLog.Error(GetType(), "This will be recorded."); - } - - Assert.AreEqual(2, messages.Count); - } - } - - public class TraceListenerCounter : TraceListener - { - private int count = 0; - - public override void Write(string message) - { - count++; - } - - public override void WriteLine(string message) - { - Write(message); - } - - public void Reset() - { - count = 0; - } - - public int Count - { - get { return count; } - } - } +using System.Collections; +using System.Diagnostics; +using log4net.Util; +using NUnit.Framework; + +namespace log4net.Tests.Util +{ + [TestFixture] + public class LogLogTest + { + [Test] + public void TraceListenerCounterTest() + { + TraceListenerCounter listTraceListener = new TraceListenerCounter(); + + Trace.Listeners.Clear(); + Trace.Listeners.Add(listTraceListener); + + Trace.Write("Hello"); + Trace.Write("World"); + + Assert.AreEqual(2, listTraceListener.Count); + } + + [Test] + public void EmitInternalMessages() + { + TraceListenerCounter listTraceListener = new TraceListenerCounter(); + Trace.Listeners.Clear(); + Trace.Listeners.Add(listTraceListener); + LogLog.Error(GetType(), "Hello"); + LogLog.Error(GetType(), "World"); + Trace.Flush(); + Assert.AreEqual(2, listTraceListener.Count); + + LogLog.EmitInternalMessages = false; + + LogLog.Error(GetType(), "Hello"); + LogLog.Error(GetType(), "World"); + Assert.AreEqual(2, listTraceListener.Count); + } + + [Test] + public void LogReceivedAdapter() + { + ArrayList messages = new ArrayList(); + + using (new LogLog.LogReceivedAdapter(messages)) + { + LogLog.Debug(GetType(), "Won't be recorded"); + LogLog.Error(GetType(), "This will be recorded."); + LogLog.Error(GetType(), "This will be recorded."); + } + + Assert.AreEqual(2, messages.Count); + } + } + + public class TraceListenerCounter : TraceListener + { + private int count = 0; + + public override void Write(string message) + { + count++; + } + + public override void WriteLine(string message) + { + Write(message); + } + + public void Reset() + { + count = 0; + } + + public int Count + { + get { return count; } + } + } } \ No newline at end of file diff --git a/tests/src/Util/PatternConverterTest.cs b/tests/src/Util/PatternConverterTest.cs index deb66122..7f0c3631 100644 --- a/tests/src/Util/PatternConverterTest.cs +++ b/tests/src/Util/PatternConverterTest.cs @@ -1,171 +1,171 @@ -using System; -using System.IO; -using System.Xml; -using log4net.Config; -using log4net.Core; -using log4net.Layout.Pattern; -using log4net.Repository; -using log4net.Tests.Appender; -using log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - [TestFixture] - public class PatternConverterTest - { - [Test] - public void PatternLayoutConverterProperties() - { - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - ILog log = LogManager.GetLogger(rep.Name, "PatternLayoutConverterProperties"); - log.Debug("Message"); - - PropertyKeyCountPatternLayoutConverter converter = - PropertyKeyCountPatternLayoutConverter.MostRecentInstance; - Assert.AreEqual(2, converter.Properties.Count); - Assert.AreEqual("4", converter.Properties["two-plus-two"]); - - StringAppender appender = - (StringAppender)LogManager.GetRepository(rep.Name).GetAppenders()[0]; - Assert.AreEqual("2", appender.GetString()); - } - - [Test] - public void PatternConverterProperties() - { - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - ILog log = LogManager.GetLogger(rep.Name, "PatternConverterProperties"); - log.Debug("Message"); - - PropertyKeyCountPatternConverter converter = - PropertyKeyCountPatternConverter.MostRecentInstance; - Assert.AreEqual(2, converter.Properties.Count); - Assert.AreEqual("4", converter.Properties["two-plus-two"]); - - PatternStringAppender appender = - (PatternStringAppender)LogManager.GetRepository(rep.Name).GetAppenders()[0]; - Assert.AreEqual("2", appender.Setting.Format()); - } - } - - public class PropertyKeyCountPatternLayoutConverter : PatternLayoutConverter - { - private static PropertyKeyCountPatternLayoutConverter mostRecentInstance; - - public PropertyKeyCountPatternLayoutConverter() - { - mostRecentInstance = this; - } - - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write(Properties.GetKeys().Length); - } - - public static PropertyKeyCountPatternLayoutConverter MostRecentInstance - { - get { return mostRecentInstance; } - } - } - - public class PropertyKeyCountPatternConverter : PatternConverter - { - private static PropertyKeyCountPatternConverter mostRecentInstance; - - public PropertyKeyCountPatternConverter() - { - mostRecentInstance = this; - } - - protected override void Convert(TextWriter writer, object state) - { - writer.Write(Properties.GetKeys().Length); - } - - public static PropertyKeyCountPatternConverter MostRecentInstance - { - get { return mostRecentInstance; } - } - } - - public class PatternStringAppender : StringAppender - { - private static PatternStringAppender mostRecentInstace; - - private PatternString setting; - - public PatternStringAppender() - { - mostRecentInstace = this; - } - - public PatternString Setting - { - get { return setting; } - set { setting = value; } - } - - public static PatternStringAppender MostRecentInstace - { - get { return mostRecentInstace; } - } - } -} +using System; +using System.IO; +using System.Xml; +using log4net.Config; +using log4net.Core; +using log4net.Layout.Pattern; +using log4net.Repository; +using log4net.Tests.Appender; +using log4net.Util; +using NUnit.Framework; + +namespace log4net.Tests.Util +{ + [TestFixture] + public class PatternConverterTest + { + [Test] + public void PatternLayoutConverterProperties() + { + XmlDocument log4netConfig = new XmlDocument(); + log4netConfig.LoadXml(@" + + + + + + + + + + + + + + + + + + + + + + + "); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + XmlConfigurator.Configure(rep, log4netConfig["log4net"]); + + ILog log = LogManager.GetLogger(rep.Name, "PatternLayoutConverterProperties"); + log.Debug("Message"); + + PropertyKeyCountPatternLayoutConverter converter = + PropertyKeyCountPatternLayoutConverter.MostRecentInstance; + Assert.AreEqual(2, converter.Properties.Count); + Assert.AreEqual("4", converter.Properties["two-plus-two"]); + + StringAppender appender = + (StringAppender)LogManager.GetRepository(rep.Name).GetAppenders()[0]; + Assert.AreEqual("2", appender.GetString()); + } + + [Test] + public void PatternConverterProperties() + { + XmlDocument log4netConfig = new XmlDocument(); + log4netConfig.LoadXml(@" + + + + + + + + + + + + + + + + + + + + + + + + "); + + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + XmlConfigurator.Configure(rep, log4netConfig["log4net"]); + + ILog log = LogManager.GetLogger(rep.Name, "PatternConverterProperties"); + log.Debug("Message"); + + PropertyKeyCountPatternConverter converter = + PropertyKeyCountPatternConverter.MostRecentInstance; + Assert.AreEqual(2, converter.Properties.Count); + Assert.AreEqual("4", converter.Properties["two-plus-two"]); + + PatternStringAppender appender = + (PatternStringAppender)LogManager.GetRepository(rep.Name).GetAppenders()[0]; + Assert.AreEqual("2", appender.Setting.Format()); + } + } + + public class PropertyKeyCountPatternLayoutConverter : PatternLayoutConverter + { + private static PropertyKeyCountPatternLayoutConverter mostRecentInstance; + + public PropertyKeyCountPatternLayoutConverter() + { + mostRecentInstance = this; + } + + protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) + { + writer.Write(Properties.GetKeys().Length); + } + + public static PropertyKeyCountPatternLayoutConverter MostRecentInstance + { + get { return mostRecentInstance; } + } + } + + public class PropertyKeyCountPatternConverter : PatternConverter + { + private static PropertyKeyCountPatternConverter mostRecentInstance; + + public PropertyKeyCountPatternConverter() + { + mostRecentInstance = this; + } + + protected override void Convert(TextWriter writer, object state) + { + writer.Write(Properties.GetKeys().Length); + } + + public static PropertyKeyCountPatternConverter MostRecentInstance + { + get { return mostRecentInstance; } + } + } + + public class PatternStringAppender : StringAppender + { + private static PatternStringAppender mostRecentInstace; + + private PatternString setting; + + public PatternStringAppender() + { + mostRecentInstace = this; + } + + public PatternString Setting + { + get { return setting; } + set { setting = value; } + } + + public static PatternStringAppender MostRecentInstace + { + get { return mostRecentInstace; } + } + } +} diff --git a/tests/src/Util/PatternStringTest.cs b/tests/src/Util/PatternStringTest.cs index 0958d4e3..37a13465 100644 --- a/tests/src/Util/PatternStringTest.cs +++ b/tests/src/Util/PatternStringTest.cs @@ -1,30 +1,30 @@ -using System; -using log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - [TestFixture] - public class PatternStringTest - { - [Test] - public void TestEnvironmentFolderPathPatternConverter() - { - string[] specialFolderNames = Enum.GetNames(typeof(Environment.SpecialFolder)); - - foreach (string specialFolderName in specialFolderNames) - { - string pattern = "%envFolderPath{" + specialFolderName + "}"; - - PatternString patternString = new PatternString(pattern); - - string evaluatedPattern = patternString.Format(); - - Environment.SpecialFolder specialFolder = - (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), specialFolderName); - - Assert.AreEqual(Environment.GetFolderPath(specialFolder), evaluatedPattern); - } - } - } -} +using System; +using log4net.Util; +using NUnit.Framework; + +namespace log4net.Tests.Util +{ + [TestFixture] + public class PatternStringTest + { + [Test] + public void TestEnvironmentFolderPathPatternConverter() + { + string[] specialFolderNames = Enum.GetNames(typeof(Environment.SpecialFolder)); + + foreach (string specialFolderName in specialFolderNames) + { + string pattern = "%envFolderPath{" + specialFolderName + "}"; + + PatternString patternString = new PatternString(pattern); + + string evaluatedPattern = patternString.Format(); + + Environment.SpecialFolder specialFolder = + (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), specialFolderName); + + Assert.AreEqual(Environment.GetFolderPath(specialFolder), evaluatedPattern); + } + } + } +} diff --git a/tests/src/log4net.Tests.vs2003.csproj b/tests/src/log4net.Tests.vs2003.csproj index 810af20e..641f4259 100644 --- a/tests/src/log4net.Tests.vs2003.csproj +++ b/tests/src/log4net.Tests.vs2003.csproj @@ -1,256 +1,256 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/log4net.Tests.vs2008.csproj b/tests/src/log4net.Tests.vs2008.csproj index bd4f1660..b20eb255 100644 --- a/tests/src/log4net.Tests.vs2008.csproj +++ b/tests/src/log4net.Tests.vs2008.csproj @@ -1,186 +1,186 @@ - - - Local - 9.0.30729 - 2.0 - {B0530F10-0238-49A9-93B0-8EF412E90BCF} - Debug - AnyCPU - - - - - log4net.Tests - - - JScript - Grid - IE50 - false - Library - log4net.Tests - - - - - - - 2.0 - v3.5 - - - ..\bin\Debug\ - false - 285212672 - false - - - TRACE;DEBUG;NET_2_0 - - - true - 4096 - false - false - false - false - 4 - full - prompt - - - ..\bin\Release\ - false - 285212672 - false - - - TRACE - - - false - 4096 - true - false - false - false - 4 - none - prompt - - - - False - ..\..\..\ibatisnet-3\External-Bin\Net\2.0\nunit.framework.dll - - - System - - - - 3.5 - - - System.Data - - - System.Runtime.Remoting - - - System.XML - - - - - AssemblyVersionInfo.cs - Code - - - - - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - - - Code - - - Code - - - - - - - Code - - - Code - - - Code - - - - - {181FE707-E161-4722-9F38-6AAAB6FAA106} - log4net.vs2008 - - - - - - - - - + + + Local + 9.0.30729 + 2.0 + {B0530F10-0238-49A9-93B0-8EF412E90BCF} + Debug + AnyCPU + + + + + log4net.Tests + + + JScript + Grid + IE50 + false + Library + log4net.Tests + + + + + + + 2.0 + v3.5 + + + ..\bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;NET_2_0 + + + true + 4096 + false + false + false + false + 4 + full + prompt + + + ..\bin\Release\ + false + 285212672 + false + + + TRACE + + + false + 4096 + true + false + false + false + 4 + none + prompt + + + + False + ..\..\..\ibatisnet-3\External-Bin\Net\2.0\nunit.framework.dll + + + System + + + + 3.5 + + + System.Data + + + System.Runtime.Remoting + + + System.XML + + + + + AssemblyVersionInfo.cs + Code + + + + + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + + + Code + + + Code + + + + + + + Code + + + Code + + + Code + + + + + {181FE707-E161-4722-9F38-6AAAB6FAA106} + log4net.vs2008 + + + + + + + + + \ No newline at end of file From de32946f5d6984b02a658c389d0d738431c362b1 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 17 Aug 2011 06:32:25 +0000 Subject: [PATCH 005/370] Add missing license headers. LOG4NET-302 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1158536 13f79535-47bb-0310-9956-ffa450edef68 --- build.cmd | 20 ++++++++++++++ doc/css/site.css | 21 +++++++++++++++ doc/css/style.css | 21 +++++++++++++++ .../Repository/SimpleApp/cs/src/App.config | 21 +++++++++++++++ .../Tutorials/ConsoleApp/cs/src/App.config | 21 +++++++++++++++ .../Repository/SimpleApp/js/src/App.config | 23 +++++++++++++++- .../Tutorials/ConsoleApp/cpp/src/App.config | 23 +++++++++++++++- .../ConsoleApp/cpp/src/ConsoleApp.vcproj | 21 +++++++++++++++ .../Tutorials/ConsoleApp/js/src/App.config | 23 +++++++++++++++- examples/net/1.1/cpp-examples.sln | 20 ++++++++++++++ .../SampleAppendersApp/cs/src/App.config | 21 +++++++++++++++ .../cs/src/SampleAppendersApp.csproj | 26 +++++++++++++++++-- .../WmiAppender/cs/src/WmiAppender.csproj | 26 +++++++++++++++++-- .../EventIDLogApp/cs/src/App.config | 21 +++++++++++++++ .../EventIDLogApp/cs/src/EventIDLogApp.csproj | 26 +++++++++++++++++-- .../TraceLogApp/cs/src/TraceLogApp.csproj | 26 +++++++++++++++++-- .../SampleLayoutsApp/cs/src/App.config | 21 +++++++++++++++ .../cs/src/SampleLayoutsApp.csproj | 26 +++++++++++++++++-- .../NotLogging/cs/src/NotLogging.csproj | 26 +++++++++++++++++-- .../NotLogging/vb/src/NotLogging.vbproj | 22 ++++++++++++++++ .../Remoting/RemotingClient/cs/src/App.config | 21 +++++++++++++++ .../cs/src/RemotingClient.csproj | 26 +++++++++++++++++-- .../Remoting/RemotingServer/cs/src/App.config | 21 +++++++++++++++ .../cs/src/RemotingServer.csproj | 26 +++++++++++++++++-- .../SharedModule/cs/src/SharedModule.csproj | 26 +++++++++++++++++-- .../SharedModule/vb/src/SharedModule.vbproj | 22 ++++++++++++++++ .../Repository/SimpleApp/cs/src/App.config | 23 +++++++++++++++- .../SimpleApp/cs/src/SimpleApp.csproj | 26 +++++++++++++++++-- .../Repository/SimpleApp/vb/src/App.config | 23 +++++++++++++++- .../SimpleApp/vb/src/SimpleApp.vbproj | 22 ++++++++++++++++ .../SimpleModule/cs/src/SimpleModule.csproj | 26 +++++++++++++++++-- .../SimpleModule/vb/src/SimpleModule.vbproj | 22 ++++++++++++++++ .../Tutorials/ConsoleApp/cs/src/App.config | 23 +++++++++++++++- .../ConsoleApp/cs/src/ConsoleApp.csproj | 26 +++++++++++++++++-- .../Tutorials/ConsoleApp/vb/src/App.config | 23 +++++++++++++++- .../ConsoleApp/vb/src/ConsoleApp.vbproj | 22 ++++++++++++++++ .../2.0/Tutorials/WebApp/cs/src/Global.asax | 21 +++++++++++++++ .../Tutorials/WebApp/cs/src/Global.asax.resx | 21 +++++++++++++++ .../2.0/Tutorials/WebApp/cs/src/Web.config | 21 +++++++++++++++ .../2.0/Tutorials/WebApp/cs/src/WebApp.csproj | 22 ++++++++++++++++ .../WebApp/cs/src/WebApp.csproj.webinfo | 22 ++++++++++++++++ .../Tutorials/WebApp/cs/src/WebApp.vsdisco | 21 +++++++++++++++ .../2.0/Tutorials/WebApp/cs/src/WebForm1.aspx | 21 +++++++++++++++ .../WebApp/cs/src/WebForm1.aspx.resx | 21 +++++++++++++++ .../2.0/Tutorials/WebApp/vb/src/Global.asax | 21 +++++++++++++++ .../Tutorials/WebApp/vb/src/Global.asax.resx | 21 +++++++++++++++ .../2.0/Tutorials/WebApp/vb/src/Web.config | 21 +++++++++++++++ .../2.0/Tutorials/WebApp/vb/src/WebApp.vbproj | 22 ++++++++++++++++ .../WebApp/vb/src/WebApp.vbproj.webinfo | 22 ++++++++++++++++ .../Tutorials/WebApp/vb/src/WebApp.vsdisco | 21 +++++++++++++++ .../2.0/Tutorials/WebApp/vb/src/WebForm1.aspx | 21 +++++++++++++++ .../WebApp/vb/src/WebForm1.aspx.resx | 21 +++++++++++++++ examples/net/2.0/cs-examples.sln | 20 ++++++++++++++ examples/net/2.0/vb-examples.sln | 20 ++++++++++++++ .../ConsoleApp/cs/src/ConsoleApp.csdproj | 22 ++++++++++++++++ .../ConsoleApp/cs/src/ConsoleApp.exe.config | 21 +++++++++++++++ .../ConsoleApp/vb/src/ConsoleApp.exe.config | 21 +++++++++++++++ .../ConsoleApp/vb/src/ConsoleApp.vbdproj | 22 ++++++++++++++++ examples/netcf/1.0/cs-examples.sln | 20 ++++++++++++++ examples/netcf/1.0/vb-examples.sln | 20 ++++++++++++++ .../Repository/SimpleApp/cs/src/App.config | 23 +++++++++++++++- .../Tutorials/ConsoleApp/js/src/App.config | 23 +++++++++++++++- extensions/net/1.0/cs-extensions.sln | 20 ++++++++++++++ .../cs/src/log4net.Ext.EventID.csproj | 22 ++++++++++++++++ .../cs/src/log4net.Ext.MarshalByRef.csproj | 22 ++++++++++++++++ .../cs/src/log4net.Ext.Trace.csproj | 22 ++++++++++++++++ log4net-sdk.ndoc | 24 ++++++++++++++++- .../StackTraceDetailPatternConverter.cs | 21 +++++++++++++++ .../ConfigurationChangedEventArgs.cs | 23 +++++++++++++++- src/Util/ConverterInfo.cs | 21 +++++++++++++++ src/Util/PropertyEntry.cs | 21 +++++++++++++++ src/log4net.vs2008.csproj | 26 +++++++++++++++++-- src/log4net.vs2008.sln | 20 ++++++++++++++ src/site/resources/css/site.css | 21 +++++++++++++++ tests/src/Appender/AdoNet/Log4NetCommand.cs | 21 +++++++++++++++ .../src/Appender/AdoNet/Log4NetConnection.cs | 21 +++++++++++++++ tests/src/Appender/AdoNet/Log4NetParameter.cs | 21 +++++++++++++++ .../AdoNet/Log4NetParameterCollection.cs | 21 +++++++++++++++ .../src/Appender/AdoNet/Log4NetTransaction.cs | 21 +++++++++++++++ tests/src/Appender/AdoNetAppenderTest.cs | 21 +++++++++++++++ tests/src/Appender/TraceAppenderTest.cs | 21 +++++++++++++++ tests/src/Core/EvaluatorTest.cs | 21 +++++++++++++++ tests/src/Filter/FilterTest.cs | 23 +++++++++++++++- tests/src/Hierarchy/Hierarchy.cs | 21 +++++++++++++++ .../LoggerRepository/ConfigurationMessages.cs | 23 +++++++++++++++- .../Util/EnvironmentPatternConverterTest.cs | 21 +++++++++++++++ tests/src/Util/LogLogTest.cs | 23 +++++++++++++++- tests/src/Util/PatternConverterTest.cs | 21 +++++++++++++++ tests/src/Util/PatternStringTest.cs | 21 +++++++++++++++ tests/src/log4net.Tests.vs2003.csproj | 22 ++++++++++++++++ tests/src/log4net.Tests.vs2008.csproj | 26 +++++++++++++++++-- 91 files changed, 1975 insertions(+), 42 deletions(-) diff --git a/build.cmd b/build.cmd index fff48943..db885124 100755 --- a/build.cmd +++ b/build.cmd @@ -1,3 +1,23 @@ +rem +rem +rem Licensed to the Apache Software Foundation (ASF) under one +rem or more contributor license agreements. See the NOTICE file +rem distributed with this work for additional information +rem regarding copyright ownership. The ASF licenses this file +rem to you under the Apache License, Version 2.0 (the +rem "License"); you may not use this file except in compliance +rem with the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, +rem software distributed under the License is distributed on an +rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +rem KIND, either express or implied. See the License for the +rem specific language governing permissions and limitations +rem under the License. +rem +rem @ECHO OFF REM We are going to change the environment variables, so protect the current settings. diff --git a/doc/css/site.css b/doc/css/site.css index 149f6c0d..76bcef1e 100644 --- a/doc/css/site.css +++ b/doc/css/site.css @@ -1,3 +1,24 @@ +/* + * + * 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. + * +*/ + H1, H2, H3 { color: #101099; diff --git a/doc/css/style.css b/doc/css/style.css index 513f6439..28fc7d6d 100644 --- a/doc/css/style.css +++ b/doc/css/style.css @@ -1,3 +1,24 @@ +/* + * + * 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. + * +*/ + body { margin: 0px 0px 0px 0px; diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/src/App.config b/examples/mono/1.0/Repository/SimpleApp/cs/src/App.config index d87f2d9f..10a5b298 100644 --- a/examples/mono/1.0/Repository/SimpleApp/cs/src/App.config +++ b/examples/mono/1.0/Repository/SimpleApp/cs/src/App.config @@ -1,4 +1,25 @@ + + diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config b/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config index 4680e125..f312d5f2 100644 --- a/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config +++ b/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config @@ -1,4 +1,25 @@ + + + - \ No newline at end of file + diff --git a/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/App.config b/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/App.config index c46c37b4..de78cf09 100644 --- a/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/App.config +++ b/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/App.config @@ -1,4 +1,25 @@ + + + + + + + + Local 8.0.50727 @@ -140,4 +162,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.csproj b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.csproj index 644ea9c5..04b4480f 100644 --- a/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.csproj +++ b/examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.csproj @@ -1,4 +1,26 @@ - + + + + Local 8.0.50727 @@ -109,4 +131,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/App.config b/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/App.config index d95aae73..24d69787 100755 --- a/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/App.config +++ b/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/App.config @@ -1,4 +1,25 @@ + + + + Local 8.0.50727 @@ -113,4 +135,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.csproj b/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.csproj index 5ef677e0..4648085c 100755 --- a/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.csproj +++ b/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.csproj @@ -1,4 +1,26 @@ - + + + + Local 8.0.50727 @@ -111,4 +133,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/App.config b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/App.config index 89ff23f3..d5b85621 100755 --- a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/App.config +++ b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/App.config @@ -1,4 +1,25 @@ + + + + Local 8.0.50727 @@ -117,4 +139,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.csproj b/examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.csproj index a80b7d47..f13c2bf3 100755 --- a/examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.csproj +++ b/examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.csproj @@ -1,4 +1,26 @@ - + + + + Local 8.0.50727 @@ -106,4 +128,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vbproj b/examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vbproj index 6dd27030..8124f718 100755 --- a/examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vbproj +++ b/examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vbproj @@ -1,3 +1,25 @@ + + + + + + + Local 8.0.50727 @@ -101,4 +123,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Remoting/RemotingServer/cs/src/App.config b/examples/net/2.0/Remoting/RemotingServer/cs/src/App.config index b49a40c4..52b699d9 100755 --- a/examples/net/2.0/Remoting/RemotingServer/cs/src/App.config +++ b/examples/net/2.0/Remoting/RemotingServer/cs/src/App.config @@ -1,4 +1,25 @@ + + diff --git a/examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.csproj b/examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.csproj index 8179eb53..6a172cce 100755 --- a/examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.csproj +++ b/examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.csproj @@ -1,4 +1,26 @@ - + + + + Local 8.0.50727 @@ -100,4 +122,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Repository/SharedModule/cs/src/SharedModule.csproj b/examples/net/2.0/Repository/SharedModule/cs/src/SharedModule.csproj index 4c03b0cc..1dfb7c9c 100755 --- a/examples/net/2.0/Repository/SharedModule/cs/src/SharedModule.csproj +++ b/examples/net/2.0/Repository/SharedModule/cs/src/SharedModule.csproj @@ -1,4 +1,26 @@ - + + + + Local 8.0.50727 @@ -107,4 +129,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Repository/SharedModule/vb/src/SharedModule.vbproj b/examples/net/2.0/Repository/SharedModule/vb/src/SharedModule.vbproj index e1f00294..6079c28f 100755 --- a/examples/net/2.0/Repository/SharedModule/vb/src/SharedModule.vbproj +++ b/examples/net/2.0/Repository/SharedModule/vb/src/SharedModule.vbproj @@ -1,3 +1,25 @@ + + + + + - \ No newline at end of file + diff --git a/examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.csproj b/examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.csproj index edefbb4b..fa3a91b3 100755 --- a/examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.csproj +++ b/examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.csproj @@ -1,4 +1,26 @@ - + + + + Local 8.0.50727 @@ -118,4 +140,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Repository/SimpleApp/vb/src/App.config b/examples/net/2.0/Repository/SimpleApp/vb/src/App.config index 4fcc7688..c37efd08 100755 --- a/examples/net/2.0/Repository/SimpleApp/vb/src/App.config +++ b/examples/net/2.0/Repository/SimpleApp/vb/src/App.config @@ -1,8 +1,29 @@ + + - \ No newline at end of file + diff --git a/examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.vbproj b/examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.vbproj index 65f3888a..f1bedee3 100755 --- a/examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.vbproj +++ b/examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.vbproj @@ -1,3 +1,25 @@ + + + + + + + Local 8.0.50727 @@ -108,4 +130,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.vbproj b/examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.vbproj index 9a99c44b..25b33136 100755 --- a/examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.vbproj +++ b/examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.vbproj @@ -1,3 +1,25 @@ + + + + + + + Local 8.0.50727 @@ -107,4 +129,4 @@ - \ No newline at end of file + diff --git a/examples/net/2.0/Tutorials/ConsoleApp/vb/src/App.config b/examples/net/2.0/Tutorials/ConsoleApp/vb/src/App.config index 682eb7b9..f3d71025 100755 --- a/examples/net/2.0/Tutorials/ConsoleApp/vb/src/App.config +++ b/examples/net/2.0/Tutorials/ConsoleApp/vb/src/App.config @@ -1,4 +1,25 @@ + + + + <%@ Application Codebehind="Global.asax.cs" Inherits="WebApp.Global" %> diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.resx b/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.resx index 7e323966..c8e3ce72 100755 --- a/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.resx +++ b/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.resx @@ -1,4 +1,25 @@ + + diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/Web.config b/examples/net/2.0/Tutorials/WebApp/cs/src/Web.config index 84f7881b..8389366f 100755 --- a/examples/net/2.0/Tutorials/WebApp/cs/src/Web.config +++ b/examples/net/2.0/Tutorials/WebApp/cs/src/Web.config @@ -1,4 +1,25 @@ + + diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj b/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj index 47c5a7c2..105bfdba 100755 --- a/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj +++ b/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj @@ -1,3 +1,25 @@ + + + + + diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.vsdisco b/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.vsdisco index 10b0ed10..639642ee 100755 --- a/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.vsdisco +++ b/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.vsdisco @@ -1,4 +1,25 @@ + + diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx b/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx index 3219c8c3..7de98908 100644 --- a/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx +++ b/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx @@ -1,3 +1,24 @@ + + <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="WebApp.WebForm1" %> diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.resx b/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.resx index 7e323966..c8e3ce72 100755 --- a/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.resx +++ b/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.resx @@ -1,4 +1,25 @@ + + diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax b/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax index ef097998..93c16a4e 100644 --- a/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax +++ b/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax @@ -1 +1,22 @@ + + <%@ Application Codebehind="Global.asax.vb" Inherits="WebApp.Global" %> diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.resx b/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.resx index 7e323966..c8e3ce72 100755 --- a/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.resx +++ b/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.resx @@ -1,4 +1,25 @@ + + diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/Web.config b/examples/net/2.0/Tutorials/WebApp/vb/src/Web.config index 972e1f49..fe903043 100755 --- a/examples/net/2.0/Tutorials/WebApp/vb/src/Web.config +++ b/examples/net/2.0/Tutorials/WebApp/vb/src/Web.config @@ -1,4 +1,25 @@ + + diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj b/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj index 5574753d..42d33e5c 100755 --- a/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj +++ b/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj @@ -1,3 +1,25 @@ + + + + + diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vsdisco b/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vsdisco index 10b0ed10..639642ee 100755 --- a/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vsdisco +++ b/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vsdisco @@ -1,4 +1,25 @@ + + diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx b/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx index 34e607de..5b8c8496 100644 --- a/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx +++ b/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx @@ -1,3 +1,24 @@ + + <%@ Page language="vb" Codebehind="WebForm1.aspx.vb" AutoEventWireup="false" Inherits="WebApp.WebForm1" %> diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.resx b/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.resx index 7e323966..c8e3ce72 100755 --- a/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.resx +++ b/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.resx @@ -1,4 +1,25 @@ + + diff --git a/examples/net/2.0/cs-examples.sln b/examples/net/2.0/cs-examples.sln index 56a2a761..7b5e2b26 100644 --- a/examples/net/2.0/cs-examples.sln +++ b/examples/net/2.0/cs-examples.sln @@ -1,5 +1,25 @@ Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 +# +# +# 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. +# +# Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "Tutorials\ConsoleApp\cs\src\ConsoleApp.csproj", "{933969DF-2BC5-44E6-8B1A-400FC276A23F}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" diff --git a/examples/net/2.0/vb-examples.sln b/examples/net/2.0/vb-examples.sln index e7fde504..c5afc467 100644 --- a/examples/net/2.0/vb-examples.sln +++ b/examples/net/2.0/vb-examples.sln @@ -1,4 +1,24 @@ Microsoft Visual Studio Solution File, Format Version 7.00 +# +# +# 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. +# +# Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ConsoleApp", "Tutorials\ConsoleApp\vb\src\ConsoleApp.vbproj", "{41B855A4-F3BF-43F8-BE6F-2ABD5E5C8D42}" EndProject Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "WebApp", "http://localhost/WebAppVB/WebApp.vbproj", "{4CEA8E96-BF74-488D-9967-EAB779EF430A}" diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csdproj b/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csdproj index aab0f599..49693d23 100755 --- a/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csdproj +++ b/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csdproj @@ -1,3 +1,25 @@ + + + + + + + + + - \ No newline at end of file + diff --git a/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/App.config b/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/App.config index 2d644aeb..12c4fef7 100755 --- a/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/App.config +++ b/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/App.config @@ -1,4 +1,25 @@ + + + + + + + + + @@ -66,4 +88,4 @@ - \ No newline at end of file + diff --git a/src/Layout/Pattern/StackTraceDetailPatternConverter.cs b/src/Layout/Pattern/StackTraceDetailPatternConverter.cs index 2277505b..0351e3f1 100644 --- a/src/Layout/Pattern/StackTraceDetailPatternConverter.cs +++ b/src/Layout/Pattern/StackTraceDetailPatternConverter.cs @@ -1,3 +1,24 @@ +/* + * + * 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.Collections; using System.Text; diff --git a/src/Repository/ConfigurationChangedEventArgs.cs b/src/Repository/ConfigurationChangedEventArgs.cs index ded98531..77df7d41 100644 --- a/src/Repository/ConfigurationChangedEventArgs.cs +++ b/src/Repository/ConfigurationChangedEventArgs.cs @@ -1,3 +1,24 @@ +/* + * + * 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.Collections; @@ -27,4 +48,4 @@ public ICollection ConfigurationMessages get { return configurationMessages; } } } -} \ No newline at end of file +} diff --git a/src/Util/ConverterInfo.cs b/src/Util/ConverterInfo.cs index efab75fd..b64edc9d 100644 --- a/src/Util/ConverterInfo.cs +++ b/src/Util/ConverterInfo.cs @@ -1,3 +1,24 @@ +/* + * + * 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; namespace log4net.Util diff --git a/src/Util/PropertyEntry.cs b/src/Util/PropertyEntry.cs index d11f58df..3357d989 100644 --- a/src/Util/PropertyEntry.cs +++ b/src/Util/PropertyEntry.cs @@ -1,3 +1,24 @@ +/* + * + * 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. + * +*/ + namespace log4net.Util { /// diff --git a/src/log4net.vs2008.csproj b/src/log4net.vs2008.csproj index 46c85553..a06bbd8c 100644 --- a/src/log4net.vs2008.csproj +++ b/src/log4net.vs2008.csproj @@ -1,4 +1,26 @@ - + + + + Local 9.0.30729 @@ -723,4 +745,4 @@ - \ No newline at end of file + diff --git a/src/log4net.vs2008.sln b/src/log4net.vs2008.sln index 74193889..2bf603c5 100644 --- a/src/log4net.vs2008.sln +++ b/src/log4net.vs2008.sln @@ -1,5 +1,25 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 +# +# +# 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. +# +# Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.vs2008", "log4net.vs2008.csproj", "{181FE707-E161-4722-9F38-6AAAB6FAA106}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Tests.vs2008", "..\tests\src\log4net.Tests.vs2008.csproj", "{B0530F10-0238-49A9-93B0-8EF412E90BCF}" diff --git a/src/site/resources/css/site.css b/src/site/resources/css/site.css index 8b137891..6005acea 100644 --- a/src/site/resources/css/site.css +++ b/src/site/resources/css/site.css @@ -1 +1,22 @@ +/* + * + * 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. + * +*/ + diff --git a/tests/src/Appender/AdoNet/Log4NetCommand.cs b/tests/src/Appender/AdoNet/Log4NetCommand.cs index d7d41a43..98beb8e2 100644 --- a/tests/src/Appender/AdoNet/Log4NetCommand.cs +++ b/tests/src/Appender/AdoNet/Log4NetCommand.cs @@ -1,3 +1,24 @@ +/* + * + * 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; diff --git a/tests/src/Appender/AdoNet/Log4NetConnection.cs b/tests/src/Appender/AdoNet/Log4NetConnection.cs index 4c3b0db5..33bbcce0 100644 --- a/tests/src/Appender/AdoNet/Log4NetConnection.cs +++ b/tests/src/Appender/AdoNet/Log4NetConnection.cs @@ -1,3 +1,24 @@ +/* + * + * 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; diff --git a/tests/src/Appender/AdoNet/Log4NetParameter.cs b/tests/src/Appender/AdoNet/Log4NetParameter.cs index 11c206ea..4eb038d3 100644 --- a/tests/src/Appender/AdoNet/Log4NetParameter.cs +++ b/tests/src/Appender/AdoNet/Log4NetParameter.cs @@ -1,3 +1,24 @@ +/* + * + * 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; diff --git a/tests/src/Appender/AdoNet/Log4NetParameterCollection.cs b/tests/src/Appender/AdoNet/Log4NetParameterCollection.cs index e77ea121..8b0d0415 100644 --- a/tests/src/Appender/AdoNet/Log4NetParameterCollection.cs +++ b/tests/src/Appender/AdoNet/Log4NetParameterCollection.cs @@ -1,3 +1,24 @@ +/* + * + * 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.Collections; using System.Data; diff --git a/tests/src/Appender/AdoNet/Log4NetTransaction.cs b/tests/src/Appender/AdoNet/Log4NetTransaction.cs index 0b09ac30..d52e3643 100644 --- a/tests/src/Appender/AdoNet/Log4NetTransaction.cs +++ b/tests/src/Appender/AdoNet/Log4NetTransaction.cs @@ -1,3 +1,24 @@ +/* + * + * 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; diff --git a/tests/src/Appender/AdoNetAppenderTest.cs b/tests/src/Appender/AdoNetAppenderTest.cs index 9f3ff399..624f1c40 100644 --- a/tests/src/Appender/AdoNetAppenderTest.cs +++ b/tests/src/Appender/AdoNetAppenderTest.cs @@ -1,3 +1,24 @@ +/* + * + * 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; diff --git a/tests/src/Appender/TraceAppenderTest.cs b/tests/src/Appender/TraceAppenderTest.cs index 3977d4b5..306ac16c 100644 --- a/tests/src/Appender/TraceAppenderTest.cs +++ b/tests/src/Appender/TraceAppenderTest.cs @@ -1,3 +1,24 @@ +/* + * + * 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.Diagnostics; using log4net.Appender; diff --git a/tests/src/Core/EvaluatorTest.cs b/tests/src/Core/EvaluatorTest.cs index 5f61cb50..62626d24 100644 --- a/tests/src/Core/EvaluatorTest.cs +++ b/tests/src/Core/EvaluatorTest.cs @@ -1,3 +1,24 @@ +/* + * + * 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 log4net.Appender; using log4net.Core; diff --git a/tests/src/Filter/FilterTest.cs b/tests/src/Filter/FilterTest.cs index 31900d62..ba4f7edc 100644 --- a/tests/src/Filter/FilterTest.cs +++ b/tests/src/Filter/FilterTest.cs @@ -1,4 +1,25 @@ -#if NET_2_0 +/* + * + * 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. + * +*/ + +#if NET_2_0 using System; using System.Collections.Generic; using System.Xml; diff --git a/tests/src/Hierarchy/Hierarchy.cs b/tests/src/Hierarchy/Hierarchy.cs index be834fc1..9ce6123f 100644 --- a/tests/src/Hierarchy/Hierarchy.cs +++ b/tests/src/Hierarchy/Hierarchy.cs @@ -1,3 +1,24 @@ +/* + * + * 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.Xml; using log4net.Config; diff --git a/tests/src/LoggerRepository/ConfigurationMessages.cs b/tests/src/LoggerRepository/ConfigurationMessages.cs index 67afe36e..3e814d49 100644 --- a/tests/src/LoggerRepository/ConfigurationMessages.cs +++ b/tests/src/LoggerRepository/ConfigurationMessages.cs @@ -1,3 +1,24 @@ +/* + * + * 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.Collections; using System.Xml; @@ -71,4 +92,4 @@ protected override void Append(LoggingEvent loggingEvent) LogLog.Error(declaringType, "Error - Appending..."); } } -} \ No newline at end of file +} diff --git a/tests/src/Util/EnvironmentPatternConverterTest.cs b/tests/src/Util/EnvironmentPatternConverterTest.cs index 4995fbee..2eee33f3 100644 --- a/tests/src/Util/EnvironmentPatternConverterTest.cs +++ b/tests/src/Util/EnvironmentPatternConverterTest.cs @@ -1,3 +1,24 @@ +/* + * + * 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. + * +*/ + // .NET Compact Framework 1.0 has no support for Environment.GetEnvironmentVariable() // .NET Framework version 1.0 / 1.1 do not have support for SetEnvironmentVariable which is used in these tests. #if !NETCF && NET_2_0 diff --git a/tests/src/Util/LogLogTest.cs b/tests/src/Util/LogLogTest.cs index eb2ac3a9..18ed78d5 100644 --- a/tests/src/Util/LogLogTest.cs +++ b/tests/src/Util/LogLogTest.cs @@ -1,3 +1,24 @@ +/* + * + * 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.Collections; using System.Diagnostics; using log4net.Util; @@ -80,4 +101,4 @@ public int Count get { return count; } } } -} \ No newline at end of file +} diff --git a/tests/src/Util/PatternConverterTest.cs b/tests/src/Util/PatternConverterTest.cs index 7f0c3631..06f352eb 100644 --- a/tests/src/Util/PatternConverterTest.cs +++ b/tests/src/Util/PatternConverterTest.cs @@ -1,3 +1,24 @@ +/* + * + * 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.IO; using System.Xml; diff --git a/tests/src/Util/PatternStringTest.cs b/tests/src/Util/PatternStringTest.cs index 37a13465..2a2ed7df 100644 --- a/tests/src/Util/PatternStringTest.cs +++ b/tests/src/Util/PatternStringTest.cs @@ -1,3 +1,24 @@ +/* + * + * 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 log4net.Util; using NUnit.Framework; diff --git a/tests/src/log4net.Tests.vs2003.csproj b/tests/src/log4net.Tests.vs2003.csproj index 641f4259..adb7f227 100644 --- a/tests/src/log4net.Tests.vs2003.csproj +++ b/tests/src/log4net.Tests.vs2003.csproj @@ -1,3 +1,25 @@ + + + + + + + Local 9.0.30729 @@ -183,4 +205,4 @@ - \ No newline at end of file + From caf2851858e716a34e9af33107592017bb10bcf5 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 17 Aug 2011 06:34:49 +0000 Subject: [PATCH 006/370] Make tests compile on .NET 2.0. COMPRESS-300 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1158537 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Filter/FilterTest.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/src/Filter/FilterTest.cs b/tests/src/Filter/FilterTest.cs index ba4f7edc..ea9a3d14 100644 --- a/tests/src/Filter/FilterTest.cs +++ b/tests/src/Filter/FilterTest.cs @@ -67,13 +67,15 @@ public void FilterConfigurationTest() IAppender[] appenders = LogManager.GetRepository(rep.Name).GetAppenders(); Assert.IsTrue(appenders.Length == 1); - IAppender appender = Array.Find(appenders, a => a.Name == "MemoryAppender"); + IAppender appender = Array.Find(appenders, delegate(IAppender a) { + return a.Name == "MemoryAppender"; + }); Assert.IsNotNull(appender); MultiplePropertyFilter multiplePropertyFilter = ((AppenderSkeleton)appender).FilterHead as MultiplePropertyFilter; - var conditions = multiplePropertyFilter.GetConditions(); + MultiplePropertyFilter.Condition[] conditions = multiplePropertyFilter.GetConditions(); Assert.AreEqual(2, conditions.Length); Assert.AreEqual("ABC", conditions[0].Key); Assert.AreEqual("123", conditions[0].StringToMatch); @@ -103,8 +105,15 @@ public void AddCondition(Condition condition) public class Condition { - public string Key { get; set; } - public string StringToMatch { get; set; } + private string key, stringToMatch; + public string Key { + get { return key; } + set { key = value; } + } + public string StringToMatch { + get { return stringToMatch; } + set { stringToMatch = value; } + } } } } From 201ac5102a4ffac35ed6188e164b2ff72b2aac41 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 17 Aug 2011 07:03:49 +0000 Subject: [PATCH 007/370] formatting changes only git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1158545 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 198 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/pom.xml b/pom.xml index 9922a8d4..93fb57e2 100644 --- a/pom.xml +++ b/pom.xml @@ -33,46 +33,46 @@ http://vmgump.apache.org/gump/public/logging-log4net/logging-log4net/index.html - - log4net-user : log4net usage - log4net-user-subscribe@logging.apache.org - log4net-user-unsubscribe@logging.apache.org - log4net-user@logging.apache.org - http://mail-archives.apache.org/mod_mbox/logging-log4net-user/ - - http://marc.info/?l=log4net-user - http://dir.gmane.org/gmane.comp.log.log4net.user - - - - log4net-dev : log4net development - log4net-dev-subscribe@logging.apache.org - log4net-dev-unsubscribe@logging.apache.org - log4net-dev@logging.apache.org - http://mail-archives.apache.org/mod_mbox/logging-log4net-dev/ - - http://marc.info/?l=log4net-dev - http://dir.gmane.org/gmane.comp.apache.logging.log4net.devel - - - - - - Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - scm:svn:http://svn.apache.org/repos/asf/logging/log4net/trunk - scm:svn:https://svn.apache.org/repos/asf/logging/log4net/trunk - http://svn.apache.org/viewcvs.cgi/logging/log4net/trunk - - + + log4net-user : log4net usage + log4net-user-subscribe@logging.apache.org + log4net-user-unsubscribe@logging.apache.org + log4net-user@logging.apache.org + http://mail-archives.apache.org/mod_mbox/logging-log4net-user/ + + http://marc.info/?l=log4net-user + http://dir.gmane.org/gmane.comp.log.log4net.user + + + + log4net-dev : log4net development + log4net-dev-subscribe@logging.apache.org + log4net-dev-unsubscribe@logging.apache.org + log4net-dev@logging.apache.org + http://mail-archives.apache.org/mod_mbox/logging-log4net-dev/ + + http://marc.info/?l=log4net-dev + http://dir.gmane.org/gmane.comp.apache.logging.log4net.devel + + + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + scm:svn:http://svn.apache.org/repos/asf/logging/log4net/trunk + scm:svn:https://svn.apache.org/repos/asf/logging/log4net/trunk + http://svn.apache.org/viewcvs.cgi/logging/log4net/trunk + + Apache Software Foundation http://www.apache.org - - + + maven-antrun-plugin @@ -81,9 +81,9 @@ compile compile - - - + + + run @@ -93,11 +93,11 @@ test-compile test-compile - - - - - + + + + + run @@ -111,27 +111,27 @@ - + run - + site site - - - - - - + + + + + + run @@ -141,11 +141,11 @@ post-site post-site - - - - - + + + + + run @@ -155,47 +155,47 @@ site-deploy site-deploy - - - - - + + + + + run - - - ant - ant-nodeps - 1.6.5 - - - - - maven-assembly-plugin - - - src/assembly/bin.xml - - false + + + ant + ant-nodeps + 1.6.5 + + + + + maven-assembly-plugin + + + src/assembly/bin.xml + + false - - - assembly - - + + + assembly + + - + - + - true + true maven-project-info-reports-plugin @@ -213,10 +213,10 @@ - maven-release-plugin - - site-deploy - + maven-release-plugin + + site-deploy + maven-changes-plugin @@ -228,12 +228,12 @@ - %URL%/browse/%ISSUE% + %URL%/browse/%ISSUE% - + - + logging.site file:///tmp/log4net-deploy From 00d2e33d82b884209a68c24d57a821c96b6f2eaa Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 18 Aug 2011 10:37:39 +0000 Subject: [PATCH 008/370] fix some XML doc warnings git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159147 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/AppenderCollection.cs | 8 ++++---- src/Appender/AppenderSkeleton.cs | 4 ++-- src/Appender/EventLogAppender.cs | 4 ++-- src/Appender/NetSendAppender.cs | 18 +++++++++--------- src/Core/LevelCollection.cs | 8 ++++---- src/MDC.cs | 4 ++-- src/Plugin/PluginCollection.cs | 8 ++++---- src/Util/OptionConverter.cs | 2 +- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Appender/AppenderCollection.cs b/src/Appender/AppenderCollection.cs index 99f94ac6..266bdc38 100755 --- a/src/Appender/AppenderCollection.cs +++ b/src/Appender/AppenderCollection.cs @@ -566,9 +566,9 @@ public virtual IAppender[] ToArray() #region Implementation (helpers) /// - /// is less than zero + /// is less than zero /// -or- - /// is equal to or greater than . + /// is equal to or greater than . /// private void ValidateIndex(int i) { @@ -576,9 +576,9 @@ private void ValidateIndex(int i) } /// - /// is less than zero + /// is less than zero /// -or- - /// is equal to or greater than . + /// is equal to or greater than . /// private void ValidateIndex(int i, bool allowEqualEnd) { diff --git a/src/Appender/AppenderSkeleton.cs b/src/Appender/AppenderSkeleton.cs index 6dc31920..a02ca986 100755 --- a/src/Appender/AppenderSkeleton.cs +++ b/src/Appender/AppenderSkeleton.cs @@ -362,14 +362,14 @@ public void DoAppend(LoggingEvent loggingEvent) /// /// /// - /// Checks that the severity of the + /// Checks that the severity of the /// is greater than or equal to the of this /// appender. /// /// /// /// Checks that the chain accepts the - /// . + /// . /// /// /// diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs index c17c2838..629f75de 100755 --- a/src/Appender/EventLogAppender.cs +++ b/src/Appender/EventLogAppender.cs @@ -403,10 +403,10 @@ override protected bool RequiresLayout #region Protected Instance Methods /// - /// Get the equivalent for a + /// Get the equivalent for a /// /// the Level to convert to an EventLogEntryType - /// The equivalent for a + /// The equivalent for a /// /// Because there are fewer applicable /// values to use in logging levels than there are in the diff --git a/src/Appender/NetSendAppender.cs b/src/Appender/NetSendAppender.cs index c0e0369f..9a22a32b 100755 --- a/src/Appender/NetSendAppender.cs +++ b/src/Appender/NetSendAppender.cs @@ -68,10 +68,10 @@ namespace log4net.Appender /// Send a message to a user account on the local machine /// /// - /// = <name of the local machine> + /// = <name of the local machine> /// /// - /// = <user name> + /// = <user name> /// /// /// @@ -79,10 +79,10 @@ namespace log4net.Appender /// Send a message to a user account on a remote machine /// /// - /// = <name of the remote machine> + /// = <name of the remote machine> /// /// - /// = <user name> + /// = <user name> /// /// /// @@ -90,10 +90,10 @@ namespace log4net.Appender /// Send a message to a domain user account /// /// - /// = <name of a domain controller | uninitialized> + /// = <name of a domain controller | uninitialized> /// /// - /// = <user name> + /// = <user name> /// /// /// @@ -101,7 +101,7 @@ namespace log4net.Appender /// Send a message to all the names in a workgroup or domain /// /// - /// = <workgroup name | domain name>* + /// = <workgroup name | domain name>* /// /// /// @@ -109,10 +109,10 @@ namespace log4net.Appender /// Send a message from the local machine to a remote machine /// /// - /// = <name of the local machine | uninitialized> + /// = <name of the local machine | uninitialized> /// /// - /// = <name of the remote machine> + /// = <name of the remote machine> /// /// /// diff --git a/src/Core/LevelCollection.cs b/src/Core/LevelCollection.cs index 1428c67c..1287ac01 100755 --- a/src/Core/LevelCollection.cs +++ b/src/Core/LevelCollection.cs @@ -541,9 +541,9 @@ public virtual void TrimToSize() #region Implementation (helpers) /// - /// is less than zero + /// is less than zero /// -or- - /// is equal to or greater than . + /// is equal to or greater than . /// private void ValidateIndex(int i) { @@ -551,9 +551,9 @@ private void ValidateIndex(int i) } /// - /// is less than zero + /// is less than zero /// -or- - /// is equal to or greater than . + /// is equal to or greater than . /// private void ValidateIndex(int i, bool allowEqualEnd) { diff --git a/src/MDC.cs b/src/MDC.cs index 2baef8dd..06e1b1db 100755 --- a/src/MDC.cs +++ b/src/MDC.cs @@ -107,13 +107,13 @@ public static string Get(string key) /// /// /// - /// Puts a context value (the parameter) as identified + /// Puts a context value (the parameter) as identified /// with the parameter into the current thread's /// context map. /// /// /// If a value is already defined for the - /// specified then the value will be replaced. If the + /// specified then the value will be replaced. If the /// is specified as null then the key value mapping will be removed. /// /// diff --git a/src/Plugin/PluginCollection.cs b/src/Plugin/PluginCollection.cs index 56cc3f5c..d068f550 100755 --- a/src/Plugin/PluginCollection.cs +++ b/src/Plugin/PluginCollection.cs @@ -553,9 +553,9 @@ public virtual void TrimToSize() #region Implementation (helpers) /// - /// is less than zero. + /// is less than zero. /// -or- - /// is equal to or greater than . + /// is equal to or greater than . /// private void ValidateIndex(int i) { @@ -563,9 +563,9 @@ private void ValidateIndex(int i) } /// - /// is less than zero. + /// is less than zero. /// -or- - /// is equal to or greater than . + /// is equal to or greater than . /// private void ValidateIndex(int i, bool allowEqualEnd) { diff --git a/src/Util/OptionConverter.cs b/src/Util/OptionConverter.cs index d509e73f..616cf1bc 100755 --- a/src/Util/OptionConverter.cs +++ b/src/Util/OptionConverter.cs @@ -492,7 +492,7 @@ public static object InstantiateByClassName(string className, Type superClass, o } /// - /// Performs variable substitution in string from the + /// Performs variable substitution in string from the /// values of keys found in . /// /// The string on which variable substitution is performed. From 31bef79a49c993a2d3f6571114a0655047142a8b Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 18 Aug 2011 10:55:25 +0000 Subject: [PATCH 009/370] obsolete warnings new in .NET 4.0 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159160 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/SmtpAppender.cs | 6 ++++++ src/Config/XmlConfigurator.cs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/Appender/SmtpAppender.cs b/src/Appender/SmtpAppender.cs index 3ef90d73..101e4e40 100755 --- a/src/Appender/SmtpAppender.cs +++ b/src/Appender/SmtpAppender.cs @@ -460,7 +460,13 @@ virtual protected void SendEmail(string messageBody) } if (!String.IsNullOrEmpty(m_replyTo)) { + // .NET 4.0 warning CS0618: 'System.Net.Mail.MailMessage.ReplyTo' is obsolete: + // 'ReplyTo is obsoleted for this type. Please use ReplyToList instead which can accept multiple addresses. http://go.microsoft.com/fwlink/?linkid=14202' +#if !NET_4_0 mailMessage.ReplyTo = new MailAddress(m_replyTo); +#else + mailMessage.ReplyToList.Add(new MailAddress(m_replyTo)); +#endif } mailMessage.Subject = m_subject; mailMessage.Priority = m_mailPriority; diff --git a/src/Config/XmlConfigurator.cs b/src/Config/XmlConfigurator.cs index c7192bc3..ea43a501 100755 --- a/src/Config/XmlConfigurator.cs +++ b/src/Config/XmlConfigurator.cs @@ -728,7 +728,13 @@ static private void InternalConfigure(ILoggerRepository repository, Stream confi #elif NET_2_0 // Allow the DTD to specify entity includes XmlReaderSettings settings = new XmlReaderSettings(); + // .NET 4.0 warning CS0618: 'System.Xml.XmlReaderSettings.ProhibitDtd' + // is obsolete: 'Use XmlReaderSettings.DtdProcessing property instead.' +#if !NET_4_0 settings.ProhibitDtd = false; +#else + settings.DtdProcessing = DtdProcessing.Parse; +#endif // Create a reader over the input stream XmlReader xmlReader = XmlReader.Create(configStream, settings); From d44e1d60ff7939c5ea9b237fc61717e0caeb3612 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 18 Aug 2011 11:03:18 +0000 Subject: [PATCH 010/370] some initial attempts at building with and for .NET 4.0 - requires NAnt 0.91alpha2 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159162 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ log4net.include | 13 ++++++++ 2 files changed, 99 insertions(+) diff --git a/log4net.build b/log4net.build index 9461a11a..19933038 100755 --- a/log4net.build +++ b/log4net.build @@ -121,6 +121,14 @@ limitations under the License. + + + + + + + + @@ -304,6 +312,18 @@ limitations under the License. + + + + + + + + + + + + @@ -724,6 +744,72 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/log4net.include b/log4net.include index 56fa5ab3..60a7ceaa 100755 --- a/log4net.include +++ b/log4net.include @@ -252,6 +252,19 @@ limitations under the License. + + + + + + + + + + + + + From 0de4d9934972011370be1f0f848dc3465f32b067 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 18 Aug 2011 11:28:43 +0000 Subject: [PATCH 011/370] try building/running tests on 4.0 as well, currently fails because of CASPolicy issues git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159170 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 2 +- tests/nant.build | 147 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 1 deletion(-) diff --git a/log4net.build b/log4net.build index 19933038..4af56825 100755 --- a/log4net.build +++ b/log4net.build @@ -312,7 +312,7 @@ limitations under the License. - + diff --git a/tests/nant.build b/tests/nant.build index 5aceb1f4..7e841b6c 100755 --- a/tests/nant.build +++ b/tests/nant.build @@ -77,6 +77,30 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + @@ -301,6 +325,115 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -357,4 +490,18 @@ limitations under the License. + + + + + + + + + + + + + + From a2d90307a12a59fccaa57521e1b41e7db76f562d Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 19 Aug 2011 02:47:30 +0000 Subject: [PATCH 012/370] bump version git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159487 13f79535-47bb-0310-9956-ffa450edef68 --- NOTICE | 4 ++-- src/AssemblyVersionInfo.cpp | 8 ++++---- src/AssemblyVersionInfo.cs | 8 ++++---- src/AssemblyVersionInfo.js | 8 ++++---- src/AssemblyVersionInfo.vb | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/NOTICE b/NOTICE index 0b6c93ab..5a70de11 100755 --- a/NOTICE +++ b/NOTICE @@ -7,7 +7,7 @@ distribution. Apache log4net - Copyright 2001-2007 The Apache Software Foundation + Copyright 2001-2011 The Apache Software Foundation This product includes software developed at - The Apache Software Foundation (http://www.apache.org/). \ No newline at end of file + The Apache Software Foundation (http://www.apache.org/). diff --git a/src/AssemblyVersionInfo.cpp b/src/AssemblyVersionInfo.cpp index 0bd84df3..41b755fa 100755 --- a/src/AssemblyVersionInfo.cpp +++ b/src/AssemblyVersionInfo.cpp @@ -31,12 +31,12 @@ using namespace System::Runtime::CompilerServices; // You can specify all the value or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersionAttribute("1.2.10.0")]; +[assembly: AssemblyVersionAttribute("1.2.11.0")]; [assembly: AssemblyInformationalVersionAttribute("1.2")]; #if !NETCF #if !SSCLI -[assembly: AssemblyFileVersionAttribute("1.2.10.0")] +[assembly: AssemblyFileVersionAttribute("1.2.11.0")] #endif #endif @@ -45,5 +45,5 @@ using namespace System::Runtime::CompilerServices; // [assembly: AssemblyCompany("The Apache Software Foundation")]; -[assembly: AssemblyCopyright("Copyright 2001-2007 The Apache Software Foundation.")]; -[assembly: AssemblyTrademark("Copyright 2001-2007 The Apache Software Foundation.")]; +[assembly: AssemblyCopyright("Copyright 2001-2011 The Apache Software Foundation.")]; +[assembly: AssemblyTrademark("Copyright 2001-2011 The Apache Software Foundation.")]; diff --git a/src/AssemblyVersionInfo.cs b/src/AssemblyVersionInfo.cs index 86db947f..51d7025d 100755 --- a/src/AssemblyVersionInfo.cs +++ b/src/AssemblyVersionInfo.cs @@ -28,12 +28,12 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: System.Reflection.AssemblyVersion("1.2.10.0")] +[assembly: System.Reflection.AssemblyVersion("1.2.11.0")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.2")] #if !NETCF #if !SSCLI -[assembly: System.Reflection.AssemblyFileVersion("1.2.10.0")] +[assembly: System.Reflection.AssemblyFileVersion("1.2.11.0")] #endif #endif @@ -42,5 +42,5 @@ // [assembly: System.Reflection.AssemblyCompany("The Apache Software Foundation")] -[assembly: System.Reflection.AssemblyCopyright("Copyright 2001-2007 The Apache Software Foundation.")] -[assembly: System.Reflection.AssemblyTrademark("Copyright 2001-2007 The Apache Software Foundation.")] +[assembly: System.Reflection.AssemblyCopyright("Copyright 2001-2011 The Apache Software Foundation.")] +[assembly: System.Reflection.AssemblyTrademark("Copyright 2001-2011 The Apache Software Foundation.")] diff --git a/src/AssemblyVersionInfo.js b/src/AssemblyVersionInfo.js index f4ab3b2d..6429a3c8 100755 --- a/src/AssemblyVersionInfo.js +++ b/src/AssemblyVersionInfo.js @@ -31,12 +31,12 @@ // an import functions as a workaround for this issue. import System.Reflection; -[assembly: AssemblyVersion("1.2.10.0")] +[assembly: AssemblyVersion("1.2.11.0")] [assembly: AssemblyInformationalVersionAttribute("1.2")] @if (!@NETCF) @if (!@SSCLI) -[assembly: AssemblyFileVersion("1.2.10.0")] +[assembly: AssemblyFileVersion("1.2.11.0")] @end @end @@ -45,5 +45,5 @@ import System.Reflection; // [assembly: AssemblyCompany("The Apache Software Foundation")] -[assembly: AssemblyCopyright("Copyright 2001-2007 The Apache Software Foundation.")] -[assembly: AssemblyTrademark("Copyright 2001-2007 The Apache Software Foundation.")] +[assembly: AssemblyCopyright("Copyright 2001-2011 The Apache Software Foundation.")] +[assembly: AssemblyTrademark("Copyright 2001-2011 The Apache Software Foundation.")] diff --git a/src/AssemblyVersionInfo.vb b/src/AssemblyVersionInfo.vb index 60746364..8f34c921 100644 --- a/src/AssemblyVersionInfo.vb +++ b/src/AssemblyVersionInfo.vb @@ -28,12 +28,12 @@ ' You can specify all the values or you can default the Revision and Build Numbers ' by using the '*' as shown below: - + #If NOT NETCF Then #If NOT SSCLI Then - + #End If #End If @@ -42,5 +42,5 @@ ' - - + + From fc8becd6967f30c209a753bdaf33c782d68bd4ed Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 19 Aug 2011 12:04:03 +0000 Subject: [PATCH 013/370] log4net enetered incubation in 2004 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159605 13f79535-47bb-0310-9956-ffa450edef68 --- NOTICE | 2 +- .../Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs | 4 ++-- .../Tutorials/WebApp/vb/src/AssemblyVersionInfo.vb | 4 ++-- log4net-sdk.ndoc | 2 +- log4net.build | 2 +- src/AssemblyVersionInfo.cpp | 4 ++-- src/AssemblyVersionInfo.cs | 4 ++-- src/AssemblyVersionInfo.js | 4 ++-- src/AssemblyVersionInfo.vb | 4 ++-- src/Core/TimeEvaluator.cs | 11 ++++++----- xdocs/src/license.xml | 2 +- 11 files changed, 22 insertions(+), 21 deletions(-) diff --git a/NOTICE b/NOTICE index 5a70de11..5a8088d1 100755 --- a/NOTICE +++ b/NOTICE @@ -7,7 +7,7 @@ distribution. Apache log4net - Copyright 2001-2011 The Apache Software Foundation + Copyright 2004-2011 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs b/examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs index b2247686..2c98bcf3 100755 --- a/examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs +++ b/examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs @@ -32,5 +32,5 @@ [assembly: System.Reflection.AssemblyCompany("The Apache Software Foundation")] -[assembly: System.Reflection.AssemblyCopyright("Copyright 2001-2007 The Apache Software Foundation.")] -[assembly: System.Reflection.AssemblyTrademark("Copyright 2001-2007 The Apache Software Foundation.")] +[assembly: System.Reflection.AssemblyCopyright("Copyright 2004-2011 The Apache Software Foundation.")] +[assembly: System.Reflection.AssemblyTrademark("Copyright 2004-2011 The Apache Software Foundation.")] diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyVersionInfo.vb b/examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyVersionInfo.vb index 16a5ff8e..124d1a6a 100644 --- a/examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyVersionInfo.vb +++ b/examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyVersionInfo.vb @@ -32,5 +32,5 @@ - - + + diff --git a/log4net-sdk.ndoc b/log4net-sdk.ndoc index 2317ea1a..86ab61a1 100755 --- a/log4net-sdk.ndoc +++ b/log4net-sdk.ndoc @@ -70,7 +70,7 @@ - + diff --git a/log4net.build b/log4net.build index 4af56825..94b0e454 100755 --- a/log4net.build +++ b/log4net.build @@ -1105,7 +1105,7 @@ limitations under the License. - + diff --git a/src/AssemblyVersionInfo.cpp b/src/AssemblyVersionInfo.cpp index 41b755fa..3b4ed388 100755 --- a/src/AssemblyVersionInfo.cpp +++ b/src/AssemblyVersionInfo.cpp @@ -45,5 +45,5 @@ using namespace System::Runtime::CompilerServices; // [assembly: AssemblyCompany("The Apache Software Foundation")]; -[assembly: AssemblyCopyright("Copyright 2001-2011 The Apache Software Foundation.")]; -[assembly: AssemblyTrademark("Copyright 2001-2011 The Apache Software Foundation.")]; +[assembly: AssemblyCopyright("Copyright 2004-2011 The Apache Software Foundation.")]; +[assembly: AssemblyTrademark("Copyright 2004-2011 The Apache Software Foundation.")]; diff --git a/src/AssemblyVersionInfo.cs b/src/AssemblyVersionInfo.cs index 51d7025d..5ce2adf0 100755 --- a/src/AssemblyVersionInfo.cs +++ b/src/AssemblyVersionInfo.cs @@ -42,5 +42,5 @@ // [assembly: System.Reflection.AssemblyCompany("The Apache Software Foundation")] -[assembly: System.Reflection.AssemblyCopyright("Copyright 2001-2011 The Apache Software Foundation.")] -[assembly: System.Reflection.AssemblyTrademark("Copyright 2001-2011 The Apache Software Foundation.")] +[assembly: System.Reflection.AssemblyCopyright("Copyright 2004-2011 The Apache Software Foundation.")] +[assembly: System.Reflection.AssemblyTrademark("Copyright 2004-2011 The Apache Software Foundation.")] diff --git a/src/AssemblyVersionInfo.js b/src/AssemblyVersionInfo.js index 6429a3c8..172fcb8c 100755 --- a/src/AssemblyVersionInfo.js +++ b/src/AssemblyVersionInfo.js @@ -45,5 +45,5 @@ import System.Reflection; // [assembly: AssemblyCompany("The Apache Software Foundation")] -[assembly: AssemblyCopyright("Copyright 2001-2011 The Apache Software Foundation.")] -[assembly: AssemblyTrademark("Copyright 2001-2011 The Apache Software Foundation.")] +[assembly: AssemblyCopyright("Copyright 2004-2011 The Apache Software Foundation.")] +[assembly: AssemblyTrademark("Copyright 2004-2011 The Apache Software Foundation.")] diff --git a/src/AssemblyVersionInfo.vb b/src/AssemblyVersionInfo.vb index 8f34c921..83373f72 100644 --- a/src/AssemblyVersionInfo.vb +++ b/src/AssemblyVersionInfo.vb @@ -42,5 +42,5 @@ ' - - + + diff --git a/src/Core/TimeEvaluator.cs b/src/Core/TimeEvaluator.cs index 9c1e0012..66ec8f68 100644 --- a/src/Core/TimeEvaluator.cs +++ b/src/Core/TimeEvaluator.cs @@ -1,10 +1,11 @@ #region Copyright & License // -// Copyright 2001-2005 The Apache Software Foundation -// -// Licensed 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 +// 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 // diff --git a/xdocs/src/license.xml b/xdocs/src/license.xml index 8fa813f4..b0e6e5ec 100755 --- a/xdocs/src/license.xml +++ b/xdocs/src/license.xml @@ -252,7 +252,7 @@ limitations under the License. distribution. Apache log4net - Copyright 2001-2007 The Apache Software Foundation + Copyright 2004-2011 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). From aeffa1ef49e68d430857e08ea3c104b8acadca24 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sat, 20 Aug 2011 04:54:09 +0000 Subject: [PATCH 014/370] Make metadata accessible without reflection git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159843 13f79535-47bb-0310-9956-ffa450edef68 --- src/Log4netAssemblyInfo.cs | 88 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/Log4netAssemblyInfo.cs diff --git a/src/Log4netAssemblyInfo.cs b/src/Log4netAssemblyInfo.cs new file mode 100644 index 00000000..c590039b --- /dev/null +++ b/src/Log4netAssemblyInfo.cs @@ -0,0 +1,88 @@ +#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 + +namespace log4net { + + /// + /// Provides information about the environment the assembly has + /// been built for. + /// + public sealed class AssemblyInfo { + /// Version of the assembly + public const string Version = "1.2.11"; + + /// Version of the framework targeted +#if NET_1_1 + public const decimal TargetFrameworkVersion = 1.1M; +#elif NET_4_0 + public const decimal TargetFrameworkVersion = 4.0M; +#elif NET_2_0 || NETCF_2_0 || MONO_2_0 +#if !CLIENT_PROFILE + public const decimal TargetFrameworkVersion = 2.0M; +#else + public const decimal TargetFrameworkVersion = 3.5M; +#endif // Client Profile +#else + public const decimal TargetFrameworkVersion = 1.0M; +#endif + + /// Type of framework targeted +#if CLI + public const string TargetFramework = "CLI Compatible Frameworks"; +#elif NET + public const string TargetFramework = ".NET Framework"; +#elif NETCF + public const string TargetFramework = ".NET Compact Framework"; +#elif MONO + public const string TargetFramework = "Mono"; +#elif SSCLI + public const string TargetFramework = "Shared Source CLI"; +#else + public const string TargetFramework = "Unknown"; +#endif + + /// Does it target a client profile? +#if !CLIENT_PROFILE + public const bool ClientProfile = false; +#else + public const bool ClientProfile = true; +#endif + + /// + /// Identifies the version and target for this assembly. + /// + public static string Info { + get { + return string.Format("Apache log4net version {0} compiled for {1}{2} {3}", + Version, TargetFramework, + /* Can't use + ClientProfile && true ? " Client Profile" : + or the compiler whines about unreachable expressions + */ +#if !CLIENT_PROFILE + string.Empty, +#else + " Client Profile", +#endif + TargetFrameworkVersion); + } + } + } + +} From f88c00a73ee149a0d0457b4467cce9dcdc4dbfb5 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sat, 20 Aug 2011 04:55:17 +0000 Subject: [PATCH 015/370] first attempt at building client profile assemblies git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159844 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 130 ++++++++++++++++++ log4net.include | 26 ++++ src/Appender/AspNetTraceAppender.cs | 2 +- .../Pattern/AspNetCachePatternConverter.cs | 2 +- .../Pattern/AspNetContextPatternConverter.cs | 2 +- src/Layout/Pattern/AspNetPatternConverter.cs | 2 +- .../Pattern/AspNetRequestPatternConverter.cs | 2 +- .../Pattern/AspNetSessionPatternConverter.cs | 2 +- src/Layout/PatternLayout.cs | 2 +- tests/nant.build | 124 +++++++++++++++++ 10 files changed, 287 insertions(+), 7 deletions(-) diff --git a/log4net.build b/log4net.build index 94b0e454..947a40c3 100755 --- a/log4net.build +++ b/log4net.build @@ -303,6 +303,7 @@ limitations under the License. + @@ -315,6 +316,7 @@ limitations under the License. + @@ -745,6 +747,70 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -810,6 +876,70 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/log4net.include b/log4net.include index 60a7ceaa..ab252bb7 100755 --- a/log4net.include +++ b/log4net.include @@ -252,6 +252,19 @@ limitations under the License. + + + + + + + + + + + + + @@ -265,6 +278,19 @@ limitations under the License. + + + + + + + + + + + + + diff --git a/src/Appender/AspNetTraceAppender.cs b/src/Appender/AspNetTraceAppender.cs index e1bdbf44..5e30eca8 100755 --- a/src/Appender/AspNetTraceAppender.cs +++ b/src/Appender/AspNetTraceAppender.cs @@ -19,7 +19,7 @@ // .NET Compact Framework 1.0 has no support for ASP.NET // SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI +#if !NETCF && !SSCLI && !CLIENT_PROFILE using System.Web; diff --git a/src/Layout/Pattern/AspNetCachePatternConverter.cs b/src/Layout/Pattern/AspNetCachePatternConverter.cs index 78564677..4452a5b9 100644 --- a/src/Layout/Pattern/AspNetCachePatternConverter.cs +++ b/src/Layout/Pattern/AspNetCachePatternConverter.cs @@ -19,7 +19,7 @@ // .NET Compact Framework 1.0 has no support for ASP.NET // SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI +#if !NETCF && !SSCLI && !CLIENT_PROFILE using System.IO; using System.Web; diff --git a/src/Layout/Pattern/AspNetContextPatternConverter.cs b/src/Layout/Pattern/AspNetContextPatternConverter.cs index b0d8ccac..61a9e179 100644 --- a/src/Layout/Pattern/AspNetContextPatternConverter.cs +++ b/src/Layout/Pattern/AspNetContextPatternConverter.cs @@ -19,7 +19,7 @@ // .NET Compact Framework 1.0 has no support for ASP.NET // SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI +#if !NETCF && !SSCLI && !CLIENT_PROFILE using System.IO; using System.Web; diff --git a/src/Layout/Pattern/AspNetPatternConverter.cs b/src/Layout/Pattern/AspNetPatternConverter.cs index 6bf756e5..7201ecd4 100644 --- a/src/Layout/Pattern/AspNetPatternConverter.cs +++ b/src/Layout/Pattern/AspNetPatternConverter.cs @@ -19,7 +19,7 @@ // .NET Compact Framework 1.0 has no support for ASP.NET // SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI +#if !NETCF && !SSCLI && !CLIENT_PROFILE using System.IO; using System.Web; diff --git a/src/Layout/Pattern/AspNetRequestPatternConverter.cs b/src/Layout/Pattern/AspNetRequestPatternConverter.cs index 8a601ade..f19837c0 100644 --- a/src/Layout/Pattern/AspNetRequestPatternConverter.cs +++ b/src/Layout/Pattern/AspNetRequestPatternConverter.cs @@ -19,7 +19,7 @@ // .NET Compact Framework 1.0 has no support for ASP.NET // SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI +#if !NETCF && !SSCLI && !CLIENT_PROFILE using System.IO; using System.Web; diff --git a/src/Layout/Pattern/AspNetSessionPatternConverter.cs b/src/Layout/Pattern/AspNetSessionPatternConverter.cs index a83dad5d..f50ad8a5 100644 --- a/src/Layout/Pattern/AspNetSessionPatternConverter.cs +++ b/src/Layout/Pattern/AspNetSessionPatternConverter.cs @@ -19,7 +19,7 @@ // .NET Compact Framework 1.0 has no support for ASP.NET // SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI +#if !NETCF && !SSCLI && !CLIENT_PROFILE using System.IO; using System.Web; diff --git a/src/Layout/PatternLayout.cs b/src/Layout/PatternLayout.cs index 863087be..66ceb387 100755 --- a/src/Layout/PatternLayout.cs +++ b/src/Layout/PatternLayout.cs @@ -816,7 +816,7 @@ static PatternLayout() // .NET Compact Framework 1.0 has no support for ASP.NET // SSCLI 1.0 has no support for ASP.NET -#if !NETCF && !SSCLI +#if !NETCF && !SSCLI && !CLIENT_PROFILE s_globalRulesRegistry.Add("aspnet-cache", typeof(AspNetCachePatternConverter)); s_globalRulesRegistry.Add("aspnet-context", typeof(AspNetContextPatternConverter)); s_globalRulesRegistry.Add("aspnet-request", typeof(AspNetRequestPatternConverter)); diff --git a/tests/nant.build b/tests/nant.build index 7e841b6c..ec9f8441 100755 --- a/tests/nant.build +++ b/tests/nant.build @@ -79,6 +79,7 @@ limitations under the License. + @@ -91,6 +92,7 @@ limitations under the License. + @@ -380,6 +382,60 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -435,6 +491,60 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -497,6 +607,13 @@ limitations under the License. + + + + + + + @@ -504,4 +621,11 @@ limitations under the License. + + + + + + + From ae5ea43b85ef7bdd5b3390e26af2449e5243cccd Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sat, 20 Aug 2011 05:22:22 +0000 Subject: [PATCH 016/370] brand management git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159849 13f79535-47bb-0310-9956-ffa450edef68 --- src/AssemblyInfo.cs | 30 +++++++++++++++--------------- src/AssemblyVersionInfo.cpp | 2 +- src/AssemblyVersionInfo.cs | 2 +- src/AssemblyVersionInfo.js | 2 +- src/AssemblyVersionInfo.vb | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/AssemblyInfo.cs b/src/AssemblyInfo.cs index 89e04cd9..34398e72 100755 --- a/src/AssemblyInfo.cs +++ b/src/AssemblyInfo.cs @@ -46,35 +46,35 @@ // #if (CLI_1_0) -[assembly: AssemblyTitle("log4net for CLI 1.0 Compatible Frameworks")] +[assembly: AssemblyTitle("Apache log4net for CLI 1.0 Compatible Frameworks")] #elif (NET_1_0) -[assembly: AssemblyTitle("log4net for .NET Framework 1.0")] +[assembly: AssemblyTitle("Apache log4net for .NET Framework 1.0")] #elif (NET_1_1) -[assembly: AssemblyTitle("log4net for .NET Framework 1.1")] +[assembly: AssemblyTitle("Apache log4net for .NET Framework 1.1")] #elif (NET_2_0) -[assembly: AssemblyTitle("log4net for .NET Framework 2.0")] +[assembly: AssemblyTitle("Apache log4net for .NET Framework 2.0")] #elif (NETCF_1_0) -[assembly: AssemblyTitle("log4net for .NET Compact Framework 1.0")] +[assembly: AssemblyTitle("Apache log4net for .NET Compact Framework 1.0")] #elif (NETCF_2_0) -[assembly: AssemblyTitle("log4net for .NET Compact Framework 2.0")] +[assembly: AssemblyTitle("Apache log4net for .NET Compact Framework 2.0")] #elif (MONO_1_0) -[assembly: AssemblyTitle("log4net for Mono 1.0")] +[assembly: AssemblyTitle("Apache log4net for Mono 1.0")] #elif (MONO_2_0) -[assembly: AssemblyTitle("log4net for Mono 2.0")] +[assembly: AssemblyTitle("Apache log4net for Mono 2.0")] #elif (SSCLI_1_0) -[assembly: AssemblyTitle("log4net for Shared Source CLI 1.0")] +[assembly: AssemblyTitle("Apache log4net for Shared Source CLI 1.0")] #elif (CLI_1_0) -[assembly: AssemblyTitle("log4net for CLI Compatible Frameworks")] +[assembly: AssemblyTitle("Apache log4net for CLI Compatible Frameworks")] #elif (NET) -[assembly: AssemblyTitle("log4net for .NET Framework")] +[assembly: AssemblyTitle("Apache log4net for .NET Framework")] #elif (NETCF) -[assembly: AssemblyTitle("log4net for .NET Compact Framework")] +[assembly: AssemblyTitle("Apache log4net for .NET Compact Framework")] #elif (MONO) -[assembly: AssemblyTitle("log4net for Mono")] +[assembly: AssemblyTitle("Apache log4net for Mono")] #elif (SSCLI) -[assembly: AssemblyTitle("log4net for Shared Source CLI")] +[assembly: AssemblyTitle("Apache log4net for Shared Source CLI")] #else -[assembly: AssemblyTitle("log4net")] +[assembly: AssemblyTitle("Apache log4net")] #endif #if DEBUG diff --git a/src/AssemblyVersionInfo.cpp b/src/AssemblyVersionInfo.cpp index 3b4ed388..c09b17c4 100755 --- a/src/AssemblyVersionInfo.cpp +++ b/src/AssemblyVersionInfo.cpp @@ -46,4 +46,4 @@ using namespace System::Runtime::CompilerServices; [assembly: AssemblyCompany("The Apache Software Foundation")]; [assembly: AssemblyCopyright("Copyright 2004-2011 The Apache Software Foundation.")]; -[assembly: AssemblyTrademark("Copyright 2004-2011 The Apache Software Foundation.")]; +[assembly: AssemblyTrademark("Apache and Apache log4net are trademarks of The Apache Software Foundation")]; diff --git a/src/AssemblyVersionInfo.cs b/src/AssemblyVersionInfo.cs index 5ce2adf0..bd490118 100755 --- a/src/AssemblyVersionInfo.cs +++ b/src/AssemblyVersionInfo.cs @@ -43,4 +43,4 @@ [assembly: System.Reflection.AssemblyCompany("The Apache Software Foundation")] [assembly: System.Reflection.AssemblyCopyright("Copyright 2004-2011 The Apache Software Foundation.")] -[assembly: System.Reflection.AssemblyTrademark("Copyright 2004-2011 The Apache Software Foundation.")] +[assembly: System.Reflection.AssemblyTrademark("Apache and Apache log4net are trademarks of The Apache Software Foundation")] diff --git a/src/AssemblyVersionInfo.js b/src/AssemblyVersionInfo.js index 172fcb8c..13833a17 100755 --- a/src/AssemblyVersionInfo.js +++ b/src/AssemblyVersionInfo.js @@ -46,4 +46,4 @@ import System.Reflection; [assembly: AssemblyCompany("The Apache Software Foundation")] [assembly: AssemblyCopyright("Copyright 2004-2011 The Apache Software Foundation.")] -[assembly: AssemblyTrademark("Copyright 2004-2011 The Apache Software Foundation.")] +[assembly: AssemblyTrademark("Apache and Apache log4net are trademarks of The Apache Software Foundation")] diff --git a/src/AssemblyVersionInfo.vb b/src/AssemblyVersionInfo.vb index 83373f72..1b35a31b 100644 --- a/src/AssemblyVersionInfo.vb +++ b/src/AssemblyVersionInfo.vb @@ -43,4 +43,4 @@ - + From 95d1b754d6903a6a66a0034fa70891aa171916d8 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sun, 21 Aug 2011 04:58:57 +0000 Subject: [PATCH 017/370] set AssemblyTitle properly for the builds targeting 4.0 and Client Profiles git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1159943 13f79535-47bb-0310-9956-ffa450edef68 --- src/AssemblyInfo.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/AssemblyInfo.cs b/src/AssemblyInfo.cs index 34398e72..01a49427 100755 --- a/src/AssemblyInfo.cs +++ b/src/AssemblyInfo.cs @@ -51,8 +51,18 @@ [assembly: AssemblyTitle("Apache log4net for .NET Framework 1.0")] #elif (NET_1_1) [assembly: AssemblyTitle("Apache log4net for .NET Framework 1.1")] +#elif (NET_4_0) +#if CLIENT_PROFILE +[assembly: AssemblyTitle("Apache log4net for .NET Framework 4.0 Client Profile")] +#else +[assembly: AssemblyTitle("Apache log4net for .NET Framework 4.0")] +#endif // Client Profile #elif (NET_2_0) +#if CLIENT_PROFILE +[assembly: AssemblyTitle("Apache log4net for .NET Framework 3.5 Client Profile")] +#else [assembly: AssemblyTitle("Apache log4net for .NET Framework 2.0")] +#endif // Client Profile #elif (NETCF_1_0) [assembly: AssemblyTitle("Apache log4net for .NET Compact Framework 1.0")] #elif (NETCF_2_0) From 42bba605a8e40700c443f8b958b998094b7d044b Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sun, 4 Sep 2011 04:14:17 +0000 Subject: [PATCH 018/370] remove executable flags git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1164961 13f79535-47bb-0310-9956-ffa450edef68 --- KEYS.txt | 0 LICENSE | 0 NOTICE | 0 README.txt | 0 STATUS.txt | 0 doc/contributing.html | 0 doc/downloads.html | 0 doc/history.html | 0 doc/index.html | 0 doc/license.html | 0 doc/release/building.html | 0 doc/release/config-examples.html | 0 doc/release/example-apps.html | 0 doc/release/faq.html | 0 doc/release/features.html | 0 doc/release/framework-support.html | 0 doc/release/howto/chainsaw.html | 0 doc/release/howto/index.html | 0 doc/release/manual/configuration.html | 0 doc/release/manual/contexts.html | 0 doc/release/manual/internals.html | 0 doc/release/manual/introduction.html | 0 doc/release/manual/plugins.html | 0 doc/release/manual/repositories.html | 0 doc/release/release-notes.html | 0 doc/roadmap.html | 0 doc/support.html | 0 .../SimpleApp/cs/src/SimpleApp.exe.log4net | 0 .../SimpleModule/cs/src/SimpleModule.dll.log4net | 0 .../Repository/SharedModule/js/src/AssemblyInfo.js | 0 .../net/1.1/Repository/SharedModule/js/src/Math.js | 0 .../1.1/Repository/SimpleApp/js/src/AssemblyInfo.js | 0 .../1.1/Repository/SimpleApp/js/src/EntryPoint.js | 0 .../SimpleApp/js/src/SimpleApp.exe.log4net | 0 .../Repository/SimpleModule/js/src/AssemblyInfo.js | 0 .../net/1.1/Repository/SimpleModule/js/src/Math.js | 0 .../SimpleModule/js/src/SimpleModule.dll.log4net | 0 .../Tutorials/ConsoleApp/cpp/src/AssemblyInfo.cpp | 0 .../1.1/Tutorials/ConsoleApp/cpp/src/ConsoleApp.cpp | 0 .../1.1/Tutorials/ConsoleApp/js/src/AssemblyInfo.js | 0 .../Tutorials/ConsoleApp/js/src/LoggingExample.js | 0 .../cs/src/Appender/SimpleSmtpAppender.cs | 0 .../SampleAppendersApp/cs/src/AssemblyInfo.cs | 0 .../SampleAppendersApp/cs/src/LoggingExample.cs | 0 .../2.0/Extensibility/EventIDLogApp/cs/nant.build | 0 .../2.0/Extensibility/EventIDLogApp/cs/nant.config | 0 .../Extensibility/EventIDLogApp/cs/src/App.config | 0 .../EventIDLogApp/cs/src/AssemblyInfo.cs | 0 .../EventIDLogApp/cs/src/EventIDLogApp.cs | 0 .../EventIDLogApp/cs/src/EventIDLogApp.csproj | 0 .../net/2.0/Extensibility/EventIDLogApp/nant.build | 0 .../net/2.0/Extensibility/EventIDLogApp/nant.config | 0 .../net/2.0/Extensibility/TraceLogApp/cs/nant.build | 0 .../2.0/Extensibility/TraceLogApp/cs/nant.config | 0 .../TraceLogApp/cs/src/AssemblyInfo.cs | 0 .../Extensibility/TraceLogApp/cs/src/TraceLogApp.cs | 0 .../TraceLogApp/cs/src/TraceLogApp.csproj | 0 .../TraceLogApp/cs/src/TraceLogApp.exe.log4net | 0 .../net/2.0/Extensibility/TraceLogApp/nant.build | 0 .../net/2.0/Extensibility/TraceLogApp/nant.config | 0 examples/net/2.0/Extensibility/nant.build | 0 examples/net/2.0/Extensibility/nant.config | 0 .../net/2.0/Layouts/SampleLayoutsApp/cs/nant.build | 0 .../net/2.0/Layouts/SampleLayoutsApp/cs/nant.config | 0 .../2.0/Layouts/SampleLayoutsApp/cs/src/App.config | 0 .../Layouts/SampleLayoutsApp/cs/src/AssemblyInfo.cs | 0 .../cs/src/Layout/ForwardingLayout.cs | 0 .../cs/src/Layout/LineWrappingLayout.cs | 0 .../SampleLayoutsApp/cs/src/LoggingExample.cs | 0 .../SampleLayoutsApp/cs/src/SampleLayoutsApp.csproj | 0 .../net/2.0/Layouts/SampleLayoutsApp/nant.build | 0 .../net/2.0/Layouts/SampleLayoutsApp/nant.config | 0 examples/net/2.0/Layouts/nant.build | 0 examples/net/2.0/Layouts/nant.config | 0 .../net/2.0/Performance/NotLogging/cs/nant.build | 0 .../net/2.0/Performance/NotLogging/cs/nant.config | 0 .../Performance/NotLogging/cs/src/AssemblyInfo.cs | 0 .../2.0/Performance/NotLogging/cs/src/NotLogging.cs | 0 .../Performance/NotLogging/cs/src/NotLogging.csproj | 0 examples/net/2.0/Performance/NotLogging/nant.build | 0 examples/net/2.0/Performance/NotLogging/nant.config | 0 .../net/2.0/Performance/NotLogging/vb/nant.build | 0 .../net/2.0/Performance/NotLogging/vb/nant.config | 0 .../Performance/NotLogging/vb/src/NotLogging.vbproj | 0 examples/net/2.0/Performance/nant.build | 0 examples/net/2.0/Performance/nant.config | 0 .../net/2.0/Remoting/RemotingClient/cs/nant.build | 0 .../net/2.0/Remoting/RemotingClient/cs/nant.config | 0 .../2.0/Remoting/RemotingClient/cs/src/App.config | 0 .../Remoting/RemotingClient/cs/src/AssemblyInfo.cs | 0 .../RemotingClient/cs/src/RemotingClient.cs | 0 .../RemotingClient/cs/src/RemotingClient.csproj | 0 examples/net/2.0/Remoting/RemotingClient/nant.build | 0 .../net/2.0/Remoting/RemotingClient/nant.config | 0 .../net/2.0/Remoting/RemotingServer/cs/nant.build | 0 .../net/2.0/Remoting/RemotingServer/cs/nant.config | 0 .../2.0/Remoting/RemotingServer/cs/src/App.config | 0 .../Remoting/RemotingServer/cs/src/AssemblyInfo.cs | 0 .../RemotingServer/cs/src/RemotingServer.cs | 0 .../RemotingServer/cs/src/RemotingServer.csproj | 0 examples/net/2.0/Remoting/RemotingServer/nant.build | 0 .../net/2.0/Remoting/RemotingServer/nant.config | 0 examples/net/2.0/Remoting/nant.build | 0 examples/net/2.0/Remoting/nant.config | 0 .../net/2.0/Repository/SharedModule/cs/nant.build | 0 .../net/2.0/Repository/SharedModule/cs/nant.config | 0 .../Repository/SharedModule/cs/src/AssemblyInfo.cs | 0 .../net/2.0/Repository/SharedModule/cs/src/Math.cs | 0 .../SharedModule/cs/src/SharedModule.csproj | 0 examples/net/2.0/Repository/SharedModule/nant.build | 0 .../net/2.0/Repository/SharedModule/nant.config | 0 .../net/2.0/Repository/SharedModule/vb/nant.build | 0 .../net/2.0/Repository/SharedModule/vb/nant.config | 0 .../SharedModule/vb/src/SharedModule.vbproj | 0 examples/net/2.0/Repository/SimpleApp/cs/nant.build | 0 .../net/2.0/Repository/SimpleApp/cs/nant.config | 0 .../net/2.0/Repository/SimpleApp/cs/src/App.config | 0 .../2.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs | 0 .../2.0/Repository/SimpleApp/cs/src/EntryPoint.cs | 0 .../Repository/SimpleApp/cs/src/SimpleApp.csproj | 0 .../SimpleApp/cs/src/SimpleApp.exe.log4net | 0 examples/net/2.0/Repository/SimpleApp/nant.build | 0 examples/net/2.0/Repository/SimpleApp/nant.config | 0 examples/net/2.0/Repository/SimpleApp/vb/nant.build | 0 .../net/2.0/Repository/SimpleApp/vb/nant.config | 0 .../net/2.0/Repository/SimpleApp/vb/src/App.config | 0 .../SimpleApp/vb/src/SimpleApp.exe.log4net | 0 .../Repository/SimpleApp/vb/src/SimpleApp.vbproj | 0 .../net/2.0/Repository/SimpleModule/cs/nant.build | 0 .../net/2.0/Repository/SimpleModule/cs/nant.config | 0 .../Repository/SimpleModule/cs/src/AssemblyInfo.cs | 0 .../net/2.0/Repository/SimpleModule/cs/src/Math.cs | 0 .../SimpleModule/cs/src/SimpleModule.csproj | 0 .../SimpleModule/cs/src/SimpleModule.dll.log4net | 0 examples/net/2.0/Repository/SimpleModule/nant.build | 0 .../net/2.0/Repository/SimpleModule/nant.config | 0 .../net/2.0/Repository/SimpleModule/vb/nant.build | 0 .../net/2.0/Repository/SimpleModule/vb/nant.config | 0 .../SimpleModule/vb/src/SimpleModule.dll.log4net | 0 .../SimpleModule/vb/src/SimpleModule.vbproj | 0 examples/net/2.0/Repository/nant.build | 0 examples/net/2.0/Repository/nant.config | 0 examples/net/2.0/Tutorials/ConsoleApp/cs/nant.build | 0 .../net/2.0/Tutorials/ConsoleApp/cs/nant.config | 0 .../net/2.0/Tutorials/ConsoleApp/cs/src/App.config | 0 .../2.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs | 0 .../Tutorials/ConsoleApp/cs/src/ConsoleApp.csproj | 0 .../Tutorials/ConsoleApp/cs/src/LoggingExample.cs | 0 examples/net/2.0/Tutorials/ConsoleApp/nant.build | 0 examples/net/2.0/Tutorials/ConsoleApp/nant.config | 0 examples/net/2.0/Tutorials/ConsoleApp/vb/nant.build | 0 .../net/2.0/Tutorials/ConsoleApp/vb/nant.config | 0 .../net/2.0/Tutorials/ConsoleApp/vb/src/App.config | 0 .../Tutorials/ConsoleApp/vb/src/ConsoleApp.vbproj | 0 examples/net/2.0/Tutorials/WebApp/cs/nant.build | 0 examples/net/2.0/Tutorials/WebApp/cs/nant.config | 0 .../net/2.0/Tutorials/WebApp/cs/src/AssemblyInfo.cs | 0 .../Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs | 0 .../net/2.0/Tutorials/WebApp/cs/src/Global.asax.cs | 0 .../2.0/Tutorials/WebApp/cs/src/Global.asax.resx | 0 .../WebApp/cs/src/SimpleModule.dll.log4net | 0 examples/net/2.0/Tutorials/WebApp/cs/src/Web.config | 0 .../net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj | 0 .../Tutorials/WebApp/cs/src/WebApp.csproj.webinfo | 0 .../2.0/Tutorials/WebApp/cs/src/WebApp.dll.log4net | 0 .../net/2.0/Tutorials/WebApp/cs/src/WebApp.vsdisco | 0 .../2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.cs | 0 .../2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.resx | 0 examples/net/2.0/Tutorials/WebApp/nant.build | 0 examples/net/2.0/Tutorials/WebApp/nant.config | 0 examples/net/2.0/Tutorials/WebApp/readme.txt | 0 examples/net/2.0/Tutorials/WebApp/vb/nant.build | 0 examples/net/2.0/Tutorials/WebApp/vb/nant.config | 0 .../2.0/Tutorials/WebApp/vb/src/Global.asax.resx | 0 .../WebApp/vb/src/SimpleModule.dll.log4net | 0 examples/net/2.0/Tutorials/WebApp/vb/src/Web.config | 0 .../2.0/Tutorials/WebApp/vb/src/WebApp.dll.log4net | 0 .../net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj | 0 .../Tutorials/WebApp/vb/src/WebApp.vbproj.webinfo | 0 .../net/2.0/Tutorials/WebApp/vb/src/WebApp.vsdisco | 0 .../2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.resx | 0 examples/net/2.0/Tutorials/nant.build | 0 examples/net/2.0/Tutorials/nant.config | 0 examples/net/2.0/nant.build | 0 examples/net/2.0/nant.config | 0 examples/net/nant.build | 0 examples/net/nant.config | 0 .../netcf/1.0/Tutorials/ConsoleApp/cs/nant.build | 0 .../netcf/1.0/Tutorials/ConsoleApp/cs/nant.config | 0 .../1.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs | 0 .../Tutorials/ConsoleApp/cs/src/ConsoleApp.csdproj | 0 .../ConsoleApp/cs/src/ConsoleApp.exe.config | 0 .../1.0/Tutorials/ConsoleApp/cs/src/EntryPoint.cs | 0 .../Tutorials/ConsoleApp/cs/src/LoggingExample.cs | 0 examples/netcf/1.0/Tutorials/ConsoleApp/nant.build | 0 examples/netcf/1.0/Tutorials/ConsoleApp/nant.config | 0 .../netcf/1.0/Tutorials/ConsoleApp/vb/nant.build | 0 .../netcf/1.0/Tutorials/ConsoleApp/vb/nant.config | 0 .../ConsoleApp/vb/src/ConsoleApp.exe.config | 0 .../Tutorials/ConsoleApp/vb/src/ConsoleApp.vbdproj | 0 examples/netcf/1.0/Tutorials/nant.build | 0 examples/netcf/1.0/Tutorials/nant.config | 0 examples/netcf/1.0/nant.build | 0 examples/netcf/1.0/nant.config | 0 examples/netcf/nant.build | 0 examples/netcf/nant.config | 0 .../sscli/1.0/Repository/SharedModule/cs/nant.build | 0 .../1.0/Repository/SharedModule/cs/nant.config | 0 .../Repository/SharedModule/cs/src/AssemblyInfo.cs | 0 .../1.0/Repository/SharedModule/cs/src/Math.cs | 0 .../sscli/1.0/Repository/SharedModule/nant.build | 0 .../sscli/1.0/Repository/SharedModule/nant.config | 0 .../sscli/1.0/Repository/SimpleApp/cs/nant.build | 0 .../sscli/1.0/Repository/SimpleApp/cs/nant.config | 0 .../1.0/Repository/SimpleApp/cs/src/App.config | 0 .../1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs | 0 .../1.0/Repository/SimpleApp/cs/src/EntryPoint.cs | 0 .../SimpleApp/cs/src/SimpleApp.exe.log4net | 0 examples/sscli/1.0/Repository/SimpleApp/nant.build | 0 examples/sscli/1.0/Repository/SimpleApp/nant.config | 0 .../sscli/1.0/Repository/SimpleModule/cs/nant.build | 0 .../1.0/Repository/SimpleModule/cs/nant.config | 0 .../Repository/SimpleModule/cs/src/AssemblyInfo.cs | 0 .../1.0/Repository/SimpleModule/cs/src/Math.cs | 0 .../SimpleModule/cs/src/SimpleModule.dll.log4net | 0 .../sscli/1.0/Repository/SimpleModule/nant.build | 0 .../sscli/1.0/Repository/SimpleModule/nant.config | 0 examples/sscli/1.0/Repository/nant.build | 0 examples/sscli/1.0/Repository/nant.config | 0 .../sscli/1.0/Tutorials/ConsoleApp/js/nant.build | 0 .../sscli/1.0/Tutorials/ConsoleApp/js/nant.config | 0 .../1.0/Tutorials/ConsoleApp/js/src/App.config | 0 .../1.0/Tutorials/ConsoleApp/js/src/AssemblyInfo.js | 0 .../Tutorials/ConsoleApp/js/src/LoggingExample.js | 0 examples/sscli/1.0/Tutorials/ConsoleApp/nant.build | 0 examples/sscli/1.0/Tutorials/ConsoleApp/nant.config | 0 examples/sscli/1.0/Tutorials/nant.build | 0 examples/sscli/1.0/Tutorials/nant.config | 0 examples/sscli/1.0/nant.build | 0 examples/sscli/1.0/nant.config | 0 examples/sscli/nant.build | 0 examples/sscli/nant.config | 0 extensions/nant.build | 0 extensions/nant.config | 0 .../net/1.0/log4net.Ext.EventID/cs/nant.build | 0 .../net/1.0/log4net.Ext.EventID/cs/nant.config | 0 .../1.0/log4net.Ext.EventID/cs/src/AssemblyInfo.cs | 0 .../log4net.Ext.EventID/cs/src/EventIDLogImpl.cs | 0 .../log4net.Ext.EventID/cs/src/EventIDLogManager.cs | 0 .../1.0/log4net.Ext.EventID/cs/src/IEventIDLog.cs | 0 .../cs/src/log4net.Ext.EventID.csproj | 0 extensions/net/1.0/log4net.Ext.EventID/nant.build | 0 extensions/net/1.0/log4net.Ext.EventID/nant.config | 0 .../net/1.0/log4net.Ext.MarshalByRef/cs/nant.build | 0 .../net/1.0/log4net.Ext.MarshalByRef/cs/nant.config | 0 .../log4net.Ext.MarshalByRef/cs/src/AssemblyInfo.cs | 0 .../cs/src/MarshalByRefLogImpl.cs | 0 .../cs/src/MarshalByRefLogManager.cs | 0 .../cs/src/log4net.Ext.MarshalByRef.csproj | 0 .../net/1.0/log4net.Ext.MarshalByRef/nant.build | 0 .../net/1.0/log4net.Ext.MarshalByRef/nant.config | 0 extensions/net/1.0/log4net.Ext.Trace/cs/nant.build | 0 extensions/net/1.0/log4net.Ext.Trace/cs/nant.config | 0 .../1.0/log4net.Ext.Trace/cs/src/AssemblyInfo.cs | 0 .../net/1.0/log4net.Ext.Trace/cs/src/ITraceLog.cs | 0 .../1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs | 0 .../1.0/log4net.Ext.Trace/cs/src/TraceLogManager.cs | 0 .../cs/src/log4net.Ext.Trace.csproj | 0 extensions/net/1.0/log4net.Ext.Trace/nant.build | 0 extensions/net/1.0/log4net.Ext.Trace/nant.config | 0 extensions/net/1.0/nant.build | 0 extensions/net/1.0/nant.config | 0 extensions/net/nant.build | 0 extensions/net/nant.config | 0 log4net-sdk.ndoc | 0 log4net.build | 0 log4net.include | 0 log4net.snk.readme | 0 src/Appender/AdoNetAppender.cs | 0 src/Appender/AnsiColorTerminalAppender.cs | 0 src/Appender/AppenderCollection.cs | 0 src/Appender/AppenderSkeleton.cs | 0 src/Appender/AspNetTraceAppender.cs | 0 src/Appender/BufferingAppenderSkeleton.cs | 0 src/Appender/BufferingForwardingAppender.cs | 0 src/Appender/ColoredConsoleAppender.cs | 0 src/Appender/ConsoleAppender.cs | 0 src/Appender/DebugAppender.cs | 0 src/Appender/EventLogAppender.cs | 0 src/Appender/FileAppender.cs | 0 src/Appender/ForwardingAppender.cs | 0 src/Appender/IAppender.cs | 0 src/Appender/IBulkAppender.cs | 0 src/Appender/LocalSyslogAppender.cs | 0 src/Appender/MemoryAppender.cs | 0 src/Appender/NetSendAppender.cs | 0 src/Appender/OutputDebugStringAppender.cs | 0 src/Appender/RemoteSyslogAppender.cs | 0 src/Appender/RemotingAppender.cs | 0 src/Appender/RollingFileAppender.cs | 0 src/Appender/SmtpAppender.cs | 0 src/Appender/SmtpPickupDirAppender.cs | 0 src/Appender/TelnetAppender.cs | 0 src/Appender/TextWriterAppender.cs | 0 src/Appender/TraceAppender.cs | 0 src/Appender/UdpAppender.cs | 0 src/AssemblyInfo.cs | 0 src/AssemblyVersionInfo.cpp | 0 src/AssemblyVersionInfo.cs | 0 src/AssemblyVersionInfo.js | 0 src/Config/AliasDomainAttribute.cs | 0 src/Config/AliasRepositoryAttribute.cs | 0 src/Config/BasicConfigurator.cs | 0 src/Config/ConfiguratorAttribute.cs | 0 src/Config/DOMConfigurator.cs | 0 src/Config/DOMConfiguratorAttribute.cs | 0 src/Config/DomainAttribute.cs | 0 src/Config/Log4NetConfigurationSectionHandler.cs | 0 src/Config/PluginAttribute.cs | 0 src/Config/RepositoryAttribute.cs | 0 src/Config/SecurityContextProviderAttribute.cs | 0 src/Config/XmlConfigurator.cs | 0 src/Config/XmlConfiguratorAttribute.cs | 0 src/Core/CompactRepositorySelector.cs | 0 src/Core/DefaultRepositorySelector.cs | 0 src/Core/ErrorCode.cs | 0 src/Core/IAppenderAttachable.cs | 0 src/Core/IErrorHandler.cs | 0 src/Core/IFixingRequired.cs | 0 src/Core/ILogger.cs | 0 src/Core/ILoggerWrapper.cs | 0 src/Core/IOptionHandler.cs | 0 src/Core/IRepositorySelector.cs | 0 src/Core/ITriggeringEventEvaluator.cs | 0 src/Core/Level.cs | 0 src/Core/LevelCollection.cs | 0 src/Core/LevelEvaluator.cs | 0 src/Core/LevelMap.cs | 0 src/Core/LocationInfo.cs | 0 src/Core/LogException.cs | 0 src/Core/LogImpl.cs | 0 src/Core/LoggerManager.cs | 0 src/Core/LoggerWrapperImpl.cs | 0 src/Core/LoggingEvent.cs | 0 src/Core/SecurityContext.cs | 0 src/Core/SecurityContextProvider.cs | 0 src/Core/WrapperMap.cs | 0 src/DateFormatter/AbsoluteTimeDateFormatter.cs | 0 src/DateFormatter/DateTimeDateFormatter.cs | 0 src/DateFormatter/IDateFormatter.cs | 0 src/DateFormatter/Iso8601DateFormatter.cs | 0 src/DateFormatter/SimpleDateFormatter.cs | 0 src/Filter/DenyAllFilter.cs | 0 src/Filter/FilterDecision.cs | 0 src/Filter/FilterSkeleton.cs | 0 src/Filter/IFilter.cs | 0 src/Filter/LevelMatchFilter.cs | 0 src/Filter/LevelRangeFilter.cs | 0 src/Filter/LoggerMatchFilter.cs | 0 src/Filter/MdcFilter.cs | 0 src/Filter/NdcFilter.cs | 0 src/Filter/PropertyFilter.cs | 0 src/Filter/StringMatchFilter.cs | 0 src/GlobalContext.cs | 0 src/ILog.cs | 0 src/Layout/ExceptionLayout.cs | 0 src/Layout/ILayout.cs | 0 src/Layout/IRawLayout.cs | 0 src/Layout/Layout2RawLayoutAdapter.cs | 0 src/Layout/LayoutSkeleton.cs | 0 src/Layout/Pattern/AppDomainPatternConverter.cs | 0 src/Layout/Pattern/DatePatternConverter.cs | 0 src/Layout/Pattern/ExceptionPatternConverter.cs | 0 src/Layout/Pattern/FileLocationPatternConverter.cs | 0 src/Layout/Pattern/FullLocationPatternConverter.cs | 0 src/Layout/Pattern/IdentityPatternConverter.cs | 0 src/Layout/Pattern/LevelPatternConverter.cs | 0 src/Layout/Pattern/LineLocationPatternConverter.cs | 0 src/Layout/Pattern/LoggerPatternConverter.cs | 0 src/Layout/Pattern/MessagePatternConverter.cs | 0 .../Pattern/MethodLocationPatternConverter.cs | 0 src/Layout/Pattern/NamedPatternConverter.cs | 0 src/Layout/Pattern/NdcPatternConverter.cs | 0 src/Layout/Pattern/PatternLayoutConverter.cs | 0 src/Layout/Pattern/PropertyPatternConverter.cs | 0 src/Layout/Pattern/RelativeTimePatternConverter.cs | 0 src/Layout/Pattern/ThreadPatternConverter.cs | 0 src/Layout/Pattern/TypeNamePatternConverter.cs | 0 src/Layout/Pattern/UserNamePatternConverter.cs | 0 src/Layout/Pattern/UtcDatePatternConverter.cs | 0 src/Layout/PatternLayout.cs | 0 src/Layout/RawLayoutConverter.cs | 0 src/Layout/RawPropertyLayout.cs | 0 src/Layout/RawTimeStampLayout.cs | 0 src/Layout/RawUtcTimeStampLayout.cs | 0 src/Layout/SimpleLayout.cs | 0 src/Layout/XMLLayout.cs | 0 src/Layout/XMLLayoutBase.cs | 0 src/Layout/XmlLayoutSchemaLog4j.cs | 0 src/LogManager.cs | 0 src/LogicalThreadContext.cs | 0 src/MDC.cs | 0 src/NDC.cs | 0 src/ObjectRenderer/DefaultRenderer.cs | 0 src/ObjectRenderer/IObjectRenderer.cs | 0 src/ObjectRenderer/RendererMap.cs | 0 src/Plugin/IPlugin.cs | 0 src/Plugin/IPluginFactory.cs | 0 src/Plugin/PluginCollection.cs | 0 src/Plugin/PluginMap.cs | 0 src/Plugin/PluginSkeleton.cs | 0 src/Plugin/RemoteLoggingServerPlugin.cs | 0 src/Repository/Hierarchy/DefaultLoggerFactory.cs | 0 src/Repository/Hierarchy/Hierarchy.cs | 0 src/Repository/Hierarchy/ILoggerFactory.cs | 0 src/Repository/Hierarchy/Logger.cs | 0 src/Repository/Hierarchy/LoggerKey.cs | 0 src/Repository/Hierarchy/ProvisionNode.cs | 0 src/Repository/Hierarchy/RootLogger.cs | 0 .../Hierarchy/XmlHierarchyConfigurator.cs | 0 src/Repository/IBasicRepositoryConfigurator.cs | 0 src/Repository/ILoggerRepository.cs | 0 src/Repository/IXmlRepositoryConfigurator.cs | 0 src/Repository/LoggerRepositorySkeleton.cs | 0 src/ThreadContext.cs | 0 src/Util/AppenderAttachedImpl.cs | 0 src/Util/CompositeProperties.cs | 0 src/Util/ContextPropertiesBase.cs | 0 src/Util/CountingQuietTextWriter.cs | 0 src/Util/CyclicBuffer.cs | 0 src/Util/EmptyCollection.cs | 0 src/Util/EmptyDictionary.cs | 0 src/Util/FormattingInfo.cs | 0 src/Util/GlobalContextProperties.cs | 0 src/Util/LevelMapping.cs | 0 src/Util/LevelMappingEntry.cs | 0 src/Util/LogLog.cs | 0 src/Util/LogicalThreadContextProperties.cs | 0 src/Util/NativeError.cs | 0 src/Util/NullDictionaryEnumerator.cs | 0 src/Util/NullEnumerator.cs | 0 src/Util/NullSecurityContext.cs | 0 src/Util/OnlyOnceErrorHandler.cs | 0 src/Util/OptionConverter.cs | 0 src/Util/PatternConverter.cs | 0 src/Util/PatternParser.cs | 0 src/Util/PatternString.cs | 0 .../AppDomainPatternConverter.cs | 0 .../PatternStringConverters/DatePatternConverter.cs | 0 .../EnvironmentPatternConverter.cs | 0 .../IdentityPatternConverter.cs | 0 .../LiteralPatternConverter.cs | 0 .../NewLinePatternConverter.cs | 0 .../ProcessIdPatternConverter.cs | 0 .../PropertyPatternConverter.cs | 0 .../RandomStringPatternConverter.cs | 0 .../UserNamePatternConverter.cs | 0 .../UtcDatePatternConverter.cs | 0 src/Util/PropertiesDictionary.cs | 0 src/Util/ProtectCloseTextWriter.cs | 0 src/Util/QuietTextWriter.cs | 0 src/Util/ReadOnlyPropertiesDictionary.cs | 0 src/Util/ReaderWriterLock.cs | 0 src/Util/ReusableStringWriter.cs | 0 src/Util/SystemInfo.cs | 0 src/Util/TextWriterAdapter.cs | 0 src/Util/ThreadContextProperties.cs | 0 src/Util/ThreadContextStack.cs | 0 src/Util/ThreadContextStacks.cs | 0 src/Util/Transform.cs | 0 src/Util/TypeConverters/BooleanConverter.cs | 0 .../ConversionNotSupportedException.cs | 0 src/Util/TypeConverters/ConverterRegistry.cs | 0 src/Util/TypeConverters/EncodingConverter.cs | 0 src/Util/TypeConverters/IConvertFrom.cs | 0 src/Util/TypeConverters/IConvertTo.cs | 0 src/Util/TypeConverters/IPAddressConverter.cs | 0 src/Util/TypeConverters/PatternLayoutConverter.cs | 0 src/Util/TypeConverters/PatternStringConverter.cs | 0 src/Util/TypeConverters/TypeConverter.cs | 0 src/Util/TypeConverters/TypeConverterAttribute.cs | 0 src/Util/WindowsSecurityContext.cs | 0 src/site/resources/images/ls-logo.jpg | Bin src/site/xdoc/history.xml | 0 src/site/xdoc/index.xml | 0 src/site/xdoc/release/building.xml | 0 src/site/xdoc/release/config-examples.xml | 0 src/site/xdoc/release/example-apps.xml | 0 src/site/xdoc/release/faq.xml | 0 src/site/xdoc/release/features.xml | 0 src/site/xdoc/release/framework-support.xml | 0 src/site/xdoc/release/howto/chainsaw.xml | 0 src/site/xdoc/release/howto/index.xml | 0 src/site/xdoc/release/manual/configuration.xml | 0 src/site/xdoc/release/manual/contexts.xml | 0 src/site/xdoc/release/manual/internals.xml | 0 src/site/xdoc/release/manual/introduction.xml | 0 src/site/xdoc/release/manual/plugins.xml | 0 src/site/xdoc/release/manual/repositories.xml | 0 src/site/xdoc/release/release-notes.xml | 0 src/site/xdoc/stylesheets/project.xml | 0 src/site/xdoc/stylesheets/site.vsl | 0 tests/nant.build | 0 tests/src/Appender/BufferingAppenderTest.cs | 0 tests/src/Appender/CountingAppender.cs | 0 tests/src/Appender/EventLogAppenderTest.cs | 0 tests/src/Appender/RemotingAppenderTest.cs | 0 tests/src/Appender/RollingFileAppenderTest.cs | 0 tests/src/Appender/StringAppender.cs | 0 tests/src/AssemblyInfo.cs | 0 tests/src/Context/ThreadContextTest.cs | 0 tests/src/Core/ShutdownTest.cs | 0 tests/src/Hierarchy/Logger.cs | 0 tests/src/Layout/PatternLayoutTest.cs | 0 tests/src/Layout/XmlLayoutTest.cs | 0 tests/src/Util/CyclicBufferTest.cs | 0 tests/src/Util/PropertiesDictionaryTest.cs | 0 tests/src/Util/RandomStringPatternConverterTest.cs | 0 tests/src/Util/SystemInfoTest.cs | 0 tests/src/Utils.cs | 0 xdocs/build.xml | 0 xdocs/src/contributing.xml | 0 xdocs/src/downloads.xml | 0 xdocs/src/history.xml | 0 xdocs/src/index.xml | 0 xdocs/src/license.xml | 0 xdocs/src/release/building.xml | 0 xdocs/src/release/config-examples.xml | 0 xdocs/src/release/example-apps.xml | 0 xdocs/src/release/faq.xml | 0 xdocs/src/release/features.xml | 0 xdocs/src/release/framework-support.xml | 0 xdocs/src/release/howto/chainsaw.xml | 0 xdocs/src/release/howto/index.xml | 0 xdocs/src/release/manual/configuration.xml | 0 xdocs/src/release/manual/contexts.xml | 0 xdocs/src/release/manual/internals.xml | 0 xdocs/src/release/manual/introduction.xml | 0 xdocs/src/release/manual/plugins.xml | 0 xdocs/src/release/manual/repositories.xml | 0 xdocs/src/release/release-notes.xml | 0 xdocs/src/roadmap.xml | 0 xdocs/src/stylesheets/project.xml | 0 xdocs/src/stylesheets/site.vsl | 0 xdocs/src/support.xml | 0 545 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 KEYS.txt mode change 100755 => 100644 LICENSE mode change 100755 => 100644 NOTICE mode change 100755 => 100644 README.txt mode change 100755 => 100644 STATUS.txt mode change 100755 => 100644 doc/contributing.html mode change 100755 => 100644 doc/downloads.html mode change 100755 => 100644 doc/history.html mode change 100755 => 100644 doc/index.html mode change 100755 => 100644 doc/license.html mode change 100755 => 100644 doc/release/building.html mode change 100755 => 100644 doc/release/config-examples.html mode change 100755 => 100644 doc/release/example-apps.html mode change 100755 => 100644 doc/release/faq.html mode change 100755 => 100644 doc/release/features.html mode change 100755 => 100644 doc/release/framework-support.html mode change 100755 => 100644 doc/release/howto/chainsaw.html mode change 100755 => 100644 doc/release/howto/index.html mode change 100755 => 100644 doc/release/manual/configuration.html mode change 100755 => 100644 doc/release/manual/contexts.html mode change 100755 => 100644 doc/release/manual/internals.html mode change 100755 => 100644 doc/release/manual/introduction.html mode change 100755 => 100644 doc/release/manual/plugins.html mode change 100755 => 100644 doc/release/manual/repositories.html mode change 100755 => 100644 doc/release/release-notes.html mode change 100755 => 100644 doc/roadmap.html mode change 100755 => 100644 doc/support.html mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net mode change 100755 => 100644 examples/mono/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net mode change 100755 => 100644 examples/net/1.1/Repository/SharedModule/js/src/AssemblyInfo.js mode change 100755 => 100644 examples/net/1.1/Repository/SharedModule/js/src/Math.js mode change 100755 => 100644 examples/net/1.1/Repository/SimpleApp/js/src/AssemblyInfo.js mode change 100755 => 100644 examples/net/1.1/Repository/SimpleApp/js/src/EntryPoint.js mode change 100755 => 100644 examples/net/1.1/Repository/SimpleApp/js/src/SimpleApp.exe.log4net mode change 100755 => 100644 examples/net/1.1/Repository/SimpleModule/js/src/AssemblyInfo.js mode change 100755 => 100644 examples/net/1.1/Repository/SimpleModule/js/src/Math.js mode change 100755 => 100644 examples/net/1.1/Repository/SimpleModule/js/src/SimpleModule.dll.log4net mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/src/AssemblyInfo.cpp mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/src/ConsoleApp.cpp mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/js/src/AssemblyInfo.js mode change 100755 => 100644 examples/net/1.1/Tutorials/ConsoleApp/js/src/LoggingExample.js mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/SimpleSmtpAppender.cs mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/LoggingExample.cs mode change 100755 => 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/src/App.config mode change 100755 => 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/src/EventIDLogApp.cs mode change 100755 => 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/src/EventIDLogApp.csproj mode change 100755 => 100644 examples/net/2.0/Extensibility/EventIDLogApp/nant.build mode change 100755 => 100644 examples/net/2.0/Extensibility/EventIDLogApp/nant.config mode change 100755 => 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.cs mode change 100755 => 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.csproj mode change 100755 => 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.exe.log4net mode change 100755 => 100644 examples/net/2.0/Extensibility/TraceLogApp/nant.build mode change 100755 => 100644 examples/net/2.0/Extensibility/TraceLogApp/nant.config mode change 100755 => 100644 examples/net/2.0/Extensibility/nant.build mode change 100755 => 100644 examples/net/2.0/Extensibility/nant.config mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/App.config mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/ForwardingLayout.cs mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LineWrappingLayout.cs mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/LoggingExample.cs mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/SampleLayoutsApp.csproj mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/nant.build mode change 100755 => 100644 examples/net/2.0/Layouts/SampleLayoutsApp/nant.config mode change 100755 => 100644 examples/net/2.0/Layouts/nant.build mode change 100755 => 100644 examples/net/2.0/Layouts/nant.config mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.cs mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.csproj mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/nant.build mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/nant.config mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/vb/nant.build mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/vb/nant.config mode change 100755 => 100644 examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vbproj mode change 100755 => 100644 examples/net/2.0/Performance/nant.build mode change 100755 => 100644 examples/net/2.0/Performance/nant.config mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingClient/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingClient/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingClient/cs/src/App.config mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingClient/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingClient/cs/src/RemotingClient.cs mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingClient/cs/src/RemotingClient.csproj mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingClient/nant.build mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingClient/nant.config mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingServer/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingServer/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingServer/cs/src/App.config mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingServer/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.cs mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.csproj mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingServer/nant.build mode change 100755 => 100644 examples/net/2.0/Remoting/RemotingServer/nant.config mode change 100755 => 100644 examples/net/2.0/Remoting/nant.build mode change 100755 => 100644 examples/net/2.0/Remoting/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/cs/src/Math.cs mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/cs/src/SharedModule.csproj mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/vb/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/vb/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SharedModule/vb/src/SharedModule.vbproj mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/cs/src/App.config mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/cs/src/EntryPoint.cs mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.csproj mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/vb/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/vb/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/vb/src/App.config mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.exe.log4net mode change 100755 => 100644 examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.vbproj mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/cs/src/Math.cs mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/cs/src/SimpleModule.csproj mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/vb/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/vb/nant.config mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.dll.log4net mode change 100755 => 100644 examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.vbproj mode change 100755 => 100644 examples/net/2.0/Repository/nant.build mode change 100755 => 100644 examples/net/2.0/Repository/nant.config mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/src/App.config mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csproj mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/nant.build mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/nant.config mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/nant.build mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/nant.config mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/src/App.config mode change 100755 => 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.vbproj mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/nant.build mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/nant.config mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.cs mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.resx mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/SimpleModule.dll.log4net mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/Web.config mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj.webinfo mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.dll.log4net mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.vsdisco mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.cs mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.resx mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/nant.build mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/nant.config mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/readme.txt mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/nant.build mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/nant.config mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.resx mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/SimpleModule.dll.log4net mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/Web.config mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.dll.log4net mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj.webinfo mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vsdisco mode change 100755 => 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.resx mode change 100755 => 100644 examples/net/2.0/Tutorials/nant.build mode change 100755 => 100644 examples/net/2.0/Tutorials/nant.config mode change 100755 => 100644 examples/net/2.0/nant.build mode change 100755 => 100644 examples/net/2.0/nant.config mode change 100755 => 100644 examples/net/nant.build mode change 100755 => 100644 examples/net/nant.config mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/nant.build mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/nant.config mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csdproj mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.exe.config mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/EntryPoint.cs mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/nant.build mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/nant.config mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/nant.build mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/nant.config mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.exe.config mode change 100755 => 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.vbdproj mode change 100755 => 100644 examples/netcf/1.0/Tutorials/nant.build mode change 100755 => 100644 examples/netcf/1.0/Tutorials/nant.config mode change 100755 => 100644 examples/netcf/1.0/nant.build mode change 100755 => 100644 examples/netcf/1.0/nant.config mode change 100755 => 100644 examples/netcf/nant.build mode change 100755 => 100644 examples/netcf/nant.config mode change 100755 => 100644 examples/sscli/1.0/Repository/SharedModule/cs/nant.build mode change 100755 => 100644 examples/sscli/1.0/Repository/SharedModule/cs/nant.config mode change 100755 => 100644 examples/sscli/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/sscli/1.0/Repository/SharedModule/cs/src/Math.cs mode change 100755 => 100644 examples/sscli/1.0/Repository/SharedModule/nant.build mode change 100755 => 100644 examples/sscli/1.0/Repository/SharedModule/nant.config mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleApp/cs/nant.build mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleApp/cs/nant.config mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleApp/cs/src/App.config mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleApp/nant.build mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleApp/nant.config mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleModule/cs/nant.build mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleModule/cs/nant.config mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleModule/cs/src/Math.cs mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleModule/nant.build mode change 100755 => 100644 examples/sscli/1.0/Repository/SimpleModule/nant.config mode change 100755 => 100644 examples/sscli/1.0/Repository/nant.build mode change 100755 => 100644 examples/sscli/1.0/Repository/nant.config mode change 100755 => 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/nant.build mode change 100755 => 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/nant.config mode change 100755 => 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/src/App.config mode change 100755 => 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/src/AssemblyInfo.js mode change 100755 => 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/src/LoggingExample.js mode change 100755 => 100644 examples/sscli/1.0/Tutorials/ConsoleApp/nant.build mode change 100755 => 100644 examples/sscli/1.0/Tutorials/ConsoleApp/nant.config mode change 100755 => 100644 examples/sscli/1.0/Tutorials/nant.build mode change 100755 => 100644 examples/sscli/1.0/Tutorials/nant.config mode change 100755 => 100644 examples/sscli/1.0/nant.build mode change 100755 => 100644 examples/sscli/1.0/nant.config mode change 100755 => 100644 examples/sscli/nant.build mode change 100755 => 100644 examples/sscli/nant.config mode change 100755 => 100644 extensions/nant.build mode change 100755 => 100644 extensions/nant.config mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.EventID/cs/nant.build mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.EventID/cs/nant.config mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/AssemblyInfo.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/EventIDLogImpl.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/EventIDLogManager.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/IEventIDLog.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/log4net.Ext.EventID.csproj mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.EventID/nant.build mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.EventID/nant.config mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/nant.build mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/nant.config mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/AssemblyInfo.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/MarshalByRefLogImpl.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/MarshalByRefLogManager.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/log4net.Ext.MarshalByRef.csproj mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/nant.build mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/nant.config mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.Trace/cs/nant.build mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.Trace/cs/nant.config mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/AssemblyInfo.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/ITraceLog.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogManager.cs mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/log4net.Ext.Trace.csproj mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.Trace/nant.build mode change 100755 => 100644 extensions/net/1.0/log4net.Ext.Trace/nant.config mode change 100755 => 100644 extensions/net/1.0/nant.build mode change 100755 => 100644 extensions/net/1.0/nant.config mode change 100755 => 100644 extensions/net/nant.build mode change 100755 => 100644 extensions/net/nant.config mode change 100755 => 100644 log4net-sdk.ndoc mode change 100755 => 100644 log4net.build mode change 100755 => 100644 log4net.include mode change 100755 => 100644 log4net.snk.readme mode change 100755 => 100644 src/Appender/AdoNetAppender.cs mode change 100755 => 100644 src/Appender/AnsiColorTerminalAppender.cs mode change 100755 => 100644 src/Appender/AppenderCollection.cs mode change 100755 => 100644 src/Appender/AppenderSkeleton.cs mode change 100755 => 100644 src/Appender/AspNetTraceAppender.cs mode change 100755 => 100644 src/Appender/BufferingAppenderSkeleton.cs mode change 100755 => 100644 src/Appender/BufferingForwardingAppender.cs mode change 100755 => 100644 src/Appender/ColoredConsoleAppender.cs mode change 100755 => 100644 src/Appender/ConsoleAppender.cs mode change 100755 => 100644 src/Appender/DebugAppender.cs mode change 100755 => 100644 src/Appender/EventLogAppender.cs mode change 100755 => 100644 src/Appender/FileAppender.cs mode change 100755 => 100644 src/Appender/ForwardingAppender.cs mode change 100755 => 100644 src/Appender/IAppender.cs mode change 100755 => 100644 src/Appender/IBulkAppender.cs mode change 100755 => 100644 src/Appender/LocalSyslogAppender.cs mode change 100755 => 100644 src/Appender/MemoryAppender.cs mode change 100755 => 100644 src/Appender/NetSendAppender.cs mode change 100755 => 100644 src/Appender/OutputDebugStringAppender.cs mode change 100755 => 100644 src/Appender/RemoteSyslogAppender.cs mode change 100755 => 100644 src/Appender/RemotingAppender.cs mode change 100755 => 100644 src/Appender/RollingFileAppender.cs mode change 100755 => 100644 src/Appender/SmtpAppender.cs mode change 100755 => 100644 src/Appender/SmtpPickupDirAppender.cs mode change 100755 => 100644 src/Appender/TelnetAppender.cs mode change 100755 => 100644 src/Appender/TextWriterAppender.cs mode change 100755 => 100644 src/Appender/TraceAppender.cs mode change 100755 => 100644 src/Appender/UdpAppender.cs mode change 100755 => 100644 src/AssemblyInfo.cs mode change 100755 => 100644 src/AssemblyVersionInfo.cpp mode change 100755 => 100644 src/AssemblyVersionInfo.cs mode change 100755 => 100644 src/AssemblyVersionInfo.js mode change 100755 => 100644 src/Config/AliasDomainAttribute.cs mode change 100755 => 100644 src/Config/AliasRepositoryAttribute.cs mode change 100755 => 100644 src/Config/BasicConfigurator.cs mode change 100755 => 100644 src/Config/ConfiguratorAttribute.cs mode change 100755 => 100644 src/Config/DOMConfigurator.cs mode change 100755 => 100644 src/Config/DOMConfiguratorAttribute.cs mode change 100755 => 100644 src/Config/DomainAttribute.cs mode change 100755 => 100644 src/Config/Log4NetConfigurationSectionHandler.cs mode change 100755 => 100644 src/Config/PluginAttribute.cs mode change 100755 => 100644 src/Config/RepositoryAttribute.cs mode change 100755 => 100644 src/Config/SecurityContextProviderAttribute.cs mode change 100755 => 100644 src/Config/XmlConfigurator.cs mode change 100755 => 100644 src/Config/XmlConfiguratorAttribute.cs mode change 100755 => 100644 src/Core/CompactRepositorySelector.cs mode change 100755 => 100644 src/Core/DefaultRepositorySelector.cs mode change 100755 => 100644 src/Core/ErrorCode.cs mode change 100755 => 100644 src/Core/IAppenderAttachable.cs mode change 100755 => 100644 src/Core/IErrorHandler.cs mode change 100755 => 100644 src/Core/IFixingRequired.cs mode change 100755 => 100644 src/Core/ILogger.cs mode change 100755 => 100644 src/Core/ILoggerWrapper.cs mode change 100755 => 100644 src/Core/IOptionHandler.cs mode change 100755 => 100644 src/Core/IRepositorySelector.cs mode change 100755 => 100644 src/Core/ITriggeringEventEvaluator.cs mode change 100755 => 100644 src/Core/Level.cs mode change 100755 => 100644 src/Core/LevelCollection.cs mode change 100755 => 100644 src/Core/LevelEvaluator.cs mode change 100755 => 100644 src/Core/LevelMap.cs mode change 100755 => 100644 src/Core/LocationInfo.cs mode change 100755 => 100644 src/Core/LogException.cs mode change 100755 => 100644 src/Core/LogImpl.cs mode change 100755 => 100644 src/Core/LoggerManager.cs mode change 100755 => 100644 src/Core/LoggerWrapperImpl.cs mode change 100755 => 100644 src/Core/LoggingEvent.cs mode change 100755 => 100644 src/Core/SecurityContext.cs mode change 100755 => 100644 src/Core/SecurityContextProvider.cs mode change 100755 => 100644 src/Core/WrapperMap.cs mode change 100755 => 100644 src/DateFormatter/AbsoluteTimeDateFormatter.cs mode change 100755 => 100644 src/DateFormatter/DateTimeDateFormatter.cs mode change 100755 => 100644 src/DateFormatter/IDateFormatter.cs mode change 100755 => 100644 src/DateFormatter/Iso8601DateFormatter.cs mode change 100755 => 100644 src/DateFormatter/SimpleDateFormatter.cs mode change 100755 => 100644 src/Filter/DenyAllFilter.cs mode change 100755 => 100644 src/Filter/FilterDecision.cs mode change 100755 => 100644 src/Filter/FilterSkeleton.cs mode change 100755 => 100644 src/Filter/IFilter.cs mode change 100755 => 100644 src/Filter/LevelMatchFilter.cs mode change 100755 => 100644 src/Filter/LevelRangeFilter.cs mode change 100755 => 100644 src/Filter/LoggerMatchFilter.cs mode change 100755 => 100644 src/Filter/MdcFilter.cs mode change 100755 => 100644 src/Filter/NdcFilter.cs mode change 100755 => 100644 src/Filter/PropertyFilter.cs mode change 100755 => 100644 src/Filter/StringMatchFilter.cs mode change 100755 => 100644 src/GlobalContext.cs mode change 100755 => 100644 src/ILog.cs mode change 100755 => 100644 src/Layout/ExceptionLayout.cs mode change 100755 => 100644 src/Layout/ILayout.cs mode change 100755 => 100644 src/Layout/IRawLayout.cs mode change 100755 => 100644 src/Layout/Layout2RawLayoutAdapter.cs mode change 100755 => 100644 src/Layout/LayoutSkeleton.cs mode change 100755 => 100644 src/Layout/Pattern/AppDomainPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/DatePatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/ExceptionPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/FileLocationPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/FullLocationPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/IdentityPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/LevelPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/LineLocationPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/LoggerPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/MessagePatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/MethodLocationPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/NamedPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/NdcPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/PatternLayoutConverter.cs mode change 100755 => 100644 src/Layout/Pattern/PropertyPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/RelativeTimePatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/ThreadPatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/TypeNamePatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/UserNamePatternConverter.cs mode change 100755 => 100644 src/Layout/Pattern/UtcDatePatternConverter.cs mode change 100755 => 100644 src/Layout/PatternLayout.cs mode change 100755 => 100644 src/Layout/RawLayoutConverter.cs mode change 100755 => 100644 src/Layout/RawPropertyLayout.cs mode change 100755 => 100644 src/Layout/RawTimeStampLayout.cs mode change 100755 => 100644 src/Layout/RawUtcTimeStampLayout.cs mode change 100755 => 100644 src/Layout/SimpleLayout.cs mode change 100755 => 100644 src/Layout/XMLLayout.cs mode change 100755 => 100644 src/Layout/XMLLayoutBase.cs mode change 100755 => 100644 src/Layout/XmlLayoutSchemaLog4j.cs mode change 100755 => 100644 src/LogManager.cs mode change 100755 => 100644 src/LogicalThreadContext.cs mode change 100755 => 100644 src/MDC.cs mode change 100755 => 100644 src/NDC.cs mode change 100755 => 100644 src/ObjectRenderer/DefaultRenderer.cs mode change 100755 => 100644 src/ObjectRenderer/IObjectRenderer.cs mode change 100755 => 100644 src/ObjectRenderer/RendererMap.cs mode change 100755 => 100644 src/Plugin/IPlugin.cs mode change 100755 => 100644 src/Plugin/IPluginFactory.cs mode change 100755 => 100644 src/Plugin/PluginCollection.cs mode change 100755 => 100644 src/Plugin/PluginMap.cs mode change 100755 => 100644 src/Plugin/PluginSkeleton.cs mode change 100755 => 100644 src/Plugin/RemoteLoggingServerPlugin.cs mode change 100755 => 100644 src/Repository/Hierarchy/DefaultLoggerFactory.cs mode change 100755 => 100644 src/Repository/Hierarchy/Hierarchy.cs mode change 100755 => 100644 src/Repository/Hierarchy/ILoggerFactory.cs mode change 100755 => 100644 src/Repository/Hierarchy/Logger.cs mode change 100755 => 100644 src/Repository/Hierarchy/LoggerKey.cs mode change 100755 => 100644 src/Repository/Hierarchy/ProvisionNode.cs mode change 100755 => 100644 src/Repository/Hierarchy/RootLogger.cs mode change 100755 => 100644 src/Repository/Hierarchy/XmlHierarchyConfigurator.cs mode change 100755 => 100644 src/Repository/IBasicRepositoryConfigurator.cs mode change 100755 => 100644 src/Repository/ILoggerRepository.cs mode change 100755 => 100644 src/Repository/IXmlRepositoryConfigurator.cs mode change 100755 => 100644 src/Repository/LoggerRepositorySkeleton.cs mode change 100755 => 100644 src/ThreadContext.cs mode change 100755 => 100644 src/Util/AppenderAttachedImpl.cs mode change 100755 => 100644 src/Util/CompositeProperties.cs mode change 100755 => 100644 src/Util/ContextPropertiesBase.cs mode change 100755 => 100644 src/Util/CountingQuietTextWriter.cs mode change 100755 => 100644 src/Util/CyclicBuffer.cs mode change 100755 => 100644 src/Util/EmptyCollection.cs mode change 100755 => 100644 src/Util/EmptyDictionary.cs mode change 100755 => 100644 src/Util/FormattingInfo.cs mode change 100755 => 100644 src/Util/GlobalContextProperties.cs mode change 100755 => 100644 src/Util/LevelMapping.cs mode change 100755 => 100644 src/Util/LevelMappingEntry.cs mode change 100755 => 100644 src/Util/LogLog.cs mode change 100755 => 100644 src/Util/LogicalThreadContextProperties.cs mode change 100755 => 100644 src/Util/NativeError.cs mode change 100755 => 100644 src/Util/NullDictionaryEnumerator.cs mode change 100755 => 100644 src/Util/NullEnumerator.cs mode change 100755 => 100644 src/Util/NullSecurityContext.cs mode change 100755 => 100644 src/Util/OnlyOnceErrorHandler.cs mode change 100755 => 100644 src/Util/OptionConverter.cs mode change 100755 => 100644 src/Util/PatternConverter.cs mode change 100755 => 100644 src/Util/PatternParser.cs mode change 100755 => 100644 src/Util/PatternString.cs mode change 100755 => 100644 src/Util/PatternStringConverters/AppDomainPatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/DatePatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/EnvironmentPatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/IdentityPatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/LiteralPatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/NewLinePatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/ProcessIdPatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/PropertyPatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/RandomStringPatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/UserNamePatternConverter.cs mode change 100755 => 100644 src/Util/PatternStringConverters/UtcDatePatternConverter.cs mode change 100755 => 100644 src/Util/PropertiesDictionary.cs mode change 100755 => 100644 src/Util/ProtectCloseTextWriter.cs mode change 100755 => 100644 src/Util/QuietTextWriter.cs mode change 100755 => 100644 src/Util/ReadOnlyPropertiesDictionary.cs mode change 100755 => 100644 src/Util/ReaderWriterLock.cs mode change 100755 => 100644 src/Util/ReusableStringWriter.cs mode change 100755 => 100644 src/Util/SystemInfo.cs mode change 100755 => 100644 src/Util/TextWriterAdapter.cs mode change 100755 => 100644 src/Util/ThreadContextProperties.cs mode change 100755 => 100644 src/Util/ThreadContextStack.cs mode change 100755 => 100644 src/Util/ThreadContextStacks.cs mode change 100755 => 100644 src/Util/Transform.cs mode change 100755 => 100644 src/Util/TypeConverters/BooleanConverter.cs mode change 100755 => 100644 src/Util/TypeConverters/ConversionNotSupportedException.cs mode change 100755 => 100644 src/Util/TypeConverters/ConverterRegistry.cs mode change 100755 => 100644 src/Util/TypeConverters/EncodingConverter.cs mode change 100755 => 100644 src/Util/TypeConverters/IConvertFrom.cs mode change 100755 => 100644 src/Util/TypeConverters/IConvertTo.cs mode change 100755 => 100644 src/Util/TypeConverters/IPAddressConverter.cs mode change 100755 => 100644 src/Util/TypeConverters/PatternLayoutConverter.cs mode change 100755 => 100644 src/Util/TypeConverters/PatternStringConverter.cs mode change 100755 => 100644 src/Util/TypeConverters/TypeConverter.cs mode change 100755 => 100644 src/Util/TypeConverters/TypeConverterAttribute.cs mode change 100755 => 100644 src/Util/WindowsSecurityContext.cs mode change 100755 => 100644 src/site/resources/images/ls-logo.jpg mode change 100755 => 100644 src/site/xdoc/history.xml mode change 100755 => 100644 src/site/xdoc/index.xml mode change 100755 => 100644 src/site/xdoc/release/building.xml mode change 100755 => 100644 src/site/xdoc/release/config-examples.xml mode change 100755 => 100644 src/site/xdoc/release/example-apps.xml mode change 100755 => 100644 src/site/xdoc/release/faq.xml mode change 100755 => 100644 src/site/xdoc/release/features.xml mode change 100755 => 100644 src/site/xdoc/release/framework-support.xml mode change 100755 => 100644 src/site/xdoc/release/howto/chainsaw.xml mode change 100755 => 100644 src/site/xdoc/release/howto/index.xml mode change 100755 => 100644 src/site/xdoc/release/manual/configuration.xml mode change 100755 => 100644 src/site/xdoc/release/manual/contexts.xml mode change 100755 => 100644 src/site/xdoc/release/manual/internals.xml mode change 100755 => 100644 src/site/xdoc/release/manual/introduction.xml mode change 100755 => 100644 src/site/xdoc/release/manual/plugins.xml mode change 100755 => 100644 src/site/xdoc/release/manual/repositories.xml mode change 100755 => 100644 src/site/xdoc/release/release-notes.xml mode change 100755 => 100644 src/site/xdoc/stylesheets/project.xml mode change 100755 => 100644 src/site/xdoc/stylesheets/site.vsl mode change 100755 => 100644 tests/nant.build mode change 100755 => 100644 tests/src/Appender/BufferingAppenderTest.cs mode change 100755 => 100644 tests/src/Appender/CountingAppender.cs mode change 100755 => 100644 tests/src/Appender/EventLogAppenderTest.cs mode change 100755 => 100644 tests/src/Appender/RemotingAppenderTest.cs mode change 100755 => 100644 tests/src/Appender/RollingFileAppenderTest.cs mode change 100755 => 100644 tests/src/Appender/StringAppender.cs mode change 100755 => 100644 tests/src/AssemblyInfo.cs mode change 100755 => 100644 tests/src/Context/ThreadContextTest.cs mode change 100755 => 100644 tests/src/Core/ShutdownTest.cs mode change 100755 => 100644 tests/src/Hierarchy/Logger.cs mode change 100755 => 100644 tests/src/Layout/PatternLayoutTest.cs mode change 100755 => 100644 tests/src/Layout/XmlLayoutTest.cs mode change 100755 => 100644 tests/src/Util/CyclicBufferTest.cs mode change 100755 => 100644 tests/src/Util/PropertiesDictionaryTest.cs mode change 100755 => 100644 tests/src/Util/RandomStringPatternConverterTest.cs mode change 100755 => 100644 tests/src/Util/SystemInfoTest.cs mode change 100755 => 100644 tests/src/Utils.cs mode change 100755 => 100644 xdocs/build.xml mode change 100755 => 100644 xdocs/src/contributing.xml mode change 100755 => 100644 xdocs/src/downloads.xml mode change 100755 => 100644 xdocs/src/history.xml mode change 100755 => 100644 xdocs/src/index.xml mode change 100755 => 100644 xdocs/src/license.xml mode change 100755 => 100644 xdocs/src/release/building.xml mode change 100755 => 100644 xdocs/src/release/config-examples.xml mode change 100755 => 100644 xdocs/src/release/example-apps.xml mode change 100755 => 100644 xdocs/src/release/faq.xml mode change 100755 => 100644 xdocs/src/release/features.xml mode change 100755 => 100644 xdocs/src/release/framework-support.xml mode change 100755 => 100644 xdocs/src/release/howto/chainsaw.xml mode change 100755 => 100644 xdocs/src/release/howto/index.xml mode change 100755 => 100644 xdocs/src/release/manual/configuration.xml mode change 100755 => 100644 xdocs/src/release/manual/contexts.xml mode change 100755 => 100644 xdocs/src/release/manual/internals.xml mode change 100755 => 100644 xdocs/src/release/manual/introduction.xml mode change 100755 => 100644 xdocs/src/release/manual/plugins.xml mode change 100755 => 100644 xdocs/src/release/manual/repositories.xml mode change 100755 => 100644 xdocs/src/release/release-notes.xml mode change 100755 => 100644 xdocs/src/roadmap.xml mode change 100755 => 100644 xdocs/src/stylesheets/project.xml mode change 100755 => 100644 xdocs/src/stylesheets/site.vsl mode change 100755 => 100644 xdocs/src/support.xml diff --git a/KEYS.txt b/KEYS.txt old mode 100755 new mode 100644 diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 diff --git a/NOTICE b/NOTICE old mode 100755 new mode 100644 diff --git a/README.txt b/README.txt old mode 100755 new mode 100644 diff --git a/STATUS.txt b/STATUS.txt old mode 100755 new mode 100644 diff --git a/doc/contributing.html b/doc/contributing.html old mode 100755 new mode 100644 diff --git a/doc/downloads.html b/doc/downloads.html old mode 100755 new mode 100644 diff --git a/doc/history.html b/doc/history.html old mode 100755 new mode 100644 diff --git a/doc/index.html b/doc/index.html old mode 100755 new mode 100644 diff --git a/doc/license.html b/doc/license.html old mode 100755 new mode 100644 diff --git a/doc/release/building.html b/doc/release/building.html old mode 100755 new mode 100644 diff --git a/doc/release/config-examples.html b/doc/release/config-examples.html old mode 100755 new mode 100644 diff --git a/doc/release/example-apps.html b/doc/release/example-apps.html old mode 100755 new mode 100644 diff --git a/doc/release/faq.html b/doc/release/faq.html old mode 100755 new mode 100644 diff --git a/doc/release/features.html b/doc/release/features.html old mode 100755 new mode 100644 diff --git a/doc/release/framework-support.html b/doc/release/framework-support.html old mode 100755 new mode 100644 diff --git a/doc/release/howto/chainsaw.html b/doc/release/howto/chainsaw.html old mode 100755 new mode 100644 diff --git a/doc/release/howto/index.html b/doc/release/howto/index.html old mode 100755 new mode 100644 diff --git a/doc/release/manual/configuration.html b/doc/release/manual/configuration.html old mode 100755 new mode 100644 diff --git a/doc/release/manual/contexts.html b/doc/release/manual/contexts.html old mode 100755 new mode 100644 diff --git a/doc/release/manual/internals.html b/doc/release/manual/internals.html old mode 100755 new mode 100644 diff --git a/doc/release/manual/introduction.html b/doc/release/manual/introduction.html old mode 100755 new mode 100644 diff --git a/doc/release/manual/plugins.html b/doc/release/manual/plugins.html old mode 100755 new mode 100644 diff --git a/doc/release/manual/repositories.html b/doc/release/manual/repositories.html old mode 100755 new mode 100644 diff --git a/doc/release/release-notes.html b/doc/release/release-notes.html old mode 100755 new mode 100644 diff --git a/doc/roadmap.html b/doc/roadmap.html old mode 100755 new mode 100644 diff --git a/doc/support.html b/doc/support.html old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net b/examples/mono/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net old mode 100755 new mode 100644 diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net b/examples/mono/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SharedModule/js/src/AssemblyInfo.js b/examples/net/1.1/Repository/SharedModule/js/src/AssemblyInfo.js old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SharedModule/js/src/Math.js b/examples/net/1.1/Repository/SharedModule/js/src/Math.js old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleApp/js/src/AssemblyInfo.js b/examples/net/1.1/Repository/SimpleApp/js/src/AssemblyInfo.js old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleApp/js/src/EntryPoint.js b/examples/net/1.1/Repository/SimpleApp/js/src/EntryPoint.js old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleApp/js/src/SimpleApp.exe.log4net b/examples/net/1.1/Repository/SimpleApp/js/src/SimpleApp.exe.log4net old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleModule/js/src/AssemblyInfo.js b/examples/net/1.1/Repository/SimpleModule/js/src/AssemblyInfo.js old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleModule/js/src/Math.js b/examples/net/1.1/Repository/SimpleModule/js/src/Math.js old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Repository/SimpleModule/js/src/SimpleModule.dll.log4net b/examples/net/1.1/Repository/SimpleModule/js/src/SimpleModule.dll.log4net old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/AssemblyInfo.cpp b/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/AssemblyInfo.cpp old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/ConsoleApp.cpp b/examples/net/1.1/Tutorials/ConsoleApp/cpp/src/ConsoleApp.cpp old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/js/src/AssemblyInfo.js b/examples/net/1.1/Tutorials/ConsoleApp/js/src/AssemblyInfo.js old mode 100755 new mode 100644 diff --git a/examples/net/1.1/Tutorials/ConsoleApp/js/src/LoggingExample.js b/examples/net/1.1/Tutorials/ConsoleApp/js/src/LoggingExample.js old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/SimpleSmtpAppender.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/SimpleSmtpAppender.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/AssemblyInfo.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/LoggingExample.cs b/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/LoggingExample.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/EventIDLogApp/cs/nant.build b/examples/net/2.0/Extensibility/EventIDLogApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/EventIDLogApp/cs/nant.config b/examples/net/2.0/Extensibility/EventIDLogApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/App.config b/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/AssemblyInfo.cs b/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/EventIDLogApp.cs b/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/EventIDLogApp.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/EventIDLogApp.csproj b/examples/net/2.0/Extensibility/EventIDLogApp/cs/src/EventIDLogApp.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/EventIDLogApp/nant.build b/examples/net/2.0/Extensibility/EventIDLogApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/EventIDLogApp/nant.config b/examples/net/2.0/Extensibility/EventIDLogApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/TraceLogApp/cs/nant.build b/examples/net/2.0/Extensibility/TraceLogApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/TraceLogApp/cs/nant.config b/examples/net/2.0/Extensibility/TraceLogApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/TraceLogApp/cs/src/AssemblyInfo.cs b/examples/net/2.0/Extensibility/TraceLogApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.cs b/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.csproj b/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.exe.log4net b/examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.exe.log4net old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/TraceLogApp/nant.build b/examples/net/2.0/Extensibility/TraceLogApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/TraceLogApp/nant.config b/examples/net/2.0/Extensibility/TraceLogApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/nant.build b/examples/net/2.0/Extensibility/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Extensibility/nant.config b/examples/net/2.0/Extensibility/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/nant.build b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/nant.config b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/App.config b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/AssemblyInfo.cs b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/ForwardingLayout.cs b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/ForwardingLayout.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LineWrappingLayout.cs b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LineWrappingLayout.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/LoggingExample.cs b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/LoggingExample.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/SampleLayoutsApp.csproj b/examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/SampleLayoutsApp.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/nant.build b/examples/net/2.0/Layouts/SampleLayoutsApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/SampleLayoutsApp/nant.config b/examples/net/2.0/Layouts/SampleLayoutsApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/nant.build b/examples/net/2.0/Layouts/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Layouts/nant.config b/examples/net/2.0/Layouts/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/cs/nant.build b/examples/net/2.0/Performance/NotLogging/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/cs/nant.config b/examples/net/2.0/Performance/NotLogging/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/cs/src/AssemblyInfo.cs b/examples/net/2.0/Performance/NotLogging/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.cs b/examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.csproj b/examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/nant.build b/examples/net/2.0/Performance/NotLogging/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/nant.config b/examples/net/2.0/Performance/NotLogging/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/vb/nant.build b/examples/net/2.0/Performance/NotLogging/vb/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/vb/nant.config b/examples/net/2.0/Performance/NotLogging/vb/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vbproj b/examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vbproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/nant.build b/examples/net/2.0/Performance/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Performance/nant.config b/examples/net/2.0/Performance/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingClient/cs/nant.build b/examples/net/2.0/Remoting/RemotingClient/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingClient/cs/nant.config b/examples/net/2.0/Remoting/RemotingClient/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingClient/cs/src/App.config b/examples/net/2.0/Remoting/RemotingClient/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingClient/cs/src/AssemblyInfo.cs b/examples/net/2.0/Remoting/RemotingClient/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingClient/cs/src/RemotingClient.cs b/examples/net/2.0/Remoting/RemotingClient/cs/src/RemotingClient.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingClient/cs/src/RemotingClient.csproj b/examples/net/2.0/Remoting/RemotingClient/cs/src/RemotingClient.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingClient/nant.build b/examples/net/2.0/Remoting/RemotingClient/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingClient/nant.config b/examples/net/2.0/Remoting/RemotingClient/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingServer/cs/nant.build b/examples/net/2.0/Remoting/RemotingServer/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingServer/cs/nant.config b/examples/net/2.0/Remoting/RemotingServer/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingServer/cs/src/App.config b/examples/net/2.0/Remoting/RemotingServer/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingServer/cs/src/AssemblyInfo.cs b/examples/net/2.0/Remoting/RemotingServer/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.cs b/examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.csproj b/examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingServer/nant.build b/examples/net/2.0/Remoting/RemotingServer/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/RemotingServer/nant.config b/examples/net/2.0/Remoting/RemotingServer/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/nant.build b/examples/net/2.0/Remoting/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Remoting/nant.config b/examples/net/2.0/Remoting/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/cs/nant.build b/examples/net/2.0/Repository/SharedModule/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/cs/nant.config b/examples/net/2.0/Repository/SharedModule/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/cs/src/AssemblyInfo.cs b/examples/net/2.0/Repository/SharedModule/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/cs/src/Math.cs b/examples/net/2.0/Repository/SharedModule/cs/src/Math.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/cs/src/SharedModule.csproj b/examples/net/2.0/Repository/SharedModule/cs/src/SharedModule.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/nant.build b/examples/net/2.0/Repository/SharedModule/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/nant.config b/examples/net/2.0/Repository/SharedModule/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/vb/nant.build b/examples/net/2.0/Repository/SharedModule/vb/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/vb/nant.config b/examples/net/2.0/Repository/SharedModule/vb/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SharedModule/vb/src/SharedModule.vbproj b/examples/net/2.0/Repository/SharedModule/vb/src/SharedModule.vbproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/cs/nant.build b/examples/net/2.0/Repository/SimpleApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/cs/nant.config b/examples/net/2.0/Repository/SimpleApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/cs/src/App.config b/examples/net/2.0/Repository/SimpleApp/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs b/examples/net/2.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/cs/src/EntryPoint.cs b/examples/net/2.0/Repository/SimpleApp/cs/src/EntryPoint.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.csproj b/examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net b/examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/nant.build b/examples/net/2.0/Repository/SimpleApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/nant.config b/examples/net/2.0/Repository/SimpleApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/vb/nant.build b/examples/net/2.0/Repository/SimpleApp/vb/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/vb/nant.config b/examples/net/2.0/Repository/SimpleApp/vb/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/vb/src/App.config b/examples/net/2.0/Repository/SimpleApp/vb/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.exe.log4net b/examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.exe.log4net old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.vbproj b/examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.vbproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/cs/nant.build b/examples/net/2.0/Repository/SimpleModule/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/cs/nant.config b/examples/net/2.0/Repository/SimpleModule/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs b/examples/net/2.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/cs/src/Math.cs b/examples/net/2.0/Repository/SimpleModule/cs/src/Math.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/cs/src/SimpleModule.csproj b/examples/net/2.0/Repository/SimpleModule/cs/src/SimpleModule.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net b/examples/net/2.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/nant.build b/examples/net/2.0/Repository/SimpleModule/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/nant.config b/examples/net/2.0/Repository/SimpleModule/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/vb/nant.build b/examples/net/2.0/Repository/SimpleModule/vb/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/vb/nant.config b/examples/net/2.0/Repository/SimpleModule/vb/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.dll.log4net b/examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.dll.log4net old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.vbproj b/examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.vbproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/nant.build b/examples/net/2.0/Repository/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Repository/nant.config b/examples/net/2.0/Repository/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/cs/nant.build b/examples/net/2.0/Tutorials/ConsoleApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/cs/nant.config b/examples/net/2.0/Tutorials/ConsoleApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/cs/src/App.config b/examples/net/2.0/Tutorials/ConsoleApp/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs b/examples/net/2.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csproj b/examples/net/2.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs b/examples/net/2.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/nant.build b/examples/net/2.0/Tutorials/ConsoleApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/nant.config b/examples/net/2.0/Tutorials/ConsoleApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/vb/nant.build b/examples/net/2.0/Tutorials/ConsoleApp/vb/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/vb/nant.config b/examples/net/2.0/Tutorials/ConsoleApp/vb/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/vb/src/App.config b/examples/net/2.0/Tutorials/ConsoleApp/vb/src/App.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.vbproj b/examples/net/2.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.vbproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/nant.build b/examples/net/2.0/Tutorials/WebApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/nant.config b/examples/net/2.0/Tutorials/WebApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyInfo.cs b/examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs b/examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.cs b/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.resx b/examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.resx old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/SimpleModule.dll.log4net b/examples/net/2.0/Tutorials/WebApp/cs/src/SimpleModule.dll.log4net old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/Web.config b/examples/net/2.0/Tutorials/WebApp/cs/src/Web.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj b/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj.webinfo b/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj.webinfo old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.dll.log4net b/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.dll.log4net old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.vsdisco b/examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.vsdisco old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.cs b/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.cs old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.resx b/examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.resx old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/nant.build b/examples/net/2.0/Tutorials/WebApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/nant.config b/examples/net/2.0/Tutorials/WebApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/readme.txt b/examples/net/2.0/Tutorials/WebApp/readme.txt old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/nant.build b/examples/net/2.0/Tutorials/WebApp/vb/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/nant.config b/examples/net/2.0/Tutorials/WebApp/vb/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.resx b/examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.resx old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/SimpleModule.dll.log4net b/examples/net/2.0/Tutorials/WebApp/vb/src/SimpleModule.dll.log4net old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/Web.config b/examples/net/2.0/Tutorials/WebApp/vb/src/Web.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.dll.log4net b/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.dll.log4net old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj b/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj.webinfo b/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj.webinfo old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vsdisco b/examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vsdisco old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.resx b/examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.resx old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/nant.build b/examples/net/2.0/Tutorials/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/Tutorials/nant.config b/examples/net/2.0/Tutorials/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/2.0/nant.build b/examples/net/2.0/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/2.0/nant.config b/examples/net/2.0/nant.config old mode 100755 new mode 100644 diff --git a/examples/net/nant.build b/examples/net/nant.build old mode 100755 new mode 100644 diff --git a/examples/net/nant.config b/examples/net/nant.config old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/cs/nant.build b/examples/netcf/1.0/Tutorials/ConsoleApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/cs/nant.config b/examples/netcf/1.0/Tutorials/ConsoleApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs b/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csdproj b/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csdproj old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.exe.config b/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.exe.config old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/EntryPoint.cs b/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/EntryPoint.cs old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs b/examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/nant.build b/examples/netcf/1.0/Tutorials/ConsoleApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/nant.config b/examples/netcf/1.0/Tutorials/ConsoleApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/vb/nant.build b/examples/netcf/1.0/Tutorials/ConsoleApp/vb/nant.build old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/vb/nant.config b/examples/netcf/1.0/Tutorials/ConsoleApp/vb/nant.config old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.exe.config b/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.exe.config old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.vbdproj b/examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.vbdproj old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/nant.build b/examples/netcf/1.0/Tutorials/nant.build old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/Tutorials/nant.config b/examples/netcf/1.0/Tutorials/nant.config old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/nant.build b/examples/netcf/1.0/nant.build old mode 100755 new mode 100644 diff --git a/examples/netcf/1.0/nant.config b/examples/netcf/1.0/nant.config old mode 100755 new mode 100644 diff --git a/examples/netcf/nant.build b/examples/netcf/nant.build old mode 100755 new mode 100644 diff --git a/examples/netcf/nant.config b/examples/netcf/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SharedModule/cs/nant.build b/examples/sscli/1.0/Repository/SharedModule/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SharedModule/cs/nant.config b/examples/sscli/1.0/Repository/SharedModule/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs b/examples/sscli/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SharedModule/cs/src/Math.cs b/examples/sscli/1.0/Repository/SharedModule/cs/src/Math.cs old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SharedModule/nant.build b/examples/sscli/1.0/Repository/SharedModule/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SharedModule/nant.config b/examples/sscli/1.0/Repository/SharedModule/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleApp/cs/nant.build b/examples/sscli/1.0/Repository/SimpleApp/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleApp/cs/nant.config b/examples/sscli/1.0/Repository/SimpleApp/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleApp/cs/src/App.config b/examples/sscli/1.0/Repository/SimpleApp/cs/src/App.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs b/examples/sscli/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs b/examples/sscli/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net b/examples/sscli/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleApp/nant.build b/examples/sscli/1.0/Repository/SimpleApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleApp/nant.config b/examples/sscli/1.0/Repository/SimpleApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleModule/cs/nant.build b/examples/sscli/1.0/Repository/SimpleModule/cs/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleModule/cs/nant.config b/examples/sscli/1.0/Repository/SimpleModule/cs/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs b/examples/sscli/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleModule/cs/src/Math.cs b/examples/sscli/1.0/Repository/SimpleModule/cs/src/Math.cs old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net b/examples/sscli/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleModule/nant.build b/examples/sscli/1.0/Repository/SimpleModule/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/SimpleModule/nant.config b/examples/sscli/1.0/Repository/SimpleModule/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/nant.build b/examples/sscli/1.0/Repository/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Repository/nant.config b/examples/sscli/1.0/Repository/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Tutorials/ConsoleApp/js/nant.build b/examples/sscli/1.0/Tutorials/ConsoleApp/js/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Tutorials/ConsoleApp/js/nant.config b/examples/sscli/1.0/Tutorials/ConsoleApp/js/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/App.config b/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/App.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/AssemblyInfo.js b/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/AssemblyInfo.js old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/LoggingExample.js b/examples/sscli/1.0/Tutorials/ConsoleApp/js/src/LoggingExample.js old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Tutorials/ConsoleApp/nant.build b/examples/sscli/1.0/Tutorials/ConsoleApp/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Tutorials/ConsoleApp/nant.config b/examples/sscli/1.0/Tutorials/ConsoleApp/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Tutorials/nant.build b/examples/sscli/1.0/Tutorials/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/Tutorials/nant.config b/examples/sscli/1.0/Tutorials/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/nant.build b/examples/sscli/1.0/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/1.0/nant.config b/examples/sscli/1.0/nant.config old mode 100755 new mode 100644 diff --git a/examples/sscli/nant.build b/examples/sscli/nant.build old mode 100755 new mode 100644 diff --git a/examples/sscli/nant.config b/examples/sscli/nant.config old mode 100755 new mode 100644 diff --git a/extensions/nant.build b/extensions/nant.build old mode 100755 new mode 100644 diff --git a/extensions/nant.config b/extensions/nant.config old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.EventID/cs/nant.build b/extensions/net/1.0/log4net.Ext.EventID/cs/nant.build old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.EventID/cs/nant.config b/extensions/net/1.0/log4net.Ext.EventID/cs/nant.config old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.EventID/cs/src/AssemblyInfo.cs b/extensions/net/1.0/log4net.Ext.EventID/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.EventID/cs/src/EventIDLogImpl.cs b/extensions/net/1.0/log4net.Ext.EventID/cs/src/EventIDLogImpl.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.EventID/cs/src/EventIDLogManager.cs b/extensions/net/1.0/log4net.Ext.EventID/cs/src/EventIDLogManager.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.EventID/cs/src/IEventIDLog.cs b/extensions/net/1.0/log4net.Ext.EventID/cs/src/IEventIDLog.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.EventID/cs/src/log4net.Ext.EventID.csproj b/extensions/net/1.0/log4net.Ext.EventID/cs/src/log4net.Ext.EventID.csproj old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.EventID/nant.build b/extensions/net/1.0/log4net.Ext.EventID/nant.build old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.EventID/nant.config b/extensions/net/1.0/log4net.Ext.EventID/nant.config old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/nant.build b/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/nant.build old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/nant.config b/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/nant.config old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/AssemblyInfo.cs b/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/MarshalByRefLogImpl.cs b/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/MarshalByRefLogImpl.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/MarshalByRefLogManager.cs b/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/MarshalByRefLogManager.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/log4net.Ext.MarshalByRef.csproj b/extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/log4net.Ext.MarshalByRef.csproj old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.MarshalByRef/nant.build b/extensions/net/1.0/log4net.Ext.MarshalByRef/nant.build old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.MarshalByRef/nant.config b/extensions/net/1.0/log4net.Ext.MarshalByRef/nant.config old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.Trace/cs/nant.build b/extensions/net/1.0/log4net.Ext.Trace/cs/nant.build old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.Trace/cs/nant.config b/extensions/net/1.0/log4net.Ext.Trace/cs/nant.config old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.Trace/cs/src/AssemblyInfo.cs b/extensions/net/1.0/log4net.Ext.Trace/cs/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.Trace/cs/src/ITraceLog.cs b/extensions/net/1.0/log4net.Ext.Trace/cs/src/ITraceLog.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs b/extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogManager.cs b/extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogManager.cs old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.Trace/cs/src/log4net.Ext.Trace.csproj b/extensions/net/1.0/log4net.Ext.Trace/cs/src/log4net.Ext.Trace.csproj old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.Trace/nant.build b/extensions/net/1.0/log4net.Ext.Trace/nant.build old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/log4net.Ext.Trace/nant.config b/extensions/net/1.0/log4net.Ext.Trace/nant.config old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/nant.build b/extensions/net/1.0/nant.build old mode 100755 new mode 100644 diff --git a/extensions/net/1.0/nant.config b/extensions/net/1.0/nant.config old mode 100755 new mode 100644 diff --git a/extensions/net/nant.build b/extensions/net/nant.build old mode 100755 new mode 100644 diff --git a/extensions/net/nant.config b/extensions/net/nant.config old mode 100755 new mode 100644 diff --git a/log4net-sdk.ndoc b/log4net-sdk.ndoc old mode 100755 new mode 100644 diff --git a/log4net.build b/log4net.build old mode 100755 new mode 100644 diff --git a/log4net.include b/log4net.include old mode 100755 new mode 100644 diff --git a/log4net.snk.readme b/log4net.snk.readme old mode 100755 new mode 100644 diff --git a/src/Appender/AdoNetAppender.cs b/src/Appender/AdoNetAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/AnsiColorTerminalAppender.cs b/src/Appender/AnsiColorTerminalAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/AppenderCollection.cs b/src/Appender/AppenderCollection.cs old mode 100755 new mode 100644 diff --git a/src/Appender/AppenderSkeleton.cs b/src/Appender/AppenderSkeleton.cs old mode 100755 new mode 100644 diff --git a/src/Appender/AspNetTraceAppender.cs b/src/Appender/AspNetTraceAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/BufferingAppenderSkeleton.cs b/src/Appender/BufferingAppenderSkeleton.cs old mode 100755 new mode 100644 diff --git a/src/Appender/BufferingForwardingAppender.cs b/src/Appender/BufferingForwardingAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/ColoredConsoleAppender.cs b/src/Appender/ColoredConsoleAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/ConsoleAppender.cs b/src/Appender/ConsoleAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/DebugAppender.cs b/src/Appender/DebugAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/FileAppender.cs b/src/Appender/FileAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/ForwardingAppender.cs b/src/Appender/ForwardingAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/IAppender.cs b/src/Appender/IAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/IBulkAppender.cs b/src/Appender/IBulkAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/LocalSyslogAppender.cs b/src/Appender/LocalSyslogAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/MemoryAppender.cs b/src/Appender/MemoryAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/NetSendAppender.cs b/src/Appender/NetSendAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/OutputDebugStringAppender.cs b/src/Appender/OutputDebugStringAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/RemoteSyslogAppender.cs b/src/Appender/RemoteSyslogAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/RemotingAppender.cs b/src/Appender/RemotingAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/SmtpAppender.cs b/src/Appender/SmtpAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/SmtpPickupDirAppender.cs b/src/Appender/SmtpPickupDirAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/TelnetAppender.cs b/src/Appender/TelnetAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/TextWriterAppender.cs b/src/Appender/TextWriterAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/TraceAppender.cs b/src/Appender/TraceAppender.cs old mode 100755 new mode 100644 diff --git a/src/Appender/UdpAppender.cs b/src/Appender/UdpAppender.cs old mode 100755 new mode 100644 diff --git a/src/AssemblyInfo.cs b/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/src/AssemblyVersionInfo.cpp b/src/AssemblyVersionInfo.cpp old mode 100755 new mode 100644 diff --git a/src/AssemblyVersionInfo.cs b/src/AssemblyVersionInfo.cs old mode 100755 new mode 100644 diff --git a/src/AssemblyVersionInfo.js b/src/AssemblyVersionInfo.js old mode 100755 new mode 100644 diff --git a/src/Config/AliasDomainAttribute.cs b/src/Config/AliasDomainAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Config/AliasRepositoryAttribute.cs b/src/Config/AliasRepositoryAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Config/BasicConfigurator.cs b/src/Config/BasicConfigurator.cs old mode 100755 new mode 100644 diff --git a/src/Config/ConfiguratorAttribute.cs b/src/Config/ConfiguratorAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Config/DOMConfigurator.cs b/src/Config/DOMConfigurator.cs old mode 100755 new mode 100644 diff --git a/src/Config/DOMConfiguratorAttribute.cs b/src/Config/DOMConfiguratorAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Config/DomainAttribute.cs b/src/Config/DomainAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Config/Log4NetConfigurationSectionHandler.cs b/src/Config/Log4NetConfigurationSectionHandler.cs old mode 100755 new mode 100644 diff --git a/src/Config/PluginAttribute.cs b/src/Config/PluginAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Config/RepositoryAttribute.cs b/src/Config/RepositoryAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Config/SecurityContextProviderAttribute.cs b/src/Config/SecurityContextProviderAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Config/XmlConfigurator.cs b/src/Config/XmlConfigurator.cs old mode 100755 new mode 100644 diff --git a/src/Config/XmlConfiguratorAttribute.cs b/src/Config/XmlConfiguratorAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Core/CompactRepositorySelector.cs b/src/Core/CompactRepositorySelector.cs old mode 100755 new mode 100644 diff --git a/src/Core/DefaultRepositorySelector.cs b/src/Core/DefaultRepositorySelector.cs old mode 100755 new mode 100644 diff --git a/src/Core/ErrorCode.cs b/src/Core/ErrorCode.cs old mode 100755 new mode 100644 diff --git a/src/Core/IAppenderAttachable.cs b/src/Core/IAppenderAttachable.cs old mode 100755 new mode 100644 diff --git a/src/Core/IErrorHandler.cs b/src/Core/IErrorHandler.cs old mode 100755 new mode 100644 diff --git a/src/Core/IFixingRequired.cs b/src/Core/IFixingRequired.cs old mode 100755 new mode 100644 diff --git a/src/Core/ILogger.cs b/src/Core/ILogger.cs old mode 100755 new mode 100644 diff --git a/src/Core/ILoggerWrapper.cs b/src/Core/ILoggerWrapper.cs old mode 100755 new mode 100644 diff --git a/src/Core/IOptionHandler.cs b/src/Core/IOptionHandler.cs old mode 100755 new mode 100644 diff --git a/src/Core/IRepositorySelector.cs b/src/Core/IRepositorySelector.cs old mode 100755 new mode 100644 diff --git a/src/Core/ITriggeringEventEvaluator.cs b/src/Core/ITriggeringEventEvaluator.cs old mode 100755 new mode 100644 diff --git a/src/Core/Level.cs b/src/Core/Level.cs old mode 100755 new mode 100644 diff --git a/src/Core/LevelCollection.cs b/src/Core/LevelCollection.cs old mode 100755 new mode 100644 diff --git a/src/Core/LevelEvaluator.cs b/src/Core/LevelEvaluator.cs old mode 100755 new mode 100644 diff --git a/src/Core/LevelMap.cs b/src/Core/LevelMap.cs old mode 100755 new mode 100644 diff --git a/src/Core/LocationInfo.cs b/src/Core/LocationInfo.cs old mode 100755 new mode 100644 diff --git a/src/Core/LogException.cs b/src/Core/LogException.cs old mode 100755 new mode 100644 diff --git a/src/Core/LogImpl.cs b/src/Core/LogImpl.cs old mode 100755 new mode 100644 diff --git a/src/Core/LoggerManager.cs b/src/Core/LoggerManager.cs old mode 100755 new mode 100644 diff --git a/src/Core/LoggerWrapperImpl.cs b/src/Core/LoggerWrapperImpl.cs old mode 100755 new mode 100644 diff --git a/src/Core/LoggingEvent.cs b/src/Core/LoggingEvent.cs old mode 100755 new mode 100644 diff --git a/src/Core/SecurityContext.cs b/src/Core/SecurityContext.cs old mode 100755 new mode 100644 diff --git a/src/Core/SecurityContextProvider.cs b/src/Core/SecurityContextProvider.cs old mode 100755 new mode 100644 diff --git a/src/Core/WrapperMap.cs b/src/Core/WrapperMap.cs old mode 100755 new mode 100644 diff --git a/src/DateFormatter/AbsoluteTimeDateFormatter.cs b/src/DateFormatter/AbsoluteTimeDateFormatter.cs old mode 100755 new mode 100644 diff --git a/src/DateFormatter/DateTimeDateFormatter.cs b/src/DateFormatter/DateTimeDateFormatter.cs old mode 100755 new mode 100644 diff --git a/src/DateFormatter/IDateFormatter.cs b/src/DateFormatter/IDateFormatter.cs old mode 100755 new mode 100644 diff --git a/src/DateFormatter/Iso8601DateFormatter.cs b/src/DateFormatter/Iso8601DateFormatter.cs old mode 100755 new mode 100644 diff --git a/src/DateFormatter/SimpleDateFormatter.cs b/src/DateFormatter/SimpleDateFormatter.cs old mode 100755 new mode 100644 diff --git a/src/Filter/DenyAllFilter.cs b/src/Filter/DenyAllFilter.cs old mode 100755 new mode 100644 diff --git a/src/Filter/FilterDecision.cs b/src/Filter/FilterDecision.cs old mode 100755 new mode 100644 diff --git a/src/Filter/FilterSkeleton.cs b/src/Filter/FilterSkeleton.cs old mode 100755 new mode 100644 diff --git a/src/Filter/IFilter.cs b/src/Filter/IFilter.cs old mode 100755 new mode 100644 diff --git a/src/Filter/LevelMatchFilter.cs b/src/Filter/LevelMatchFilter.cs old mode 100755 new mode 100644 diff --git a/src/Filter/LevelRangeFilter.cs b/src/Filter/LevelRangeFilter.cs old mode 100755 new mode 100644 diff --git a/src/Filter/LoggerMatchFilter.cs b/src/Filter/LoggerMatchFilter.cs old mode 100755 new mode 100644 diff --git a/src/Filter/MdcFilter.cs b/src/Filter/MdcFilter.cs old mode 100755 new mode 100644 diff --git a/src/Filter/NdcFilter.cs b/src/Filter/NdcFilter.cs old mode 100755 new mode 100644 diff --git a/src/Filter/PropertyFilter.cs b/src/Filter/PropertyFilter.cs old mode 100755 new mode 100644 diff --git a/src/Filter/StringMatchFilter.cs b/src/Filter/StringMatchFilter.cs old mode 100755 new mode 100644 diff --git a/src/GlobalContext.cs b/src/GlobalContext.cs old mode 100755 new mode 100644 diff --git a/src/ILog.cs b/src/ILog.cs old mode 100755 new mode 100644 diff --git a/src/Layout/ExceptionLayout.cs b/src/Layout/ExceptionLayout.cs old mode 100755 new mode 100644 diff --git a/src/Layout/ILayout.cs b/src/Layout/ILayout.cs old mode 100755 new mode 100644 diff --git a/src/Layout/IRawLayout.cs b/src/Layout/IRawLayout.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Layout2RawLayoutAdapter.cs b/src/Layout/Layout2RawLayoutAdapter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/LayoutSkeleton.cs b/src/Layout/LayoutSkeleton.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/AppDomainPatternConverter.cs b/src/Layout/Pattern/AppDomainPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/DatePatternConverter.cs b/src/Layout/Pattern/DatePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/ExceptionPatternConverter.cs b/src/Layout/Pattern/ExceptionPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/FileLocationPatternConverter.cs b/src/Layout/Pattern/FileLocationPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/FullLocationPatternConverter.cs b/src/Layout/Pattern/FullLocationPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/IdentityPatternConverter.cs b/src/Layout/Pattern/IdentityPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/LevelPatternConverter.cs b/src/Layout/Pattern/LevelPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/LineLocationPatternConverter.cs b/src/Layout/Pattern/LineLocationPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/LoggerPatternConverter.cs b/src/Layout/Pattern/LoggerPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/MessagePatternConverter.cs b/src/Layout/Pattern/MessagePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/MethodLocationPatternConverter.cs b/src/Layout/Pattern/MethodLocationPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/NamedPatternConverter.cs b/src/Layout/Pattern/NamedPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/NdcPatternConverter.cs b/src/Layout/Pattern/NdcPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/PatternLayoutConverter.cs b/src/Layout/Pattern/PatternLayoutConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/PropertyPatternConverter.cs b/src/Layout/Pattern/PropertyPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/RelativeTimePatternConverter.cs b/src/Layout/Pattern/RelativeTimePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/ThreadPatternConverter.cs b/src/Layout/Pattern/ThreadPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/TypeNamePatternConverter.cs b/src/Layout/Pattern/TypeNamePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/UserNamePatternConverter.cs b/src/Layout/Pattern/UserNamePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/Pattern/UtcDatePatternConverter.cs b/src/Layout/Pattern/UtcDatePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/PatternLayout.cs b/src/Layout/PatternLayout.cs old mode 100755 new mode 100644 diff --git a/src/Layout/RawLayoutConverter.cs b/src/Layout/RawLayoutConverter.cs old mode 100755 new mode 100644 diff --git a/src/Layout/RawPropertyLayout.cs b/src/Layout/RawPropertyLayout.cs old mode 100755 new mode 100644 diff --git a/src/Layout/RawTimeStampLayout.cs b/src/Layout/RawTimeStampLayout.cs old mode 100755 new mode 100644 diff --git a/src/Layout/RawUtcTimeStampLayout.cs b/src/Layout/RawUtcTimeStampLayout.cs old mode 100755 new mode 100644 diff --git a/src/Layout/SimpleLayout.cs b/src/Layout/SimpleLayout.cs old mode 100755 new mode 100644 diff --git a/src/Layout/XMLLayout.cs b/src/Layout/XMLLayout.cs old mode 100755 new mode 100644 diff --git a/src/Layout/XMLLayoutBase.cs b/src/Layout/XMLLayoutBase.cs old mode 100755 new mode 100644 diff --git a/src/Layout/XmlLayoutSchemaLog4j.cs b/src/Layout/XmlLayoutSchemaLog4j.cs old mode 100755 new mode 100644 diff --git a/src/LogManager.cs b/src/LogManager.cs old mode 100755 new mode 100644 diff --git a/src/LogicalThreadContext.cs b/src/LogicalThreadContext.cs old mode 100755 new mode 100644 diff --git a/src/MDC.cs b/src/MDC.cs old mode 100755 new mode 100644 diff --git a/src/NDC.cs b/src/NDC.cs old mode 100755 new mode 100644 diff --git a/src/ObjectRenderer/DefaultRenderer.cs b/src/ObjectRenderer/DefaultRenderer.cs old mode 100755 new mode 100644 diff --git a/src/ObjectRenderer/IObjectRenderer.cs b/src/ObjectRenderer/IObjectRenderer.cs old mode 100755 new mode 100644 diff --git a/src/ObjectRenderer/RendererMap.cs b/src/ObjectRenderer/RendererMap.cs old mode 100755 new mode 100644 diff --git a/src/Plugin/IPlugin.cs b/src/Plugin/IPlugin.cs old mode 100755 new mode 100644 diff --git a/src/Plugin/IPluginFactory.cs b/src/Plugin/IPluginFactory.cs old mode 100755 new mode 100644 diff --git a/src/Plugin/PluginCollection.cs b/src/Plugin/PluginCollection.cs old mode 100755 new mode 100644 diff --git a/src/Plugin/PluginMap.cs b/src/Plugin/PluginMap.cs old mode 100755 new mode 100644 diff --git a/src/Plugin/PluginSkeleton.cs b/src/Plugin/PluginSkeleton.cs old mode 100755 new mode 100644 diff --git a/src/Plugin/RemoteLoggingServerPlugin.cs b/src/Plugin/RemoteLoggingServerPlugin.cs old mode 100755 new mode 100644 diff --git a/src/Repository/Hierarchy/DefaultLoggerFactory.cs b/src/Repository/Hierarchy/DefaultLoggerFactory.cs old mode 100755 new mode 100644 diff --git a/src/Repository/Hierarchy/Hierarchy.cs b/src/Repository/Hierarchy/Hierarchy.cs old mode 100755 new mode 100644 diff --git a/src/Repository/Hierarchy/ILoggerFactory.cs b/src/Repository/Hierarchy/ILoggerFactory.cs old mode 100755 new mode 100644 diff --git a/src/Repository/Hierarchy/Logger.cs b/src/Repository/Hierarchy/Logger.cs old mode 100755 new mode 100644 diff --git a/src/Repository/Hierarchy/LoggerKey.cs b/src/Repository/Hierarchy/LoggerKey.cs old mode 100755 new mode 100644 diff --git a/src/Repository/Hierarchy/ProvisionNode.cs b/src/Repository/Hierarchy/ProvisionNode.cs old mode 100755 new mode 100644 diff --git a/src/Repository/Hierarchy/RootLogger.cs b/src/Repository/Hierarchy/RootLogger.cs old mode 100755 new mode 100644 diff --git a/src/Repository/Hierarchy/XmlHierarchyConfigurator.cs b/src/Repository/Hierarchy/XmlHierarchyConfigurator.cs old mode 100755 new mode 100644 diff --git a/src/Repository/IBasicRepositoryConfigurator.cs b/src/Repository/IBasicRepositoryConfigurator.cs old mode 100755 new mode 100644 diff --git a/src/Repository/ILoggerRepository.cs b/src/Repository/ILoggerRepository.cs old mode 100755 new mode 100644 diff --git a/src/Repository/IXmlRepositoryConfigurator.cs b/src/Repository/IXmlRepositoryConfigurator.cs old mode 100755 new mode 100644 diff --git a/src/Repository/LoggerRepositorySkeleton.cs b/src/Repository/LoggerRepositorySkeleton.cs old mode 100755 new mode 100644 diff --git a/src/ThreadContext.cs b/src/ThreadContext.cs old mode 100755 new mode 100644 diff --git a/src/Util/AppenderAttachedImpl.cs b/src/Util/AppenderAttachedImpl.cs old mode 100755 new mode 100644 diff --git a/src/Util/CompositeProperties.cs b/src/Util/CompositeProperties.cs old mode 100755 new mode 100644 diff --git a/src/Util/ContextPropertiesBase.cs b/src/Util/ContextPropertiesBase.cs old mode 100755 new mode 100644 diff --git a/src/Util/CountingQuietTextWriter.cs b/src/Util/CountingQuietTextWriter.cs old mode 100755 new mode 100644 diff --git a/src/Util/CyclicBuffer.cs b/src/Util/CyclicBuffer.cs old mode 100755 new mode 100644 diff --git a/src/Util/EmptyCollection.cs b/src/Util/EmptyCollection.cs old mode 100755 new mode 100644 diff --git a/src/Util/EmptyDictionary.cs b/src/Util/EmptyDictionary.cs old mode 100755 new mode 100644 diff --git a/src/Util/FormattingInfo.cs b/src/Util/FormattingInfo.cs old mode 100755 new mode 100644 diff --git a/src/Util/GlobalContextProperties.cs b/src/Util/GlobalContextProperties.cs old mode 100755 new mode 100644 diff --git a/src/Util/LevelMapping.cs b/src/Util/LevelMapping.cs old mode 100755 new mode 100644 diff --git a/src/Util/LevelMappingEntry.cs b/src/Util/LevelMappingEntry.cs old mode 100755 new mode 100644 diff --git a/src/Util/LogLog.cs b/src/Util/LogLog.cs old mode 100755 new mode 100644 diff --git a/src/Util/LogicalThreadContextProperties.cs b/src/Util/LogicalThreadContextProperties.cs old mode 100755 new mode 100644 diff --git a/src/Util/NativeError.cs b/src/Util/NativeError.cs old mode 100755 new mode 100644 diff --git a/src/Util/NullDictionaryEnumerator.cs b/src/Util/NullDictionaryEnumerator.cs old mode 100755 new mode 100644 diff --git a/src/Util/NullEnumerator.cs b/src/Util/NullEnumerator.cs old mode 100755 new mode 100644 diff --git a/src/Util/NullSecurityContext.cs b/src/Util/NullSecurityContext.cs old mode 100755 new mode 100644 diff --git a/src/Util/OnlyOnceErrorHandler.cs b/src/Util/OnlyOnceErrorHandler.cs old mode 100755 new mode 100644 diff --git a/src/Util/OptionConverter.cs b/src/Util/OptionConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternConverter.cs b/src/Util/PatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternParser.cs b/src/Util/PatternParser.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternString.cs b/src/Util/PatternString.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/AppDomainPatternConverter.cs b/src/Util/PatternStringConverters/AppDomainPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/DatePatternConverter.cs b/src/Util/PatternStringConverters/DatePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/EnvironmentPatternConverter.cs b/src/Util/PatternStringConverters/EnvironmentPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/IdentityPatternConverter.cs b/src/Util/PatternStringConverters/IdentityPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/LiteralPatternConverter.cs b/src/Util/PatternStringConverters/LiteralPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/NewLinePatternConverter.cs b/src/Util/PatternStringConverters/NewLinePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs b/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/PropertyPatternConverter.cs b/src/Util/PatternStringConverters/PropertyPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/RandomStringPatternConverter.cs b/src/Util/PatternStringConverters/RandomStringPatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/UserNamePatternConverter.cs b/src/Util/PatternStringConverters/UserNamePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PatternStringConverters/UtcDatePatternConverter.cs b/src/Util/PatternStringConverters/UtcDatePatternConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/PropertiesDictionary.cs b/src/Util/PropertiesDictionary.cs old mode 100755 new mode 100644 diff --git a/src/Util/ProtectCloseTextWriter.cs b/src/Util/ProtectCloseTextWriter.cs old mode 100755 new mode 100644 diff --git a/src/Util/QuietTextWriter.cs b/src/Util/QuietTextWriter.cs old mode 100755 new mode 100644 diff --git a/src/Util/ReadOnlyPropertiesDictionary.cs b/src/Util/ReadOnlyPropertiesDictionary.cs old mode 100755 new mode 100644 diff --git a/src/Util/ReaderWriterLock.cs b/src/Util/ReaderWriterLock.cs old mode 100755 new mode 100644 diff --git a/src/Util/ReusableStringWriter.cs b/src/Util/ReusableStringWriter.cs old mode 100755 new mode 100644 diff --git a/src/Util/SystemInfo.cs b/src/Util/SystemInfo.cs old mode 100755 new mode 100644 diff --git a/src/Util/TextWriterAdapter.cs b/src/Util/TextWriterAdapter.cs old mode 100755 new mode 100644 diff --git a/src/Util/ThreadContextProperties.cs b/src/Util/ThreadContextProperties.cs old mode 100755 new mode 100644 diff --git a/src/Util/ThreadContextStack.cs b/src/Util/ThreadContextStack.cs old mode 100755 new mode 100644 diff --git a/src/Util/ThreadContextStacks.cs b/src/Util/ThreadContextStacks.cs old mode 100755 new mode 100644 diff --git a/src/Util/Transform.cs b/src/Util/Transform.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/BooleanConverter.cs b/src/Util/TypeConverters/BooleanConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/ConversionNotSupportedException.cs b/src/Util/TypeConverters/ConversionNotSupportedException.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/ConverterRegistry.cs b/src/Util/TypeConverters/ConverterRegistry.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/EncodingConverter.cs b/src/Util/TypeConverters/EncodingConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/IConvertFrom.cs b/src/Util/TypeConverters/IConvertFrom.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/IConvertTo.cs b/src/Util/TypeConverters/IConvertTo.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/IPAddressConverter.cs b/src/Util/TypeConverters/IPAddressConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/PatternLayoutConverter.cs b/src/Util/TypeConverters/PatternLayoutConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/PatternStringConverter.cs b/src/Util/TypeConverters/PatternStringConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/TypeConverter.cs b/src/Util/TypeConverters/TypeConverter.cs old mode 100755 new mode 100644 diff --git a/src/Util/TypeConverters/TypeConverterAttribute.cs b/src/Util/TypeConverters/TypeConverterAttribute.cs old mode 100755 new mode 100644 diff --git a/src/Util/WindowsSecurityContext.cs b/src/Util/WindowsSecurityContext.cs old mode 100755 new mode 100644 diff --git a/src/site/resources/images/ls-logo.jpg b/src/site/resources/images/ls-logo.jpg old mode 100755 new mode 100644 diff --git a/src/site/xdoc/history.xml b/src/site/xdoc/history.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/building.xml b/src/site/xdoc/release/building.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/config-examples.xml b/src/site/xdoc/release/config-examples.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/example-apps.xml b/src/site/xdoc/release/example-apps.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/faq.xml b/src/site/xdoc/release/faq.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/features.xml b/src/site/xdoc/release/features.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/framework-support.xml b/src/site/xdoc/release/framework-support.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/howto/chainsaw.xml b/src/site/xdoc/release/howto/chainsaw.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/howto/index.xml b/src/site/xdoc/release/howto/index.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/manual/configuration.xml b/src/site/xdoc/release/manual/configuration.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/manual/contexts.xml b/src/site/xdoc/release/manual/contexts.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/manual/internals.xml b/src/site/xdoc/release/manual/internals.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/manual/introduction.xml b/src/site/xdoc/release/manual/introduction.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/manual/plugins.xml b/src/site/xdoc/release/manual/plugins.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/manual/repositories.xml b/src/site/xdoc/release/manual/repositories.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/release/release-notes.xml b/src/site/xdoc/release/release-notes.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/stylesheets/project.xml b/src/site/xdoc/stylesheets/project.xml old mode 100755 new mode 100644 diff --git a/src/site/xdoc/stylesheets/site.vsl b/src/site/xdoc/stylesheets/site.vsl old mode 100755 new mode 100644 diff --git a/tests/nant.build b/tests/nant.build old mode 100755 new mode 100644 diff --git a/tests/src/Appender/BufferingAppenderTest.cs b/tests/src/Appender/BufferingAppenderTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Appender/CountingAppender.cs b/tests/src/Appender/CountingAppender.cs old mode 100755 new mode 100644 diff --git a/tests/src/Appender/EventLogAppenderTest.cs b/tests/src/Appender/EventLogAppenderTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Appender/RemotingAppenderTest.cs b/tests/src/Appender/RemotingAppenderTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Appender/RollingFileAppenderTest.cs b/tests/src/Appender/RollingFileAppenderTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Appender/StringAppender.cs b/tests/src/Appender/StringAppender.cs old mode 100755 new mode 100644 diff --git a/tests/src/AssemblyInfo.cs b/tests/src/AssemblyInfo.cs old mode 100755 new mode 100644 diff --git a/tests/src/Context/ThreadContextTest.cs b/tests/src/Context/ThreadContextTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Core/ShutdownTest.cs b/tests/src/Core/ShutdownTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Hierarchy/Logger.cs b/tests/src/Hierarchy/Logger.cs old mode 100755 new mode 100644 diff --git a/tests/src/Layout/PatternLayoutTest.cs b/tests/src/Layout/PatternLayoutTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Layout/XmlLayoutTest.cs b/tests/src/Layout/XmlLayoutTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Util/CyclicBufferTest.cs b/tests/src/Util/CyclicBufferTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Util/PropertiesDictionaryTest.cs b/tests/src/Util/PropertiesDictionaryTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Util/RandomStringPatternConverterTest.cs b/tests/src/Util/RandomStringPatternConverterTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Util/SystemInfoTest.cs b/tests/src/Util/SystemInfoTest.cs old mode 100755 new mode 100644 diff --git a/tests/src/Utils.cs b/tests/src/Utils.cs old mode 100755 new mode 100644 diff --git a/xdocs/build.xml b/xdocs/build.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/contributing.xml b/xdocs/src/contributing.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/downloads.xml b/xdocs/src/downloads.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/history.xml b/xdocs/src/history.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/index.xml b/xdocs/src/index.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/license.xml b/xdocs/src/license.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/building.xml b/xdocs/src/release/building.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/config-examples.xml b/xdocs/src/release/config-examples.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/example-apps.xml b/xdocs/src/release/example-apps.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/faq.xml b/xdocs/src/release/faq.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/features.xml b/xdocs/src/release/features.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/framework-support.xml b/xdocs/src/release/framework-support.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/howto/chainsaw.xml b/xdocs/src/release/howto/chainsaw.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/howto/index.xml b/xdocs/src/release/howto/index.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/manual/configuration.xml b/xdocs/src/release/manual/configuration.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/manual/contexts.xml b/xdocs/src/release/manual/contexts.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/manual/internals.xml b/xdocs/src/release/manual/internals.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/manual/introduction.xml b/xdocs/src/release/manual/introduction.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/manual/plugins.xml b/xdocs/src/release/manual/plugins.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/manual/repositories.xml b/xdocs/src/release/manual/repositories.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/release/release-notes.xml b/xdocs/src/release/release-notes.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/roadmap.xml b/xdocs/src/roadmap.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/stylesheets/project.xml b/xdocs/src/stylesheets/project.xml old mode 100755 new mode 100644 diff --git a/xdocs/src/stylesheets/site.vsl b/xdocs/src/stylesheets/site.vsl old mode 100755 new mode 100644 diff --git a/xdocs/src/support.xml b/xdocs/src/support.xml old mode 100755 new mode 100644 From 4bfb22cff5c71cba3bba8e3d70f81ed7b83bcb70 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 5 Sep 2011 14:55:39 +0000 Subject: [PATCH 019/370] VS 2010 Solution file targeting .NET 4.0 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1165307 13f79535-47bb-0310-9956-ffa450edef68 --- src/log4net.vs2010.csproj | 783 ++++++++++++++++++++++++++ src/log4net.vs2010.sln | 45 ++ tests/src/log4net.Tests.vs2010.csproj | 242 ++++++++ 3 files changed, 1070 insertions(+) create mode 100644 src/log4net.vs2010.csproj create mode 100644 src/log4net.vs2010.sln create mode 100644 tests/src/log4net.Tests.vs2010.csproj diff --git a/src/log4net.vs2010.csproj b/src/log4net.vs2010.csproj new file mode 100644 index 00000000..5ba69b4f --- /dev/null +++ b/src/log4net.vs2010.csproj @@ -0,0 +1,783 @@ + + + + + Local + 9.0.30729 + 2.0 + {181FE707-E161-4722-9F38-6AAAB6FAA106} + Debug + AnyCPU + + + + + log4net + + + JScript + Grid + IE50 + false + Library + log4net + + + + + + + 3.5 + v4.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + ..\build\bin\net\2.0\debug\ + false + 285212672 + false + + + TRACE;DEBUG;NET;NET_2_0;NET_4_0 + log4net.xml + true + 4096 + false + false + false + false + 4 + full + prompt + SecurityRules.ruleset + + + ..\build\bin\net\1.0\release\ + false + 285212672 + false + + + TRACE;STRONG;NET;NET_1_0; + log4net.xml + false + 4096 + true + false + false + false + 4 + none + prompt + AllRules.ruleset + + + + System + + + + System.Data + + + System.Web + + + System.XML + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + + + \ No newline at end of file diff --git a/src/log4net.vs2010.sln b/src/log4net.vs2010.sln new file mode 100644 index 00000000..db0afd90 --- /dev/null +++ b/src/log4net.vs2010.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +# +# +# 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. +# +# +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.vs2010", "log4net.vs2010.csproj", "{181FE707-E161-4722-9F38-6AAAB6FAA106}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Tests.vs2010", "..\tests\src\log4net.Tests.vs2010.csproj", "{B0530F10-0238-49A9-93B0-8EF412E90BCF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.Build.0 = Debug|Any CPU + {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.ActiveCfg = Release|Any CPU + {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.Build.0 = Release|Any CPU + {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tests/src/log4net.Tests.vs2010.csproj b/tests/src/log4net.Tests.vs2010.csproj new file mode 100644 index 00000000..57f244cd --- /dev/null +++ b/tests/src/log4net.Tests.vs2010.csproj @@ -0,0 +1,242 @@ + + + + + Local + 9.0.30729 + 2.0 + {B0530F10-0238-49A9-93B0-8EF412E90BCF} + Debug + AnyCPU + + + + + log4net.Tests + + + JScript + Grid + IE50 + false + Library + log4net.Tests + + + + + + + 3.5 + v4.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + ..\bin\Debug\ + false + 285212672 + false + + + TRACE;DEBUG;NET;NET_2_0;NET_4_0 + + + true + 4096 + false + false + false + false + 4 + full + prompt + AllRules.ruleset + + + ..\bin\Release\ + false + 285212672 + false + + + TRACE + + + false + 4096 + true + false + false + false + 4 + none + prompt + AllRules.ruleset + + + + False + ..\..\..\ibatisnet-3\External-Bin\Net\2.0\nunit.framework.dll + + + System + + + + 3.5 + + + System.Data + + + System.Runtime.Remoting + + + System.XML + + + + + AssemblyVersionInfo.cs + Code + + + + + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + + + Code + + + Code + + + + + + + Code + + + Code + + + Code + + + + + {181FE707-E161-4722-9F38-6AAAB6FAA106} + log4net.vs2008 + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + + + \ No newline at end of file From d12fa0ecba7265ee1b2b4914e8f4db316f884c71 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 5 Sep 2011 15:48:51 +0000 Subject: [PATCH 020/370] Throw in a bunch of Security(Safe)Critical attributes to hopefully satisfy the security transparency system of .NET 4.0 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1165341 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/ColoredConsoleAppender.cs | 12 ++++++++++-- src/Appender/FileAppender.cs | 3 +++ src/Appender/LocalSyslogAppender.cs | 16 +++++++++++++--- src/Appender/NetSendAppender.cs | 6 +++++- src/Appender/OutputDebugStringAppender.cs | 6 +++++- src/Appender/RemotingAppender.cs | 5 ++++- src/Config/XmlConfigurator.cs | 8 +++++++- src/Core/LoggingEvent.cs | 4 ++++ src/Plugin/RemoteLoggingServerPlugin.cs | 10 ++++++++-- src/Util/LogicalThreadContextProperties.cs | 10 ++++++++-- src/Util/NativeError.cs | 12 ++++++++++-- .../ProcessIdPatternConverter.cs | 5 ++++- src/Util/ReadOnlyPropertiesDictionary.cs | 6 +++++- src/Util/WindowsSecurityContext.cs | 6 +++++- 14 files changed, 91 insertions(+), 18 deletions(-) diff --git a/src/Appender/ColoredConsoleAppender.cs b/src/Appender/ColoredConsoleAppender.cs index 0d587e3e..eb58da46 100644 --- a/src/Appender/ColoredConsoleAppender.cs +++ b/src/Appender/ColoredConsoleAppender.cs @@ -265,7 +265,11 @@ public void AddMapping(LevelColors mapping) /// The format of the output will depend on the appender's layout. /// /// - override protected void Append(log4net.Core.LoggingEvent loggingEvent) +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] + override protected void Append(log4net.Core.LoggingEvent loggingEvent) { if (m_consoleOutputWriter != null) { @@ -430,7 +434,11 @@ override protected bool RequiresLayout /// Initialize the level to color mappings set on this appender. /// /// - public override void ActivateOptions() +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode=true)] + public override void ActivateOptions() { base.ActivateOptions(); m_levelMapping.ActivateOptions(); diff --git a/src/Appender/FileAppender.cs b/src/Appender/FileAppender.cs index 8e3e1c57..0f047cd3 100644 --- a/src/Appender/FileAppender.cs +++ b/src/Appender/FileAppender.cs @@ -607,6 +607,9 @@ public class MutexLock : LockingModelBase /// - and . /// /// +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif public override void OpenFile(string filename, bool append, Encoding encoding) { try diff --git a/src/Appender/LocalSyslogAppender.cs b/src/Appender/LocalSyslogAppender.cs index e5b4f4bd..36fb49e7 100644 --- a/src/Appender/LocalSyslogAppender.cs +++ b/src/Appender/LocalSyslogAppender.cs @@ -337,7 +337,10 @@ public void AddMapping(LevelSeverity mapping) /// must be called again. /// /// - public override void ActivateOptions() +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + public override void ActivateOptions() { base.ActivateOptions(); @@ -375,7 +378,11 @@ public override void ActivateOptions() /// The format of the output will depend on the appender's layout. /// /// - protected override void Append(LoggingEvent loggingEvent) +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] + protected override void Append(LoggingEvent loggingEvent) { int priority = GeneratePriority(m_facility, GetSeverity(loggingEvent.Level)); string message = RenderLoggingEvent(loggingEvent); @@ -393,7 +400,10 @@ protected override void Append(LoggingEvent loggingEvent) /// Close the syslog when the appender is closed /// /// - protected override void OnClose() +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + protected override void OnClose() { base.OnClose(); diff --git a/src/Appender/NetSendAppender.cs b/src/Appender/NetSendAppender.cs index 9a22a32b..1f49a53c 100644 --- a/src/Appender/NetSendAppender.cs +++ b/src/Appender/NetSendAppender.cs @@ -304,7 +304,11 @@ public override void ActivateOptions() /// Sends the event using a network message. /// /// - protected override void Append(LoggingEvent loggingEvent) +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] + protected override void Append(LoggingEvent loggingEvent) { NativeError nativeError = null; diff --git a/src/Appender/OutputDebugStringAppender.cs b/src/Appender/OutputDebugStringAppender.cs index c9c20f30..f61dc480 100644 --- a/src/Appender/OutputDebugStringAppender.cs +++ b/src/Appender/OutputDebugStringAppender.cs @@ -75,7 +75,11 @@ public OutputDebugStringAppender() /// Write the logging event to the output debug string API /// /// - override protected void Append(LoggingEvent loggingEvent) +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] + override protected void Append(LoggingEvent loggingEvent) { OutputDebugString(RenderLoggingEvent(loggingEvent)); } diff --git a/src/Appender/RemotingAppender.cs b/src/Appender/RemotingAppender.cs index d1834e7d..24ca2e0b 100644 --- a/src/Appender/RemotingAppender.cs +++ b/src/Appender/RemotingAppender.cs @@ -138,7 +138,10 @@ public string Sink /// must be called again. /// /// - override public void ActivateOptions() +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + override public void ActivateOptions() { base.ActivateOptions(); diff --git a/src/Config/XmlConfigurator.cs b/src/Config/XmlConfigurator.cs index ea43a501..4fc219c5 100644 --- a/src/Config/XmlConfigurator.cs +++ b/src/Config/XmlConfigurator.cs @@ -963,7 +963,10 @@ private sealed class ConfigureAndWatchHandler : IDisposable /// Initializes a new instance of the class. /// /// - public ConfigureAndWatchHandler(ILoggerRepository repository, FileInfo configFile) +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + public ConfigureAndWatchHandler(ILoggerRepository repository, FileInfo configFile) { m_repository = repository; m_configFile = configFile; @@ -1040,6 +1043,9 @@ private void OnWatchedFileChange(object state) /// /// Release the handles held by the watcher and timer. /// +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif public void Dispose() { m_watcher.EnableRaisingEvents = false; diff --git a/src/Core/LoggingEvent.cs b/src/Core/LoggingEvent.cs index 0cbc025b..16620697 100644 --- a/src/Core/LoggingEvent.cs +++ b/src/Core/LoggingEvent.cs @@ -1013,7 +1013,11 @@ public FixFlags Fix /// is to be used outside that method. /// /// +#if NET_4_0 + [System.Security.SecurityCritical] +#else [System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.Demand, SerializationFormatter=true)] +#endif public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { // The caller must call FixVolatileData before this object diff --git a/src/Plugin/RemoteLoggingServerPlugin.cs b/src/Plugin/RemoteLoggingServerPlugin.cs index d24cc814..8cc5b435 100644 --- a/src/Plugin/RemoteLoggingServerPlugin.cs +++ b/src/Plugin/RemoteLoggingServerPlugin.cs @@ -145,7 +145,10 @@ override public void Attach(ILoggerRepository repository) /// sink is disconnected. /// /// - override public void Shutdown() +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + override public void Shutdown() { // Stops the sink from receiving messages RemotingServices.Disconnect(m_sink); @@ -247,7 +250,10 @@ public void LogEvents(LoggingEvent[] events) /// therefore this implementation returns null. /// /// - public override object InitializeLifetimeService() +#if NET_4_0 + [System.Security.SecurityCritical] +#endif + public override object InitializeLifetimeService() { return null; } diff --git a/src/Util/LogicalThreadContextProperties.cs b/src/Util/LogicalThreadContextProperties.cs index a83fa2a0..e53a5e1b 100644 --- a/src/Util/LogicalThreadContextProperties.cs +++ b/src/Util/LogicalThreadContextProperties.cs @@ -203,7 +203,10 @@ internal PropertiesDictionary GetProperties(bool create) /// security link demand, therfore we must put the method call in a seperate method /// that we can wrap in an exception handler. /// - private static PropertiesDictionary GetCallContextData() +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + private static PropertiesDictionary GetCallContextData() { return CallContext.GetData(c_SlotName) as PropertiesDictionary; } @@ -217,7 +220,10 @@ private static PropertiesDictionary GetCallContextData() /// security link demand, therfore we must put the method call in a seperate method /// that we can wrap in an exception handler. /// - private static void SetCallContextData(PropertiesDictionary properties) +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + private static void SetCallContextData(PropertiesDictionary properties) { CallContext.SetData(c_SlotName, properties); } diff --git a/src/Util/NativeError.cs b/src/Util/NativeError.cs index f889d9e5..dbb904a9 100644 --- a/src/Util/NativeError.cs +++ b/src/Util/NativeError.cs @@ -114,7 +114,11 @@ public string Message /// native Win32 FormatMessage function. /// /// - public static NativeError GetLastError() +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode=true)] + public static NativeError GetLastError() { int number = Marshal.GetLastWin32Error(); return new NativeError(number, NativeError.GetErrorMessage(number)); @@ -152,7 +156,11 @@ public static NativeError GetError(int number) /// using the native FormatMessage function. /// /// - public static string GetErrorMessage(int messageId) +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] + public static string GetErrorMessage(int messageId) { // Win32 constants int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; // The function should allocates a buffer large enough to hold the formatted message diff --git a/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs b/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs index 29a33a68..cf5df787 100644 --- a/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs +++ b/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs @@ -46,7 +46,10 @@ internal sealed class ProcessIdPatternConverter : PatternConverter /// Write the current process ID to the output . /// /// - override protected void Convert(TextWriter writer, object state) +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + override protected void Convert(TextWriter writer, object state) { #if (NETCF || SSCLI) // On compact framework there is no System.Diagnostics.Process class diff --git a/src/Util/ReadOnlyPropertiesDictionary.cs b/src/Util/ReadOnlyPropertiesDictionary.cs index 407fd5c8..519d4d77 100644 --- a/src/Util/ReadOnlyPropertiesDictionary.cs +++ b/src/Util/ReadOnlyPropertiesDictionary.cs @@ -203,8 +203,12 @@ protected Hashtable InnerHashtable /// Serializes this object into the provided. /// /// +#if NET_4_0 + [System.Security.SecurityCritical] +#else [System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.Demand, SerializationFormatter=true)] - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) +#endif + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { foreach(DictionaryEntry entry in InnerHashtable) { diff --git a/src/Util/WindowsSecurityContext.cs b/src/Util/WindowsSecurityContext.cs index 9e6e4510..357c43dc 100644 --- a/src/Util/WindowsSecurityContext.cs +++ b/src/Util/WindowsSecurityContext.cs @@ -275,7 +275,11 @@ public override IDisposable Impersonate(object state) /// token is used to initialize the WindowsIdentity. /// /// - private static WindowsIdentity LogonUser(string userName, string domainName, string password) +#if NET_4_0 + [System.Security.SecuritySafeCritical] +#endif + [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] + private static WindowsIdentity LogonUser(string userName, string domainName, string password) { const int LOGON32_PROVIDER_DEFAULT = 0; //This parameter causes LogonUser to create a primary token. From 1a8deb710de45a8e31e600dc8c682a3fd62af12d Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 6 Sep 2011 12:20:23 +0000 Subject: [PATCH 021/370] .NET 2.0 wraps all non-CLS exceptions in RuntimeWrappedExceptions so the blocks without any Exception are never reached and create a compiler warning git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1165634 13f79535-47bb-0310-9956-ffa450edef68 --- src/Repository/Hierarchy/Logger.cs | 6 ++++++ src/Util/SystemStringFormat.cs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/Repository/Hierarchy/Logger.cs b/src/Repository/Hierarchy/Logger.cs index 3b49b3fa..750e2bb5 100644 --- a/src/Repository/Hierarchy/Logger.cs +++ b/src/Repository/Hierarchy/Logger.cs @@ -432,10 +432,12 @@ virtual public void Log(Type callerStackBoundaryDeclaringType, Level level, obje { log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); } +#if !NET_2_0 catch { log4net.Util.LogLog.Error(declaringType, "Exception while logging"); } +#endif } /// @@ -467,10 +469,12 @@ virtual public void Log(LoggingEvent logEvent) { log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); } +#if !NET_2_0 catch { log4net.Util.LogLog.Error(declaringType, "Exception while logging"); } +#endif } /// @@ -505,10 +509,12 @@ virtual public bool IsEnabledFor(Level level) { log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); } +#if !NET_2_0 catch { log4net.Util.LogLog.Error(declaringType, "Exception while logging"); } +#endif return false; } diff --git a/src/Util/SystemStringFormat.cs b/src/Util/SystemStringFormat.cs index 8e022fe2..353708a9 100644 --- a/src/Util/SystemStringFormat.cs +++ b/src/Util/SystemStringFormat.cs @@ -109,11 +109,13 @@ private static string StringFormat(IFormatProvider provider, string format, para log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]", ex); return StringFormatError(ex, format, args); } +#if !NET_2_0 catch { log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]"); return StringFormatError(null, format, args); } +#endif } /// @@ -146,11 +148,13 @@ private static string StringFormatError(Exception formatException, string format log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex); return "Exception during StringFormat. See Internal Log."; } +#if !NET_2_0 catch { log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling"); return "Exception during StringFormat. See Internal Log."; } +#endif } /// @@ -206,10 +210,12 @@ private static void RenderObject(Object obj, StringBuilder buffer) { buffer.Append(""); } +#if !NET_2_0 catch { buffer.Append(""); } +#endif } } From 6b52786ce4eb57bbf574ff440fe71d2c749ca4a6 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 6 Sep 2011 13:55:09 +0000 Subject: [PATCH 022/370] ensure tests reset static LogLog configuration if they change it. Fixes the two LogLog tests that are part of the ten failing tests in LOG4NET-301 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1165671 13f79535-47bb-0310-9956-ffa450edef68 --- .../LoggerRepository/ConfigurationMessages.cs | 22 ++++++++++++------- tests/src/Util/LogLogTest.cs | 13 +++++++---- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/tests/src/LoggerRepository/ConfigurationMessages.cs b/tests/src/LoggerRepository/ConfigurationMessages.cs index 3e814d49..e9a88778 100644 --- a/tests/src/LoggerRepository/ConfigurationMessages.cs +++ b/tests/src/LoggerRepository/ConfigurationMessages.cs @@ -37,11 +37,12 @@ public class ConfigurationMessages [Test] public void ConfigurationMessagesTest() { - LogLog.EmitInternalMessages = false; - LogLog.InternalDebugging = true; + try { + LogLog.EmitInternalMessages = false; + LogLog.InternalDebugging = true; - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" + XmlDocument log4netConfig = new XmlDocument(); + log4netConfig.LoadXml(@" @@ -56,12 +57,17 @@ public void ConfigurationMessagesTest() "); - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - rep.ConfigurationChanged += new LoggerRepositoryConfigurationChangedEventHandler(rep_ConfigurationChanged); + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + rep.ConfigurationChanged += new LoggerRepositoryConfigurationChangedEventHandler(rep_ConfigurationChanged); - ICollection configurationMessages = XmlConfigurator.Configure(rep, log4netConfig["log4net"]); + ICollection configurationMessages = XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - Assert.IsTrue(configurationMessages.Count > 0); + Assert.IsTrue(configurationMessages.Count > 0); + } + finally { + LogLog.EmitInternalMessages = true; + LogLog.InternalDebugging = false; + } } static void rep_ConfigurationChanged(object sender, EventArgs e) diff --git a/tests/src/Util/LogLogTest.cs b/tests/src/Util/LogLogTest.cs index 18ed78d5..7d9030b6 100644 --- a/tests/src/Util/LogLogTest.cs +++ b/tests/src/Util/LogLogTest.cs @@ -54,11 +54,16 @@ public void EmitInternalMessages() Trace.Flush(); Assert.AreEqual(2, listTraceListener.Count); - LogLog.EmitInternalMessages = false; + try { + LogLog.EmitInternalMessages = false; - LogLog.Error(GetType(), "Hello"); - LogLog.Error(GetType(), "World"); - Assert.AreEqual(2, listTraceListener.Count); + LogLog.Error(GetType(), "Hello"); + LogLog.Error(GetType(), "World"); + Assert.AreEqual(2, listTraceListener.Count); + } + finally { + LogLog.EmitInternalMessages = true; + } } [Test] From f16056bef615ab218d193a4f4e8bc2622613d0f0 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 6 Sep 2011 14:19:44 +0000 Subject: [PATCH 023/370] skip test that tries to set a system level environment variable if user lacks the permission to set it. LOG4NET-301 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1165680 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Util/EnvironmentPatternConverterTest.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/src/Util/EnvironmentPatternConverterTest.cs b/tests/src/Util/EnvironmentPatternConverterTest.cs index 2eee33f3..be4f7e6c 100644 --- a/tests/src/Util/EnvironmentPatternConverterTest.cs +++ b/tests/src/Util/EnvironmentPatternConverterTest.cs @@ -42,7 +42,12 @@ public class EnvironmentPatternConverterTest public void SystemLevelEnvironmentVariable() { EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, SYSTEM_LEVEL_VALUE, EnvironmentVariableTarget.Machine); + try { + Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, SYSTEM_LEVEL_VALUE, EnvironmentVariableTarget.Machine); + } + catch (System.Security.SecurityException) { + Assert.Ignore("Test skipped as current user must not set system level environment variables"); + } converter.Option = ENVIRONMENT_VARIABLE_NAME; From f0d0609636f3f42e3428d9d239db23d2a0198bc4 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 6 Sep 2011 15:25:44 +0000 Subject: [PATCH 024/370] Make MinimalLock work again with appendToFile=false. LOG4NET-311, fixes two tests mentioned in LOG4NET-301, regression introduced as part of LOG4NET-164 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1165715 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/FileAppender.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Appender/FileAppender.cs b/src/Appender/FileAppender.cs index 0f047cd3..54f3f29d 100644 --- a/src/Appender/FileAppender.cs +++ b/src/Appender/FileAppender.cs @@ -557,6 +557,7 @@ public override Stream AcquireLock() try { m_stream = CreateStream(m_filename, m_append, FileShare.Read); + m_append = true; } catch (Exception e1) { From 811e0474a2fc519b8f5f0e899d89d2044b3a162c Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Sep 2011 07:58:26 +0000 Subject: [PATCH 025/370] properly shutdown remoting infrastructure in tests so test can be rerun git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1166034 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Appender/RemotingAppenderTest.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/src/Appender/RemotingAppenderTest.cs b/tests/src/Appender/RemotingAppenderTest.cs index f2705fd2..07ef02c1 100644 --- a/tests/src/Appender/RemotingAppenderTest.cs +++ b/tests/src/Appender/RemotingAppenderTest.cs @@ -222,7 +222,7 @@ private void RegisterRemotingServerChannel() } } - /// + /// /// Shuts down any loggers in the hierarchy, along /// with all appenders. /// @@ -254,6 +254,22 @@ public void TearDown() ResetRepository(); } + /// + /// Close down remoting infrastructure + /// + [TestFixtureTearDown] + public void UnregisterRemotingServerChannel() { + if (m_remotingChannel != null) { + ((TcpChannel) m_remotingChannel).StopListening(null); + try { + ChannelServices.UnregisterChannel(m_remotingChannel); + } + catch (Exception) { + } + m_remotingChannel = null; + } + } + /// /// Configures the root appender for counting and rolling /// From 8442ade53304d6bdd8907ac35b119bac3f0b676f Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Sep 2011 08:18:53 +0000 Subject: [PATCH 026/370] RemotingAppenderTest fails on very first test because of timing issues - at least on my machine. Avoid problems by waiting a bit longer. LOG4NET-301 and LOG4NET-265 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1166042 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Appender/RemotingAppenderTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/src/Appender/RemotingAppenderTest.cs b/tests/src/Appender/RemotingAppenderTest.cs index 07ef02c1..1da68682 100644 --- a/tests/src/Appender/RemotingAppenderTest.cs +++ b/tests/src/Appender/RemotingAppenderTest.cs @@ -66,7 +66,7 @@ public void TestRemotedMessage() root.Log(Level.Debug, testMessage, null); // Wait for the remoted object to be delivered - Thread.Sleep(1000); + Thread.Sleep(2000); LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events; Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event"); @@ -92,7 +92,7 @@ public void TestPartialFix() root.Log(Level.Debug, "test message", null); // Wait for the remoted object to be delivered - Thread.Sleep(1000); + Thread.Sleep(2000); LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events; Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event"); @@ -121,7 +121,7 @@ public void TestFullFix() root.Log(Level.Debug, "test message", null); // Wait for the remoted object to be delivered - Thread.Sleep(1000); + Thread.Sleep(2000); LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events; Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event"); @@ -156,7 +156,7 @@ public void TestRemotedMessageNdcPushPop() root.Log(Level.Debug, testMessage, null); // Wait for the remoted object to be delivered - Thread.Sleep(1000); + Thread.Sleep(2000); LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events; Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event"); From edd81274b6d1005d3adfdd97e448356fd6b99e93 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Sep 2011 08:46:05 +0000 Subject: [PATCH 027/370] ThreadContextTest and PatternLayoutTest influence each other via contexts, reset the contexts. LOG4NET-301 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1166059 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Context/ThreadContextTest.cs | 39 +++++++++++++++----------- tests/src/Layout/PatternLayoutTest.cs | 18 ++++++++---- tests/src/Utils.cs | 7 +++++ 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/tests/src/Context/ThreadContextTest.cs b/tests/src/Context/ThreadContextTest.cs index d5ccc8d8..e489efc4 100644 --- a/tests/src/Context/ThreadContextTest.cs +++ b/tests/src/Context/ThreadContextTest.cs @@ -39,11 +39,16 @@ namespace log4net.Tests.Context [TestFixture] public class ThreadContextTest { - [Test] + [TearDown] + public void TearDown() { + Utils.RemovePropertyFromAllContexts(); + } + + [Test] public void TestThreadPropertiesPattern() { StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{prop1}"); + stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); BasicConfigurator.Configure(rep, stringAppender); @@ -54,13 +59,13 @@ public void TestThreadPropertiesPattern() Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread properties value set"); stringAppender.Reset(); - ThreadContext.Properties["prop1"] = "val1"; + ThreadContext.Properties[Utils.PROPERTY_KEY] = "val1"; log1.Info("TestMessage"); Assert.AreEqual("val1", stringAppender.GetString(), "Test thread properties value set"); stringAppender.Reset(); - ThreadContext.Properties.Remove("prop1"); + ThreadContext.Properties.Remove(Utils.PROPERTY_KEY); log1.Info("TestMessage"); Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread properties value removed"); @@ -71,7 +76,7 @@ public void TestThreadPropertiesPattern() public void TestThreadStackPattern() { StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{prop1}"); + stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); BasicConfigurator.Configure(rep, stringAppender); @@ -82,7 +87,7 @@ public void TestThreadStackPattern() Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set"); stringAppender.Reset(); - using(ThreadContext.Stacks["prop1"].Push("val1")) + using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1")) { log1.Info("TestMessage"); Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set"); @@ -98,7 +103,7 @@ public void TestThreadStackPattern() public void TestThreadStackPattern2() { StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{prop1}"); + stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); BasicConfigurator.Configure(rep, stringAppender); @@ -109,13 +114,13 @@ public void TestThreadStackPattern2() Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set"); stringAppender.Reset(); - using(ThreadContext.Stacks["prop1"].Push("val1")) + using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1")) { log1.Info("TestMessage"); Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set"); stringAppender.Reset(); - using(ThreadContext.Stacks["prop1"].Push("val2")) + using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val2")) { log1.Info("TestMessage"); Assert.AreEqual("val1 val2", stringAppender.GetString(), "Test thread stack value pushed 2nd val"); @@ -132,7 +137,7 @@ public void TestThreadStackPattern2() public void TestThreadStackPatternNullVal() { StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{prop1}"); + stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); BasicConfigurator.Configure(rep, stringAppender); @@ -143,7 +148,7 @@ public void TestThreadStackPatternNullVal() Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set"); stringAppender.Reset(); - using(ThreadContext.Stacks["prop1"].Push(null)) + using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null)) { log1.Info("TestMessage"); Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value set"); @@ -159,7 +164,7 @@ public void TestThreadStackPatternNullVal() public void TestThreadStackPatternNullVal2() { StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{prop1}"); + stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); BasicConfigurator.Configure(rep, stringAppender); @@ -170,13 +175,13 @@ public void TestThreadStackPatternNullVal2() Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set"); stringAppender.Reset(); - using(ThreadContext.Stacks["prop1"].Push("val1")) + using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1")) { log1.Info("TestMessage"); Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set"); stringAppender.Reset(); - using(ThreadContext.Stacks["prop1"].Push(null)) + using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null)) { log1.Info("TestMessage"); Assert.AreEqual("val1 ", stringAppender.GetString(), "Test thread stack value pushed null"); @@ -189,13 +194,15 @@ public void TestThreadStackPatternNullVal2() stringAppender.Reset(); } + private static string TestBackgroundThreadContextPropertyRepository; + [Test] public void TestBackgroundThreadContextProperty() { StringAppender stringAppender = new StringAppender(); stringAppender.Layout = new PatternLayout("%property{DateTimeTodayToString}"); - ILoggerRepository rep = LogManager.CreateRepository("TestBackgroundThreadContextPropertyRepository"); + ILoggerRepository rep = LogManager.CreateRepository(TestBackgroundThreadContextPropertyRepository = "TestBackgroundThreadContextPropertyRepository" + Guid.NewGuid().ToString()); BasicConfigurator.Configure(rep, stringAppender); Thread thread = new Thread(new ThreadStart(ExecuteBackgroundThread)); @@ -206,7 +213,7 @@ public void TestBackgroundThreadContextProperty() private static void ExecuteBackgroundThread() { - ILog log = LogManager.GetLogger("TestBackgroundThreadContextPropertyRepository", "ExecuteBackGroundThread"); + ILog log = LogManager.GetLogger(TestBackgroundThreadContextPropertyRepository, "ExecuteBackGroundThread"); ThreadContext.Properties["DateTimeTodayToString"] = DateTime.Today.ToString(); log.Info("TestMessage"); diff --git a/tests/src/Layout/PatternLayoutTest.cs b/tests/src/Layout/PatternLayoutTest.cs index a3ec6bb0..d462af83 100644 --- a/tests/src/Layout/PatternLayoutTest.cs +++ b/tests/src/Layout/PatternLayoutTest.cs @@ -41,11 +41,17 @@ namespace log4net.Tests.Layout [TestFixture] public class PatternLayoutTest { + + [TearDown] + public void TearDown() { + Utils.RemovePropertyFromAllContexts(); + } + [Test] public void TestThreadPropertiesPattern() { StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{prop1}"); + stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); BasicConfigurator.Configure(rep, stringAppender); @@ -56,13 +62,13 @@ public void TestThreadPropertiesPattern() Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread properties value set"); stringAppender.Reset(); - ThreadContext.Properties["prop1"] = "val1"; + ThreadContext.Properties[Utils.PROPERTY_KEY] = "val1"; log1.Info("TestMessage"); Assert.AreEqual("val1", stringAppender.GetString(), "Test thread properties value set"); stringAppender.Reset(); - ThreadContext.Properties.Remove("prop1"); + ThreadContext.Properties.Remove(Utils.PROPERTY_KEY); log1.Info("TestMessage"); Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread properties value removed"); @@ -89,7 +95,7 @@ public void TestStackTracePattern() public void TestGlobalPropertiesPattern() { StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{prop1}"); + stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); BasicConfigurator.Configure(rep, stringAppender); @@ -100,13 +106,13 @@ public void TestGlobalPropertiesPattern() Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no global properties value set"); stringAppender.Reset(); - GlobalContext.Properties["prop1"] = "val1"; + GlobalContext.Properties[Utils.PROPERTY_KEY] = "val1"; log1.Info("TestMessage"); Assert.AreEqual("val1", stringAppender.GetString(), "Test global properties value set"); stringAppender.Reset(); - GlobalContext.Properties.Remove("prop1"); + GlobalContext.Properties.Remove(Utils.PROPERTY_KEY); log1.Info("TestMessage"); Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test global properties value removed"); diff --git a/tests/src/Utils.cs b/tests/src/Utils.cs index bd98a92a..8de9a9f6 100644 --- a/tests/src/Utils.cs +++ b/tests/src/Utils.cs @@ -99,5 +99,12 @@ private static Type[] GetTypesArray(object[] args) return types; } + + internal const string PROPERTY_KEY = "prop1"; + + internal static void RemovePropertyFromAllContexts() { + GlobalContext.Properties.Remove(PROPERTY_KEY); + ThreadContext.Properties.Remove(PROPERTY_KEY); + } } } \ No newline at end of file From fdc45e6b66418d0bab6c0fb86916122f10c288dc Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Sep 2011 08:54:54 +0000 Subject: [PATCH 028/370] FixingTest failed when rerunning tests in NUnit GUI without reloading the DLL. Related to LOG4NET-301 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1166068 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Core/FixingTest.cs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tests/src/Core/FixingTest.cs b/tests/src/Core/FixingTest.cs index fc319655..5415f023 100644 --- a/tests/src/Core/FixingTest.cs +++ b/tests/src/Core/FixingTest.cs @@ -31,9 +31,24 @@ namespace log4net.Tests.Core [TestFixture] public class FixingTest { - static FixingTest() + const string TEST_REPOSITORY = "Test Repository"; + + [TestFixtureSetUp] + public void CreateRepository() { - LogManager.CreateRepository("Test Repository"); + bool exists = false; + Repository.ILoggerRepository[] repositories = LogManager.GetAllRepositories(); + if (repositories != null) { + foreach (Repository.ILoggerRepository r in repositories) { + if (r.Name == TEST_REPOSITORY) { + exists = true; + break; + } + } + } + if (!exists) { + LogManager.CreateRepository(TEST_REPOSITORY); + } // write-once if (Thread.CurrentThread.Name == null) @@ -50,7 +65,7 @@ public void TestUnfixedValues() // LoggingEvents occur at distinct points in time LoggingEvent loggingEvent = new LoggingEvent( loggingEventData.LocationInfo.GetType(), - LogManager.GetRepository("Test Repository"), + LogManager.GetRepository(TEST_REPOSITORY), loggingEventData.LoggerName, loggingEventData.Level, loggingEventData.Message, @@ -69,7 +84,7 @@ public void TestAllFixedValues() // LoggingEvents occur at distinct points in time LoggingEvent loggingEvent = new LoggingEvent( loggingEventData.LocationInfo.GetType(), - LogManager.GetRepository("Test Repository"), + LogManager.GetRepository(TEST_REPOSITORY), loggingEventData.LoggerName, loggingEventData.Level, loggingEventData.Message, @@ -90,7 +105,7 @@ public void TestNoFixedValues() // LoggingEvents occur at distinct points in time LoggingEvent loggingEvent = new LoggingEvent( loggingEventData.LocationInfo.GetType(), - LogManager.GetRepository("Test Repository"), + LogManager.GetRepository(TEST_REPOSITORY), loggingEventData.LoggerName, loggingEventData.Level, loggingEventData.Message, @@ -126,7 +141,7 @@ private static void AssertExpectedLoggingEvent(LoggingEvent loggingEvent, Loggin Assert.AreEqual(Level.Warn, loggingEventData.Level, "Level is incorrect"); Assert.AreEqual("get_LocationInformation", loggingEvent.LocationInformation.MethodName, "Location Info is incorrect"); Assert.AreEqual("log4net.Tests.Core.FixingTest", loggingEventData.LoggerName, "LoggerName is incorrect"); - Assert.AreEqual(LogManager.GetRepository("Test Repository"), loggingEvent.Repository, "Repository is incorrect"); + Assert.AreEqual(LogManager.GetRepository(TEST_REPOSITORY), loggingEvent.Repository, "Repository is incorrect"); Assert.AreEqual(Thread.CurrentThread.Name, loggingEventData.ThreadName, "ThreadName is incorrect"); Assert.IsNotNull(loggingEventData.TimeStamp, "TimeStamp is incorrect"); Assert.AreEqual("TestUser", loggingEventData.UserName, "UserName is incorrect"); From 7b3947543a47468db69817c228a21b880d937c3c Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Sep 2011 09:23:52 +0000 Subject: [PATCH 029/370] test new MutexLock and make it actually work. LOG4NET-164 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1166079 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/FileAppender.cs | 32 +++++---- tests/src/Appender/RollingFileAppenderTest.cs | 69 ++++++++++++++++++- 2 files changed, 86 insertions(+), 15 deletions(-) diff --git a/src/Appender/FileAppender.cs b/src/Appender/FileAppender.cs index 54f3f29d..ff5993d4 100644 --- a/src/Appender/FileAppender.cs +++ b/src/Appender/FileAppender.cs @@ -388,7 +388,7 @@ protected Stream CreateStream(string filename, bool append, FileShare fileShare) } FileMode fileOpenMode = append ? FileMode.Append : FileMode.Create; - return new FileStream(filename, fileOpenMode, FileAccess.Write, FileShare.Read); + return new FileStream(filename, fileOpenMode, FileAccess.Write, fileShare); } } @@ -640,12 +640,15 @@ public override void OpenFile(string filename, bool append, Encoding encoding) /// public override void CloseFile() { - CloseStream(m_stream); - m_stream = null; - - m_mutex.ReleaseMutex(); - m_mutex.Close(); - m_mutexClosed = true; + try { + CloseStream(m_stream); + m_stream = null; + } + finally { + m_mutex.ReleaseMutex(); + m_mutex.Close(); + m_mutexClosed = true; + } } /// @@ -659,13 +662,14 @@ public override void CloseFile() /// public override Stream AcquireLock() { - // TODO: add timeout? - m_mutex.WaitOne(); + if (m_mutex != null) { + // TODO: add timeout? + m_mutex.WaitOne(); - // should always be true (and fast) for FileStream - if (m_stream.CanSeek) - { - m_stream.Seek(0, SeekOrigin.End); + // should always be true (and fast) for FileStream + if (m_stream.CanSeek) { + m_stream.Seek(0, SeekOrigin.End); + } } return m_stream; @@ -676,7 +680,7 @@ public override Stream AcquireLock() /// public override void ReleaseLock() { - if (m_mutexClosed == false) + if (m_mutexClosed == false && m_mutex != null) { m_mutex.ReleaseMutex(); } diff --git a/tests/src/Appender/RollingFileAppenderTest.cs b/tests/src/Appender/RollingFileAppenderTest.cs index 8bfcb642..13338062 100644 --- a/tests/src/Appender/RollingFileAppenderTest.cs +++ b/tests/src/Appender/RollingFileAppenderTest.cs @@ -1603,7 +1603,74 @@ public void TestMinimalLockUnlocks() Assert.AreEqual("", sh.Message, "Unexpected error message"); } - /// + /// + /// Verifies that attempting to log to a locked file fails gracefully + /// + [Test] + public void TestMutexLockFails() { + String filename = "test.log"; + + FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None); + fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4); + + SilentErrorHandler sh = new SilentErrorHandler(); + ILogger log = CreateLogger(filename, new FileAppender.MutexLock(), sh); + log.Log(GetType(), Level.Info, "This is a message", null); + log.Log(GetType(), Level.Info, "This is a message 2", null); + DestroyLogger(); + fs.Close(); + + AssertFileEquals(filename, "Test"); + Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message"); + } + + /// + /// Verifies that attempting to log to a locked file recovers if the lock is released + /// + [Test] + public void TestMutexLockRecovers() { + String filename = "test.log"; + + FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None); + fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4); + + SilentErrorHandler sh = new SilentErrorHandler(); + ILogger log = CreateLogger(filename, new FileAppender.MutexLock(), sh); + log.Log(GetType(), Level.Info, "This is a message", null); + fs.Close(); + log.Log(GetType(), Level.Info, "This is a message 2", null); + DestroyLogger(); + + AssertFileEquals(filename, "This is a message 2" + Environment.NewLine); + Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message"); + } + + /// + /// Verifies that attempting to log to a file with ExclusiveLock really locks the file + /// + [Test] + public void TestMutexLockUnlocks() { + String filename = "test.log"; + bool locked; + + SilentErrorHandler sh = new SilentErrorHandler(); + ILogger log = CreateLogger(filename, new FileAppender.MutexLock(), sh); + log.Log(GetType(), Level.Info, "This is a message", null); + + locked = true; + FileStream fs = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); + fs.Write(Encoding.ASCII.GetBytes("Test" + Environment.NewLine), 0, 4 + Environment.NewLine.Length); + fs.Close(); + + log.Log(GetType(), Level.Info, "This is a message 2", null); + DestroyLogger(); + + Assert.IsTrue(locked, "File was not locked"); + AssertFileEquals(filename, "This is a message" + Environment.NewLine + "Test" + Environment.NewLine + "This is a message 2" + Environment.NewLine); + Assert.AreEqual("", sh.Message, "Unexpected error message"); + } + + /// /// Verify that the default LockModel is ExclusiveLock, to maintain backwards compatibility with previous behaviour /// [Test] From a507483852d9c2b4899f5e52f029fd23bf06dd26 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Sep 2011 11:00:12 +0000 Subject: [PATCH 030/370] Use mvn purely to generate the site, improve layout a bit, add footer as required by branding rules. LOG4NET-117, LOG4NET-275 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1166110 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 225 +++----- src/site/apt/download.apt | 15 +- src/site/resources/css/maven-base.css | 168 ++++++ src/site/site.vm | 542 ++++++++++++++++++ src/site/site.xml | 2 +- src/site/xdoc/release/building.xml | 8 +- src/site/xdoc/release/features.xml | 20 +- src/site/xdoc/release/framework-support.xml | 32 +- .../xdoc/release/manual/configuration.xml | 28 +- src/site/xdoc/release/manual/contexts.xml | 2 +- src/site/xdoc/release/manual/introduction.xml | 16 +- src/site/xdoc/release/release-notes.xml | 224 -------- src/site/xdoc/stylesheets/project.xml | 65 --- src/site/xdoc/stylesheets/site.vsl | 406 ------------- 14 files changed, 829 insertions(+), 924 deletions(-) create mode 100644 src/site/resources/css/maven-base.css create mode 100644 src/site/site.vm delete mode 100644 src/site/xdoc/stylesheets/project.xml delete mode 100644 src/site/xdoc/stylesheets/site.vsl diff --git a/pom.xml b/pom.xml index 93fb57e2..9a8ebe32 100644 --- a/pom.xml +++ b/pom.xml @@ -23,10 +23,11 @@ 1.2.11-SNAPSHOT Apache log4net Logging framework for Microsoft .NET Framework. - http://logging.apache.org:80/log4net + http://logging.apache.org/log4net/ + 2004 JIRA - http://issues.apache.org/jira/ + http://issues.apache.org/jira/LOG4NET Gump @@ -55,6 +56,13 @@ http://dir.gmane.org/gmane.comp.apache.logging.log4net.devel + + logging commits : all svn commits of the logging projects including log4net + commits-subscribe@logging.apache.org + commits-unsubscribe@logging.apache.org + Read-Only List + http://mail-archives.apache.org/mod_mbox/logging-commits/ + @@ -66,7 +74,7 @@ scm:svn:http://svn.apache.org/repos/asf/logging/log4net/trunk scm:svn:https://svn.apache.org/repos/asf/logging/log4net/trunk - http://svn.apache.org/viewcvs.cgi/logging/log4net/trunk + http://svn.apache.org/viewvc/logging/log4net/trunk Apache Software Foundation @@ -75,168 +83,79 @@ - maven-antrun-plugin - - - compile - compile - - - - - - - run - - - - test-compile - test-compile - - - - - - - - - run - - - - test - test - - - - - - - - - run - - - - site - site - - - - - - - - - - run - - - - post-site - post-site - - - - - - - - - run - - - - site-deploy - site-deploy - - - - - - - - - run - - - - - - ant - ant-nodeps - 1.6.5 - - + org.apache.rat + apache-rat-plugin + 0.7 - maven-assembly-plugin + org.apache.maven.plugins + maven-site-plugin + 3.0 - - src/assembly/bin.xml - - false + + + + ${basedir}/src/site/site.vm + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.4 + + + + cim + scm + dependencies + license + project-team + issue-tracking + mailing-list + + + + + + + + org.apache.maven.plugins + maven-changes-plugin + 2.6 + + + + changes-report + jira-report + + + + + Resolved, Closed + Type,Key,Summary,Assignee,Status,Resolution,Fix Version + + + + + + org.apache.rat + apache-rat-plugin + 0.7 + + - - - - assembly - - - + - - true - - - maven-project-info-reports-plugin - - - - scm - cim - dependencies - issue-tracking - mailing-list - license - - - - - - maven-release-plugin - - site-deploy - - - - maven-changes-plugin - - - - changes-report - - - - - %URL%/browse/%ISSUE% - - - - + logging.site - file:///tmp/log4net-deploy + file:///${user.dir}/target/site-deploy diff --git a/src/site/apt/download.apt b/src/site/apt/download.apt index 277a4edd..4c8f7175 100644 --- a/src/site/apt/download.apt +++ b/src/site/apt/download.apt @@ -31,13 +31,14 @@ Download Apache log4net 1.2.10 try a different browser. The checksum and signature are links to the originals on the main distribution server. -*-------------------------+---------+----------+-----------+ -| | Mirrors | Checksum | Signature | -*-------------------------+---------+----------+-----------+ -*-------------------------+---------+----------+-----------+ -| log4net 1.2.10 (zip) | {{{http://archive.apache.org/dist/incubator/log4net/1.2.10/incubating-log4net-1.2.10.zip} incubating-log4net-1.2.10.zip}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.10/incubating-log4net-1.2.10.zip.md5} incubating-log4net-1.2.10.zip.md5}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.10/incubating-log4net-1.2.10.zip.asc} incubating-log4net-1.2.10.zip.asc}}| -| log4net 1.2.9-beta (zip) | {{{http://archive.apache.org/dist/incubator/log4net/1.2.9/incubating-log4net-1.2.9-beta.zip} incubating-log4net-1.2.9-beta.zip}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.9/incubating-log4net-1.2.9-beta.zip.md5} incubating-log4net-1.2.9-beta.zip.md5}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.9/incubating-log4net-1.2.9-beta.zip.asc} incubating-log4net-1.2.9-beta.zip.asc}}| -*-------------------------+---------+----------+-----------+ +*------------------------+---------+----------+-----------+ + | Mirrors | Checksum | Signature | +*------------------------+---------+----------+-----------+ +*------------------------+---------+----------+-----------+ + log4net 1.2.10 (zip) | {{{http://archive.apache.org/dist/incubator/log4net/1.2.10/incubating-log4net-1.2.10.zip} incubating-log4net-1.2.10.zip}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.10/incubating-log4net-1.2.10.zip.md5} incubating-log4net-1.2.10.zip.md5}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.10/incubating-log4net-1.2.10.zip.asc} incubating-log4net-1.2.10.zip.asc}}| +*------------------------+---------+----------+-----------+ + log4net 1.2.9-beta (zip) | {{{http://archive.apache.org/dist/incubator/log4net/1.2.9/incubating-log4net-1.2.9-beta.zip} incubating-log4net-1.2.9-beta.zip}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.9/incubating-log4net-1.2.9-beta.zip.md5} incubating-log4net-1.2.9-beta.zip.md5}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.9/incubating-log4net-1.2.9-beta.zip.asc} incubating-log4net-1.2.9-beta.zip.asc}}| +*------------------------+---------+----------+-----------+ Please read {{{http://httpd.apache.org/dev/verification.html}Verifying Apache HTTP Server Releases}} for more information on why you should verify our releases. diff --git a/src/site/resources/css/maven-base.css b/src/site/resources/css/maven-base.css new file mode 100644 index 00000000..0167aa87 --- /dev/null +++ b/src/site/resources/css/maven-base.css @@ -0,0 +1,168 @@ +/* + 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. + +*/ +body { + margin: 0px; + padding: 0px; +} +img { + border:none; +} +table { + padding:0px; + width: 100%; + margin-left: -2px; + margin-right: -2px; +} +acronym { + cursor: help; + border-bottom: 1px dotted #feb; +} +table.bodyTable th, table.bodyTable td { + padding: 2px 4px 2px 4px; + vertical-align: top; +} +div.clear{ + clear:both; + visibility: hidden; +} +div.clear hr{ + display: none; +} +#bannerLeft, #bannerRight { + font-size: xx-large; + font-weight: bold; +} +#bannerLeft img, #bannerRight img { + margin: 0px; +} +.xleft, #bannerLeft img { + float:left; +} +.xright, #bannerRight { + float:right; +} +#banner { + padding: 0px; +} +#banner img { + border: none; +} +#breadcrumbs { + padding: 3px 10px 3px 10px; +} +#leftColumn { + width: 170px; + float:left; + overflow: auto; +} +#bodyColumn { + margin-right: 1.5em; + margin-left: 197px; +} +#legend { + padding: 8px 0 8px 0; +} +#navcolumn { + padding: 8px 4px 0 8px; +} +#navcolumn h5 { + margin: 0; + padding: 0; + font-size: small; +} +#navcolumn ul { + margin: 0; + padding: 0; + font-size: small; +} +#navcolumn li { + list-style-type: none; + background-image: none; + background-repeat: no-repeat; + background-position: 0 0.4em; + padding-left: 16px; + list-style-position: outside; + line-height: 1.2em; + font-size: smaller; +} +#navcolumn li.expanded { + background-image: url(../images/expanded.gif); +} +#navcolumn li.collapsed { + background-image: url(../images/collapsed.gif); +} +#poweredBy { + text-align: center; +} +#navcolumn img { + margin-top: 10px; + margin-bottom: 3px; +} +#poweredBy img { + display:block; + margin: 20px 0 20px 17px; +} +#search img { + margin: 0px; + display: block; +} +#search #q, #search #btnG { + border: 1px solid #999; + margin-bottom:10px; +} +#search form { + margin: 0px; +} +#lastPublished { + font-size: x-small; +} +.navSection { + margin-bottom: 2px; + padding: 8px; +} +.navSectionHead { + font-weight: bold; + font-size: x-small; +} +.section { + padding: 4px; +} +#footer { + padding: 3px 10px 3px 10px; + font-size: x-small; +} +#breadcrumbs { + font-size: x-small; + margin: 0pt; +} +.source { + padding: 12px; + margin: 1em 7px 1em 7px; +} +.source pre { + margin: 0px; + padding: 0px; +} +#navcolumn img.imageLink, .imageLink{ + padding-left: 0px; + padding-bottom: 0px; + padding-top: 0px; + padding-right: 2px; + border: 0px; + margin: 0px; +} diff --git a/src/site/site.vm b/src/site/site.vm new file mode 100644 index 00000000..4b46bbf6 --- /dev/null +++ b/src/site/site.vm @@ -0,0 +1,542 @@ + + +#macro ( link $href $name $target $img $position $alt $border $width $height ) + #set ( $linkTitle = ' title="' + $name + '"' ) + #if( $target ) + #set ( $linkTarget = ' target="' + $target + '"' ) + #else + #set ( $linkTarget = "" ) + #end + #if ( $href.toLowerCase().startsWith("http:/") || $href.toLowerCase().startsWith("https:/") || + $href.toLowerCase().startsWith("ftp:/") || $href.toLowerCase().startsWith("mailto:/") || + $href.toLowerCase().startsWith("file:/") || ($href.toLowerCase().indexOf("://") != -1) ) + #set ( $linkClass = ' class="externalLink"' ) + #else + #set ( $linkClass = "" ) + #end + #if ( $img ) + #if ( $position == "left" ) + #image($img $alt $border $width $height)$name + #else + $name #image($img $alt $border $width $height) + #end + #else + $name + #end +#end +## +#macro ( image $img $alt $border $width $height ) + #if( $img ) + #if ( ! ( $img.toLowerCase().startsWith("http:/") || $img.toLowerCase().startsWith("https:/") || + $img.toLowerCase().startsWith("ftp:/") || $img.toLowerCase().startsWith("mailto:/") || + $img.toLowerCase().startsWith("file:/") || ($img.toLowerCase().indexOf("://") != -1) ) ) + #set ( $imgSrc = $PathTool.calculateLink( $img, $relativePath ) ) + #set ( $imgSrc = $imgSrc.replaceAll( '\\', '/' ) ) + #set ( $imgSrc = ' src="' + $imgSrc + '"' ) + #else + #set ( $imgSrc = ' src="' + $img + '"' ) + #end + #if( $alt ) + #set ( $imgAlt = ' alt="' + $alt + '"' ) + #else + #set ( $imgAlt = ' alt=""' ) + #end + #if( $border ) + #set ( $imgBorder = ' border="' + $border + '"' ) + #else + #set ( $imgBorder = "" ) + #end + #if( $width ) + #set ( $imgWidth = ' width="' + $width + '"' ) + #else + #set ( $imgWidth = "" ) + #end + #if( $height ) + #set ( $imgHeight = ' height="' + $height + '"' ) + #else + #set ( $imgHeight = "" ) + #end + + #end +#end +#macro ( banner $banner $id ) + #if ( $banner ) + #if( $banner.href ) + #set ( $hrf = $banner.href ) + #if ( ! ( $hrf.toLowerCase().startsWith("http:/") || $hrf.toLowerCase().startsWith("https:/") || + $hrf.toLowerCase().startsWith("ftp:/") || $hrf.toLowerCase().startsWith("mailto:/") || + $hrf.toLowerCase().startsWith("file:/") || ($hrf.toLowerCase().indexOf("://") != -1) ) ) + #set ( $hrf = $PathTool.calculateLink( $hrf, $relativePath ) ) + #set ( $hrf = $hrf.replaceAll( '\\', '/' ) ) + #if ( ( $hrf == '' ) ) + #set ( $hrf = './' ) + #end + #end + + #else + + #end + #end +#end +## +#macro ( links $links ) + #set ( $counter = 0 ) + #foreach( $item in $links ) + #set ( $counter = $counter + 1 ) + #set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) ) + #set ( $currentItemHref = $currentItemHref.replaceAll( '\\', '/' ) ) + #link( $currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height ) + #if ( $links.size() > $counter ) + | + #end + #end +#end +## +#macro ( breadcrumbs $breadcrumbs ) + #foreach( $item in $breadcrumbs ) + #set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) ) + #set ( $currentItemHref = $currentItemHref.replaceAll( '\\', '/' ) ) + #if ( ( $currentItemHref == '' ) ) + #set ( $currentItemHref = './' ) + #end +## + #link( $currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height ) + > + #end + $title +#end +## +#macro ( displayTree $display $item ) + #if ( $item && $item.items && $item.items.size() > 0 ) + #foreach( $subitem in $item.items ) + #set ( $subitemHref = $PathTool.calculateLink( $subitem.href, $relativePath ) ) + #set ( $subitemHref = $subitemHref.replaceAll( '\\', '/' ) ) +## + #if ( $alignedFileName == $subitemHref ) + #set ( $display = true ) + #end +## + #displayTree( $display $subitem ) + #end + #end +#end +## +#macro ( menuItem $item ) + #set ( $collapse = "none" ) + #set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) ) + #set ( $currentItemHref = $currentItemHref.replaceAll( '\\', '/' ) ) +## + #if ( $item && $item.items && $item.items.size() > 0 ) + #if ( $item.collapse == false ) + #set ( $collapse = "expanded" ) + #else + ## By default collapsed + #set ( $collapse = "collapsed" ) + #end +## + #set ( $display = false ) + #displayTree( $display $item ) +## + #if ( $alignedFileName == $currentItemHref || $display ) + #set ( $collapse = "expanded" ) + #end + #end +
  • + #if ( $item.img ) + #if ( $item.position == "left" ) + #if ( $alignedFileName == $currentItemHref ) + #image($item.img $item.alt $item.border $item.width $item.height) $item.name + #else + #link($currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height) + #end + #else + #if ( $alignedFileName == $currentItemHref ) + $item.name #image($item.img $item.alt $item.border $item.width $item.height) + #else + #link($currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height) + #end + #end + #else + #if ( $alignedFileName == $currentItemHref ) + $item.name + #else + #link( $currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height ) + #end + #end + #if ( $item && $item.items && $item.items.size() > 0 ) + #if ( $collapse == "expanded" ) +
      + #foreach( $subitem in $item.items ) + #menuItem( $subitem ) + #end +
    + #end + #end +
  • +#end +## +#macro ( mainMenu $menus ) + #foreach( $menu in $menus ) + #if ( $menu.name ) + #if ( $menu.img ) + #if( $menu.position ) + #set ( $position = $menu.position ) + #else + #set ( $position = "left" ) + #end +## + #if ( ! ( $menu.img.toLowerCase().startsWith("http:/") || $menu.img.toLowerCase().startsWith("https:/") || + $menu.img.toLowerCase().startsWith("ftp:/") || $menu.img.toLowerCase().startsWith("mailto:/") || + $menu.img.toLowerCase().startsWith("file:/") || ($menu.img.toLowerCase().indexOf("://") != -1) ) ) + #set ( $src = $PathTool.calculateLink( $menu.img, $relativePath ) ) + #set ( $src = $src.replaceAll( '\\', '/' ) ) + #set ( $src = ' src="' + $src + '"' ) + #else + #set ( $src = ' src="' + $menu.img + '"' ) + #end +## + #if( $menu.alt ) + #set ( $alt = ' alt="' + $menu.alt + '"' ) + #else + #set ( $alt = ' alt="' + $menu.name + '"' ) + #end +## + #if( $menu.border ) + #set ( $border = ' border="' + $menu.border + '"' ) + #else + #set ( $border = ' border="0"' ) + #end +## + #if( $menu.width ) + #set ( $width = ' width="' + $menu.width + '"' ) + #else + #set ( $width = "" ) + #end + #if( $menu.height ) + #set ( $height = ' height="' + $menu.height + '"' ) + #else + #set ( $height = "" ) + #end +## + #set ( $img = '" ) +## + #if ( $position == "left" ) +
    $img $menu.name
    + #else +
    $menu.name $img
    + #end + #else +
    $menu.name
    + #end + #end + #if ( $menu.items && $menu.items.size() > 0 ) +
      + #foreach( $item in $menu.items ) + #menuItem( $item ) + #end +
    + #end + #end +#end +## +#macro ( copyright ) + #if ( $project ) + #if ( ${project.organization} && ${project.organization.name} ) + #set ( $period = "" ) + #else + #set ( $period = "." ) + #end +## + #set ( $currentYear = ${currentDate.year} + 1900 ) +## + #if ( ${project.inceptionYear} && ( ${project.inceptionYear} != ${currentYear.toString()} ) ) + ${project.inceptionYear}-${currentYear}${period} + #else + ${currentYear}${period} + #end +## + #if ( ${project.organization} ) + #if ( ${project.organization.name} && ${project.organization.url} ) + ${project.organization.name}. + #elseif ( ${project.organization.name} ) + ${project.organization.name}. + #end + #end + #end +#end +## +#macro ( publishDate $position $publishDate $version ) + #if ( $publishDate && $publishDate.format ) + #set ( $format = $publishDate.format ) + #else + #set ( $format = "yyyy-MM-dd" ) + #end +## + $dateFormat.applyPattern( $format ) +## + #set ( $dateToday = $dateFormat.format( $currentDate ) ) +## + #if ( $publishDate && $publishDate.position ) + #set ( $datePosition = $publishDate.position ) + #else + #set ( $datePosition = "left" ) + #end +## + #if ( $version ) + #if ( $version.position ) + #set ( $versionPosition = $version.position ) + #else + #set ( $versionPosition = "left" ) + #end + #else + #set ( $version = "" ) + #set ( $versionPosition = "left" ) + #end +## + #set ( $breadcrumbs = $decoration.body.breadcrumbs ) + #set ( $links = $decoration.body.links ) + + #if ( $datePosition.equalsIgnoreCase( "right" ) && $links && $links.size() > 0 ) + #set ( $prefix = " |" ) + #else + #set ( $prefix = "" ) + #end +## + #if ( $datePosition.equalsIgnoreCase( $position ) ) + #if ( ( $datePosition.equalsIgnoreCase( "right" ) ) || ( $datePosition.equalsIgnoreCase( "bottom" ) ) ) + $prefix $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday + #if ( $versionPosition.equalsIgnoreCase( $position ) ) +  | $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version} + #end + #elseif ( ( $datePosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $datePosition.equalsIgnoreCase( "navigation-top" ) ) ) +
    + $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday + #if ( $versionPosition.equalsIgnoreCase( $position ) ) +  | $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version} + #end +
    + #elseif ( $datePosition.equalsIgnoreCase("left") ) +
    + $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday + #if ( $versionPosition.equalsIgnoreCase( $position ) ) +  | $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version} + #end + #if ( $breadcrumbs && $breadcrumbs.size() > 0 ) + | #breadcrumbs( $breadcrumbs ) + #end +
    + #end + #elseif ( $versionPosition.equalsIgnoreCase( $position ) ) + #if ( ( $versionPosition.equalsIgnoreCase( "right" ) ) || ( $versionPosition.equalsIgnoreCase( "bottom" ) ) ) + $prefix $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version} + #elseif ( ( $versionPosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $versionPosition.equalsIgnoreCase( "navigation-top" ) ) ) +
    + $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version} +
    + #elseif ( $versionPosition.equalsIgnoreCase("left") ) +
    + $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version} + #if ( $breadcrumbs && $breadcrumbs.size() > 0 ) + | #breadcrumbs( $breadcrumbs ) + #end +
    + #end + #elseif ( $position.equalsIgnoreCase( "left" ) ) + #if ( $breadcrumbs && $breadcrumbs.size() > 0 ) +
    + #breadcrumbs( $breadcrumbs ) +
    + #end + #end +#end +## +#macro ( poweredByLogo $poweredBy ) + #if( $poweredBy ) + #foreach ($item in $poweredBy) + #if( $item.href ) + #set ( $href = $PathTool.calculateLink( $item.href, $relativePath ) ) + #set ( $href = $href.replaceAll( '\\', '/' ) ) + #else + #set ( $href="http://maven.apache.org/" ) + #end +## + #if( $item.name ) + #set ( $name = $item.name ) + #else + #set ( $name = $i18n.getString( "site-renderer", $locale, "template.builtby" ) ) + #set ( $name = "${name} Maven" ) + #end +## + #if( $item.img ) + #set ( $img = $item.img ) + #else + #set ( $img = "images/logos/maven-feather.png" ) + #end +## + #if ( ! ( $img.toLowerCase().startsWith("http:/") || $img.toLowerCase().startsWith("https:/") || + $img.toLowerCase().startsWith("ftp:/") || $img.toLowerCase().startsWith("mailto:/") || + $img.toLowerCase().startsWith("file:/") || ($img.toLowerCase().indexOf("://") != -1) ) ) + #set ( $img = $PathTool.calculateLink( $img, $relativePath ) ) + #set ( $img = $img.replaceAll( '\\', '/' ) ) + #end +## + #if( $item.alt ) + #set ( $alt = ' alt="' + $item.alt + '"' ) + #else + #set ( $alt = ' alt="' + $name + '"' ) + #end +## + #if( $item.border ) + #set ( $border = ' border="' + $item.border + '"' ) + #else + #set ( $border = "" ) + #end +## + #if( $item.width ) + #set ( $width = ' width="' + $item.width + '"' ) + #else + #set ( $width = "" ) + #end + #if( $item.height ) + #set ( $height = ' height="' + $item.height + '"' ) + #else + #set ( $height = "" ) + #end +## + + + + #end + #if( $poweredBy.isEmpty() ) + + $i18n.getString( + + #end + #else + + $i18n.getString( + + #end +#end +## +#macro ( googleAnalytics $accountId ) + #if( $accountId && $accountId != "" ) + + + #end +#end +## + + + + $title + + +#foreach( $author in $authors ) + +#end +#if ( $dateCreation ) + +#end +#if ( $dateRevision ) + +#end +#if ( $locale ) + +#end + #if ( $decoration.body.head ) + #foreach( $item in $decoration.body.head.getChildren() ) + ## Workaround for DOXIA-150 due to a non-desired behaviour in p-u + ## @see org.codehaus.plexus.util.xml.Xpp3Dom#toString() + ## @see org.codehaus.plexus.util.xml.Xpp3Dom#toUnescapedString() + #set ( $documentHeader = '' ) + #if ( $item.name == "script" ) + $StringUtils.replace( $item.toUnescapedString(), $documentHeader, "" ) + #else + $StringUtils.replace( $item.toString(), $documentHeader, "" ) + #end + #end + #end + $headContent + #googleAnalytics( $decoration.googleAnalyticsAccountId ) + + + + +
    + +
    +
    +
    + $bodyContent +
    +
    +
    +
    +
    +

    - The log4net HTML documentation is built using Velocity. - The source are XML files in the xdocs/src directory. - Building the documentation requires Java, Ant, and Velocity. - Run ant from within the xdocs directory. + The log4net HTML documentation is built using Apache Maven. + The source are files in various formats in the src/site directory. + Building the documentation requires Java 5 or newer and Maven 2.2.1 or newer. + Run mvn from within the root directory.

    diff --git a/src/site/xdoc/release/features.xml b/src/site/xdoc/release/features.xml index 616fa089..bef112ba 100644 --- a/src/site/xdoc/release/features.xml +++ b/src/site/xdoc/release/features.xml @@ -27,8 +27,6 @@ limitations under the License.
    - -

    log4net is a tool to help the programmer output log statements to a @@ -53,15 +51,15 @@ limitations under the License.

      -
    • Support for multiple frameworks

    • -
    • Output to multiple logging targets

    • -
    • Hierarchical logging architecture

    • -
    • XML Configuration

    • -
    • Dynamic Configuration

    • -
    • Logging Context

    • -
    • Proven architecture

    • -
    • Modular and extensible design

    • -
    • High performance with flexibility

    • +
    • Support for multiple frameworks
    • +
    • Output to multiple logging targets
    • +
    • Hierarchical logging architecture
    • +
    • XML Configuration
    • +
    • Dynamic Configuration
    • +
    • Logging Context
    • +
    • Proven architecture
    • +
    • Modular and extensible design
    • +
    • High performance with flexibility
    diff --git a/src/site/xdoc/release/framework-support.xml b/src/site/xdoc/release/framework-support.xml index ce7d3c6a..c6539bf5 100644 --- a/src/site/xdoc/release/framework-support.xml +++ b/src/site/xdoc/release/framework-support.xml @@ -27,8 +27,6 @@ limitations under the License.
    - -

    log4net is built on a number of different frameworks. Each new version of the frameworks add @@ -58,7 +56,7 @@ limitations under the License.

    - +
    @@ -118,7 +116,7 @@ limitations under the License. framework and the platform it runs on:

    -
    +
    @@ -382,8 +380,6 @@ limitations under the License.
    -
      -
    • Assembly attributes

      The .NET Compact Framework 1.0 does not support retrieving assembly level @@ -425,8 +421,6 @@ namespace TestApp } } -

    • -
    • Notification events

      The .NET Compact Framework 1.0 does not support notification events during the @@ -440,8 +434,6 @@ namespace TestApp method in order to prevent losing logging events. See the code above for an example.

      -
    • -
    • FileSystemWatcher

      The .NET Compact Framework 1.0 does not support the @@ -453,8 +445,6 @@ namespace TestApp methods are not available. Watching changes to the log4net configuration file is not supported on the .NET Compact Framework 1.0.

      -
    • -
    • UserName

      The .NET Compact Framework 1.0 does not support the @@ -463,8 +453,6 @@ namespace TestApp the LoggingEvent.UserName property will return the value "NOT AVAILABLE".

      -
    • -
    • Identity

      The .NET Compact Framework 1.0 does not support the @@ -473,23 +461,17 @@ namespace TestApp the LoggingEvent.Identity property will return the value "NOT AVAILABLE".

      -
    • -
    • Environment variables

      The .NET Compact Framework 1.0 does not support retrieving environment variables, therefore it's not possible to substitute environment variables in parameter values when using the .NET Compact Framework 1.0 version of log4net.

      -
    • -
    • Serialization

      The .NET Compact Framework 1.0 does not support serialization, therefore none of the log4net classes in the .NET Compact Framework 1.0 version are serializable.

      -
    • -
    • LoggingEvent.Domain

      The .NET Compact Framework 1.0 does not support AppDomain functionality. The @@ -498,8 +480,6 @@ namespace TestApp PatternLayout. On the .NET Compact Framework 1.0 this value is generated by taking the file name for the application's primary module.

      -
    • -
    - - - log4net - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/site/xdoc/stylesheets/site.vsl b/src/site/xdoc/stylesheets/site.vsl deleted file mode 100644 index 25910232..00000000 --- a/src/site/xdoc/stylesheets/site.vsl +++ /dev/null @@ -1,406 +0,0 @@ - - - - - - ## Defined variables - #set ($bodybg = "#ffffff") - #set ($bodyfg = "#000000") - #set ($bodylink = "#525D76") - - #set ($titlebg = "#FFFFFF") - #set ($titlefg = "#2222AA") - -## #set ($bannerbg = "#525D76") - #set ($bannerbg = "#FFFFFF") - #set ($bannerfg = "#2222AA") - - #set ($subbannerbg = "#828DA6") - #set ($subbannerfg = "#ffffff") - #set ($tablethbg = "#039acc") - #set ($tabletdbg = "#a0ddf0") - - -#document() - - -## This is where the macro's live - -#macro ( projectanchor $name $value ) -#if ($value.startsWith("http://")) - $name -## #elseif ($value.startsWith("/site")) -## $name -#else - $name -#end -#end - -#macro ( metaauthor $author $email ) - - -#end - -#macro ( image $value ) -#if ($value.getAttributeValue("width")) -#set ($width=$value.getAttributeValue("width")) -#end -#if ($value.getAttributeValue("height")) -#set ($height=$value.getAttributeValue("height")) -#end -#if ($value.getAttributeValue("align")) -#set ($align=$value.getAttributeValue("align")) -#end - -#end - -#macro ( old_source $value ) -
    -
    - - - - - - - - - - - - - - - -
    $escape.getText($value.getText())
    -
    -#end - -#macro ( source $value ) - -
    $escape.getText($value.getText())
    - -#end - -## =================================== -## titleSection macro -## =================================== -#macro ( titleSection $titleSection) - $titleSection.getAttributeValue("name") -#end - -## ================================ -## section macro -## ================================ -#macro ( section $section $level ) - #if($section.getAttributeValue("id")) - $section.getAttributeValue("name") - #else - $section.getAttributeValue("name") - #end -
    - #foreach ( $item in $section.getChildren() ) - #if ($items.getName().equals("img")) - #image ($item) - #elseif ($item.getName().equals("source")) - #source ($item) - #elseif ($item.getName().equals("table")) - #table ($item) - #elseif ($item.getName().equals("section")) - #set ($nextLevel = $level + 1) - #section ($item $nextLevel ) - #set ($nextLevel = $nextLevel - 1) - #elseif ($item.getName().equals("sectionMenu")) - #set ($nextLevel = $level + 1) - #sectionMenu1 ($item $item.getParent() $nextLevel) - #set ($nextLevel = $nextLevel - 1) - #else - $item - #end - #end -
    -#end - -## ================================ -## sectionMenu1 macro -## ================================ -#macro ( sectionMenu1 $sectionMenu $section $level ) - #if($sectionMenu.getAttributeValue("name")) - $sectionMenu.getAttributeValue("name") -
    - #foreach ( $items in $section.getChildren() ) - #if ($items.getName().equals("section")) - #sectionMenu2 ($items ) - #end - #end -
    - #else - #foreach ( $items in $section.getChildren() ) - #if ($items.getName().equals("section")) - #sectionMenu2 ($items ) - #end - #end - #end -#end - -## ================================ -## sectionMenu2 macro -## ================================ -#macro ( sectionMenu2 $section ) - #if ($section.getAttributeValue("id")) - $section.getAttributeValue("name")
    - #else - $section.getAttributeValue("name")
    - #end -
    - #foreach ( $items in $section.getChildren() ) - #if ($items.getName().equals("section")) - #sectionMenu2 ($items ) - #end - #end -
    -#end - -## =================================== -## make navigation bar -## =================================== - -#macro ( makeNavigationBar ) - -
    - #set ($menus = $project.getChild("body").getChildren("menu")) - #foreach ( $menu in $menus ) - - #foreach ($item in $menu.getChildren() ) - #set ($name = $item.getAttributeValue("name")) - - #end - #end -
    - -#end - -## ==================================== -## getProjectImage -## ==================================== -#macro (getProjectImage) - ## -#end - -#macro (printMeta $metaElement) - -#end - -#macro (messages $root) - #foreach ( $m in $root.getChild("body").getChildren() ) - #if ($m.getName().equals("message")) - -
    - $m.getChild("explanation").getContent() -
    - #end - #end -#end - -#macro (document) - #set ($properties = $root.getChild("properties") ) - - - - - - - - - #set ($authors = $root.getChild("properties").getChildren("author")) - #foreach ( $au in $authors ) - #metaauthor ( $au.getText() $au.getAttributeValue("email") ) - #end - - #set ($metas = $root.getChildren("meta")) - - ## Parse meta directives such as - ## - #foreach ($meta in $metas) #printMeta($meta) #end - - ## Support for tags. - #if ($root.getChild("properties").getChild("base")) - #set ($url = $root.getChild("properties").getChild("base").getAttributeValue("href")) - - #end - - - - #foreach ( $cssItem in $project.getChildren("css") ) - - #end - - $root.getChild("properties").getChild("title").getText() - - #if ($root.getChild("head")) - $root.getChild("head").getContent() - #end - - - - ## Google analytics code - - - - -## -## -## - #getProjectImage() -## -##
    - - - -
    - ##
    - - -## -## - -## -## -## -## -## - - - #messages ($root) - - -

     

    - -## -## - ##
    -##
    -##
    - - #foreach ( $item in $root.getChild("body").getChildren() ) - #if ($item.getName().equals("img")) - #image ($item) - #elseif ($item.getName().equals("section")) - #section ($item 1) - #elseif ($item.getName().equals("source")) - #source ($item) - #elseif ($item.getName().equals("table")) - #table ($item) - #elseif ($item.getName().equals("sectionMenu")) - #sectionMenu1 ($item $item.getParent() 1) - #else - $item - #end - #end - -## #if ($root.getChild("body").getChild("titleSection")) -## #set ($titleSection = $root.getChild("body").getChild("titleSection")) -## #titleSection($titleSection) -## #end -##
    -##
    -##
    -
    - Copyright © - #if($root.getChild("properties").getChild("copyright").getAttributeValue("year")) - ${root.getChild("properties").getChild("copyright").getAttributeValue("year")}, - #elseif($project.getChild("copyright").getAttributeValue("year")) - ${project.getChild("copyright").getAttributeValue("year")}, - #else - 1999-2007, - #end - #if($root.getChild("properties").getChild("copyright").getAttributeValue("holder")) - ${root.getChild("properties").getChild("copyright").getAttributeValue("holder")} - #elseif($project.getChild("copyright").getAttributeValue("holder")) - ${project.getChild("copyright").getAttributeValue("holder")} - #else - Apache Software Foundation - #end -
    - ##
    - - -
    - - - #makeNavigationBar() - - ## Call the google analyticis code to register this page - - - -#end - - - - - From e858925eceb2fc5a6eb2351750e20910c0248678 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Sep 2011 13:26:16 +0000 Subject: [PATCH 031/370] Add reporting (namely RAT), populate team list in POM, remove contributors list from landing page, address some of the branding requirements. LOG4NET-275 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1166167 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 75 +++++++++++++++++++++++++++--- src/site/site.xml | 8 ++-- src/site/xdoc/index.xml | 100 +++------------------------------------- 3 files changed, 79 insertions(+), 104 deletions(-) diff --git a/pom.xml b/pom.xml index 9a8ebe32..f52ad909 100644 --- a/pom.xml +++ b/pom.xml @@ -136,19 +136,80 @@ Type,Key,Summary,Assignee,Status,Resolution,Fix Version - - - - org.apache.rat - apache-rat-plugin - 0.7 - + + + + + org.apache.rat + apache-rat-plugin + 0.7 + + + + + + + Curt Arnold + carnold + + + Stefan Bodewig + bodewig + + + Nicko Cadell + nicko + + + Niall Daley + niall + + + Gert Driesen + drieseng + + + Ron Grabowski + rgrabowski + + + + + + Julian Biddle + + + Daniel Cazzulino + + + Aspi Havewala + + + Rick Hobbs + + + Lance Nehring + + + Angelika Schnagl + + + Edward Smit + + + Douglas de la Torre + + + Thomas Voss + + + diff --git a/src/site/site.xml b/src/site/site.xml index 4cc4e335..ed550ebd 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -28,14 +28,14 @@ - + + - + - @@ -65,6 +65,8 @@ + + diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml index 7459d258..84afa79a 100644 --- a/src/site/xdoc/index.xml +++ b/src/site/xdoc/index.xml @@ -25,111 +25,23 @@ limitations under the License. -
    +
    -

    - log4net is a tool to help the programmer output log statements to a variety + The Apache log4net™ library is a tool to help the programmer output log statements to a variety of output targets. log4net is a port of the excellent log4j framework to the .NET runtime. We have kept the framework similar in spirit to the original log4j while taking advantage of new features in the .NET runtime. For more information on log4net see the features document.

    +
    +

    - log4net is part of the Apache Logging Services - project. The Logging Services project is intended to provide cross-language logging + log4net is part of the Apache Logging Services + project at the Apache Software Foundation. The Logging Services project is intended to provide cross-language logging services for purposes of application debugging and auditing.

    -
    - -
    - -
    - -
      -
    • -

      - Curt Arnold -

      -
    • -
    • -

      - Nicko Cadell -

      -
    • -
    • -

      - Niall Daley -

      -
    • -
    • -

      - Gert Driesen -

      -
    • -
    • -

      - Ron Grabowski -

      -
    • -
    - -
    - -
    - -
      -
    • -

      - Julian Biddle -

      -
    • -
    • -

      - Daniel Cazzulino -

      -
    • -
    • -

      - Aspi Havewala -

      -
    • -
    • -

      - Rick Hobbs -

      -
    • -
    • -

      - Lance Nehring -

      -
    • -
    • -

      - Angelika Schnagl -

      -
    • -
    • -

      - Edward Smit -

      -
    • -
    • -

      - Douglas de la Torre -

      -
    • -
    • -

      - Thomas Voss -

      -
    • -
    -
    - -
    -
    From d6bf4bf06514de0e8d150bf6732140b3685689e0 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Sep 2011 13:35:17 +0000 Subject: [PATCH 032/370] link to KEYS file on download page. LOG4NET-242 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1166170 13f79535-47bb-0310-9956-ffa450edef68 --- src/site/apt/download.apt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/site/apt/download.apt b/src/site/apt/download.apt index 4c8f7175..bb587dd7 100644 --- a/src/site/apt/download.apt +++ b/src/site/apt/download.apt @@ -41,7 +41,9 @@ Download Apache log4net 1.2.10 *------------------------+---------+----------+-----------+ Please read {{{http://httpd.apache.org/dev/verification.html}Verifying Apache HTTP Server Releases}} - for more information on why you should verify our releases. + for more information on why you should verify our releases. The + PGP keys used to sign our distributions are part of the + {{{http://www.apache.org/dist/logging/KEYS} KEYS file}}. * Previous Releases From 0663c306a98bce6ee753c34a9aebee2831eba8d7 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Sep 2011 13:58:08 +0000 Subject: [PATCH 033/370] fix links in examples page. LOG4NET-243 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1166186 13f79535-47bb-0310-9956-ffa450edef68 --- src/site/resources/js/blockLocalOnlyLinks.js | 39 ++++++++++++++++++++ src/site/xdoc/release/example-apps.xml | 36 ++---------------- 2 files changed, 42 insertions(+), 33 deletions(-) create mode 100644 src/site/resources/js/blockLocalOnlyLinks.js diff --git a/src/site/resources/js/blockLocalOnlyLinks.js b/src/site/resources/js/blockLocalOnlyLinks.js new file mode 100644 index 00000000..21a010a4 --- /dev/null +++ b/src/site/resources/js/blockLocalOnlyLinks.js @@ -0,0 +1,39 @@ +/* + 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. + +*/ +function getElementsByClass(node,searchClass,tag) { + var classElements = new Array(); + var els = node.getElementsByTagName(tag); + var elsLen = els.length; + var pattern = new RegExp("\\b"+searchClass+"\\b"); + for (i = 0, j = 0; i < elsLen; i++) { + if ( pattern.test(els[i].className) ) { + classElements[j] = els[i]; + j++; + } + } + return classElements; +} +function BlockLocalOnlyLinks() { + if (window.location.protocol!="file:") { + var links = getElementsByClass(document, "localOnly", "a"); + for(var i=0; i < links.length; i++) { + links[i].href = "#overview"; + } + } +} +BlockLocalOnlyLinks(); diff --git a/src/site/xdoc/release/example-apps.xml b/src/site/xdoc/release/example-apps.xml index 43ec2aa6..ff0a88de 100644 --- a/src/site/xdoc/release/example-apps.xml +++ b/src/site/xdoc/release/example-apps.xml @@ -24,38 +24,7 @@ limitations under the License. - - - - - +
    @@ -63,7 +32,7 @@ links[i].href = "#overview";

    The following examples are only available in the log4net release download, not - on-line. To obtain the examples download one of the log4net releases. + on-line. To obtain the examples download one of the log4net releases.

    @@ -500,5 +469,6 @@ links[i].href = "#overview";
    + - - - - - - - - - - - - -
    - - - - -

    Contributing to log4net Development

    -
    -

    Contents

    - -

    Developer Mailing List

    -
    -

    - All discussion relating to log4net development takes place on this list. All SVN checkin - notifications are also copied to this list. -

    -

    Mailing List Archives

    -
    -

    - You can browse the mailing list archives at the following locations: -

    - -
    -

    Subscribe

    -
    -

    - Subscribe to either the list or to the digest list: -

    - -
    -

    Unsubscribe

    -
    -

    - To unsubscribe send an email to the relevant email address: -

    - -
    -

    Posting

    -
    -

    - Most of the guidelines for the log4net-user list also apply to the dev list. - Please have a quick read through the guidelines, thanks. -

    -

    - To prevent spam, we require you to be subscribed to the list before posting to it. -

    -

    - This is the log4net developer list, it holds discussions relating to the - development of log4net not the use of log4net. If you have a question that begins - with the word "How" or you are unsure as the the appropriate list to post to then - you probably want to start with the log4net-user list. -

    -

    - Post to the list by sending mail to - log4net-dev@logging.apache.org. -

    -
    -
    -

    Source Access

    -
    -

    - The source for log4net is held in the Apache Subversion source code control repository. -

    -

    Browsing SVN

    -
    -

    - Browse log4net - SVN repository using ViewCVS. -

    -
    -

    Anonymous SVN Access

    -
    -

    - Anyone can checkout source code from our anonymous SVN - server. To do so, simply use the following command (if you are - using a GUI SVN client, configure it appropriately). -

    -

    - Checkout the logging/log4net module. -

    - -
    -svn checkout http://svn.apache.org/repos/asf/logging/log4net/trunk log4net
    - -

    - If you are not familiar with SVN, the Apache - Source Code Repositories - page has links to more information on SVN. -

    -
    -
    -

    Issue Tracking

    -
    -

    - Many bugs reported end up not being a bug in the log4net code, - but are due to incorrect configuration, problems caused by installed applications, - the operating system, etc. -

    -

    - Before reporting a bug please make every effort to investigate and resolve the problem yourself. - Just reporting a bug will not fix it. A good bug report includes a detailed - description of the problem and a succinct test case which can reproduce the problem. -

    -

    - Before reporting an issue please investigate the following information sources for - a potential resolution. -

    - -

    - Before reporting a bug, you are advised to discuss it on the relevant mailing list first. -

    -

    - Search the bug database to see if the bug - you are seeing has already been reported. If it has been reported then you can vote for the issue. -

    -

    Reporting an Issue

    -
    -

    - If after you have exhausted all other resources to resolve a problem you may want to file a bug report. - Please make sure the problem is a bug in Logging and not a bug in your application. -

    -

    - Please make sure you provide as much information as possible. Its very hard to fix a bug if the person - looking into the problem can't reproduce it. Here is a listing of information which should be included: -

    -
      -
    • Version - log4net version, or if from a nightly build, version and date of build.
    • -
    • Application Type - Assembly type, i.e. exe or dll, and how your code is launched, e.g. console application, windows application, ASP.NET project, COM+ hosted object, etc...
    • -
    • Framework - The .NET framework running the application, name (e.g. MS .NET, Mono, SSCLI) and version.
    • -
    • Platform - Computer operating system, version, and hardware platform in use.
    • -
    • Configuration - Attach configuration files if they would help track down the bug.
    • -
    • Log Files - Review your logs files, produced with internal log4net debug enabled. Submit any relevant sections of the log which help document the bug.
    • -
    • Stack Traces - Any stack traces generated by the bug, if any.
    • -
    • Example - Example configuration files or web applications which demonstrate the bug. When submitting an example which reproduces the bug, please try to make it as simple as possible.
    • -
    • Bug Fix Patch - A patch created using diff -u which fixes the bug. (If you have found a bug fix which can be applied to the code).
    • -
    • Description of the Bug - A description of the bug, include observed as well as expected behavior.
    • -
    • Miscellaneous - Any other information you feel will help track down the problem.
    • -
    -

    - Just reporting a bug will not fix it. A good bug report includes a detailed description of the - problem and a succinct test case which can reproduce the problem. The very best sort of report - includes an NUnit testcase which reproduces the issue, this means that we can fix it and that we can - be sure that it stays fixed in future! -

    -

    - Report a log4net issue here. You will need to login to JIRA before you can submit an issue. -

    -
    -
    -

    Contributing Patches

    -
    -

    - Before starting to work on a patch it is probably a good idea to join the log4net-dev - mailing list to check that equivalent or complementary work is not already underway. -

    -

    - Currently the only supported way of submitting patches to log4net - is via the JIRA issue tracking system. -

    -

    - The preferred method of generating a patch is a unified context diff against - the latest development version in SVN. To do this you should do the following: -

    -
      -
    • -

      - Get the latest version of the code from SVN, see the section above on - Anonymous SVN Access for details on how to obtain the SVN version. -

      -
    • -
    • -

      - Make your code changes to the log4net source. Please follow existing - code styles where possible. If adding new API methods or classes then - these should be appropriately documented with code comments. - Contributions intended for inclusion in ASF products must be licensed - to ASF under the terms of the - Apache Software License. -

      -
    • -
    • -

      - Generate a unified context diff for the files you have changed. Run the - svn diff > patch-file command from the root of the log4net - codebase to generate a diff file. -

      -
    • -
    • -

      - If you have added new files these will not be included in the diff. You - will need to attach these files separately. -

      -
    • -
    -

    - If you are not using SVN then you can still generate a unified context diff - using the diff GNU tool with the -u command line options. - The GNU tools are available for Windows as part - of the Cygwin package. -

    -

    - If you are unable to generate a diff please submit each file separately and place - block comments around each code change to highlight the differences. -

    -

    - In order to submit your patch please follow the following steps: -

    -
      -
    • -

      - Create a new issue for your patch. On the - log4net issues home page - select the Create New Issue from the menu bar. You will need to be logged - into JIRA in order to create an issue. -

      -
    • -
    • -

      - Select the issue type as appropriate. -

      -
    • -
    • -

      - Prefix the summary with [PATCH]. Enter a description of the changes made, - new features, or bug fixes in your patch. -

      -
    • -
    • -

      - Once the issue has been created you can attach your patch file to the issue - by selecting the Attach file to this issue operation from the left hand - menu. When attaching your patch you must select the Grant license to ASF for - inclusion in ASF works option. When attaching a patch please include in the - description the baseline version of log4net you used to build your patch, if against - an SVN version please include the version number and if from a tag or branch include - the repository path. -

      -
    • -
    • -

      - If you have other files to attach, e.g. you have added new files to log4net, then - attach each file separately. Please include in the description the name of the file - attached and the path it should live in the project. -

      -
    • -
    -

    - A notification will be sent to the log4net-dev list once you have created your issue, - however it may also be worth mailing the log4net-dev list to encourage the project - committers to apply your patch, or at least find out when they may do so. -

    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/css/site.css b/doc/css/site.css deleted file mode 100644 index 76bcef1e..00000000 --- a/doc/css/site.css +++ /dev/null @@ -1,161 +0,0 @@ -/* - * - * 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. - * -*/ - - -H1, H2, H3 { - color: #101099; -} - -A:link, A:visited { - text-decoration: none; - color: #006699; -} - -A:link:hover { - text-decoration: underline; -} - -.centercol { - margin-top: 120px; - margin-left: 210px; - margin-right:210px; - max-width: 800px; -} - -.leftcol { - position: absolute; - left: 10px; - top: 130px; - width: 190px; -} - -.banner { - position: absolute; - left: 10px; - top: 10px; - height: 130px; - width: 1000px; -} - -.menu_header, .menu_item { -/* width: 190px; */ - font-family: "trebuchet MS", Arial, Helvetica, sans-serif; - font-size: smaller; -} - -.menu_header { - border:1px solid #AAAAAA; - background: #CCCCCC; - padding-left: 1ex; -} - -.menu_item:hover { - background: #DDD; -} - -.menu_item { - background: #EEEEEE; - padding-left: 2ex; - border-top: 0px solid #AAAAAA; - border-right: 1px solid #AAAAAA; - border-bottom:1px solid #AAAAAA; - border-left: 1px solid #AAAAAA; -} - -.source { - border-top: 1px solid #DDDDDD; - border-bottom: 1px solid #DDDDDD; - background:#eee; - font-family: Courier, "MS Courier New", Prestige, Everson Monocourrier, monospace; - font-size: smaller; - padding-bottom: 0.5ex; - padding-top: 0.5ex; - padding-left: 2ex; -} - -table.ls { - background: #FFFFFF; -} -table.ls td { - background: #f4f4f4; - vertical-align: top; - padding-bottom: 1ex; -} - -table.ls th { - background: #E4E4E4; -} - -.index-faqSection { - font-size: larger; - padding-left: 0em; - font-weight: bolder; -} -.index-question { - padding-left: 1em; -} - -.faqSection { - font-size: larger; - font-weight: bolder; -} - -.question { - font-weight: bolder; -} - -/* this class is used for screen output placed in
     tags */
    -.screen_output {
    -  padding-left:  1em;
    -  padding-right: 1em;
    -  border-top:   1px solid #AAAAAA;
    -  border-right: 1px solid #AAAAAA;
    -  border-bottom:1px solid #AAAAAA;
    -  border-left:  1px solid #AAAAAA;
    -}
    -
    -
    -.big {
    -  font-size: larger;
    -  font-weight: bold;
    -}
    -
    -.small {
    -  font-size: smaller;
    -}
    -
    -.red {
    -  color: #AA0000;
    -}
    -
    -.msg_title {
    -  padding-left:  1ex;
    -  padding-right: 1ex;
    -  font-family: Courier, "MS Courier New", Prestige, Everson Monocourrier, monospace;
    -  border:   1px solid #AAAAAA;
    -  background: #DDDDFF;
    -
    -}
    -
    -.msg_meaning {
    -  padding-left:  1em;
    -  padding-right: 1em;
    -}
    diff --git a/doc/css/style.css b/doc/css/style.css
    deleted file mode 100644
    index 28fc7d6d..00000000
    --- a/doc/css/style.css
    +++ /dev/null
    @@ -1,265 +0,0 @@
    -/*
    - *
    - * 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.
    - *
    -*/
    -
    -body
    -{
    -	margin: 0px 0px 0px 0px;
    -	padding: 0px 0px 0px 0px;
    -	background: white;
    -	color: black;
    -	font-family: Verdana, Arial, Helvetica, sans-serif;
    -	font-size: 70%;
    -	width: 100%;
    -}
    -
    -h1, h2, h3, h4, h5
    -{
    -	margin-bottom: .8em;
    -	margin-top: 1em;
    -}
    -
    -h1
    -{
    -	/*font-size: 120%;*/
    -	font-size: 20px;
    -	margin-top: 0em;
    -}
    -
    -h2
    -{
    -	/*font-size: 115%;*/
    -	font-size: 15px;
    -}
    -
    -h3
    -{
    -	/*font-size: 105%;*/
    -	font-size: 13px;
    -}
    -
    -h4
    -{
    -	/*font-size: 95%;*/
    -	font-size: 11px;
    -}
    -
    -h5
    -{
    -	/*font-size: 85%;*/
    -	font-size: 9px;
    -}
    -
    -
    -div.table
    -{
    -	text-align: center;
    -}
    -
    -.table table
    -{
    -	font-size: 100%;
    -	border-collapse: collapse;
    -	width: 90%;
    -}
    -
    -.table th
    -{
    -	background-color: #cccccc;
    -	color: black;
    -	font-weight: bolder;
    -	padding: 5px;
    -	border: 1px solid #999999;
    -}
    -
    -.table tr
    -{
    -	background-color: inherit;
    -	color: black;
    -	padding: 5px;
    -	text-align: left;
    -	border: 1px solid #999999;
    -}
    -
    -.table td
    -{
    -	border: 1px solid #999999;
    -	padding: 5px;
    -}
    -
    -p
    -{
    -	margin: .5em 0em .5em 0em;
    -}
    -
    -pre
    -{
    -	margin-top: .5em;
    -	margin-bottom: .5em;
    -	font-size: 11px;
    -}
    -
    -pre.code
    -{
    -	font-family: Monospace, Courier New, Courier;
    -	background-color: inherit;
    -	color: black;
    -	font-size: 100%;
    -	margin-left: 20px;
    -}
    -
    -span.code
    -{
    -	font-family: Monospace, Courier New, Courier;
    -	background-color: inherit;
    -	/* color: #0000EE; */
    -	color: #101080;
    -	font-size: 100%;
    -}
    -
    -.syntax
    -{
    -	font-family: Monospace, Courier New, Courier;
    -	letter-spacing: .1em;
    -	background-color: #f5f5ff;
    -	color: white;
    -	font-size: 100%;
    -	font-weight: inherit;
    -	padding: 5px;
    -	border: 1px solid #999999;
    -	margin-left: 20px;
    -	padding: 4px 8px;
    -	margin-top: 1em;
    -	margin-bottom: 1em;
    -	width: 95%;
    -}
    -
    -.rule dt 
    -{
    -	font-weight: bolder;
    -}
    -
    -.rule
    -{
    -	background-color: #f5f5f5;
    -	color: black;
    -	font-size: 100%;
    -	padding: 5px;
    -	border: 1px solid #999999;
    -	margin-left: 30px;
    -	padding: 4px 8px;
    -	margin-top: 1em;
    -	margin-bottom: 1em;
    -	width: 90%;
    -}
    -
    -
    -.i1
    -{
    -	margin-left: 20px;
    -}
    -
    -.i2
    -{
    -	margin-left: 40px;
    -}
    -
    -.i3
    -{
    -	margin-left: 60px;
    -}
    -
    -
    -div#header
    -{
    -	width: 100%;
    -	margin: 0px 0px 0px 0px;
    -	border-width: 0px;
    -	border-bottom: 1px solid #999999;
    -	padding: 0px 0px 0px 0px;
    -	background-color: #99ccff;
    -	color: black;
    -}
    -
    -div#header h1
    -{
    -	margin: 0px 0px 0px 0px;
    -	border-width: 0px;
    -	padding: 0 .4em .3em .4em;
    -	background-color: #99ccff;
    -	color: black;
    -}
    -
    -div#footer
    -{
    -	font-size: 100%;
    -	font-style:italic;
    -	border-top: 1px solid #999999;
    -	margin-left: 20px;
    -	margin-top: 1em;
    -	margin-bottom: 1em;
    -	width: 96%;
    -}
    -
    -div#content
    -{
    -	margin: 0px 0px 0px 0px;
    -	padding: 4px 4px 4px 4px;
    -}
    -
    -a:link
    -{
    -	color: #0000ff;
    -	background-color: inherit;
    -}
    -
    -a:visited
    -{
    -	color: #0000ff;
    -	background-color: inherit;
    -}
    -
    -a:hover
    -{
    -	color: #3366ff;
    -	background-color: inherit;
    -}
    -
    -
    -/* Override site.css */
    -
    -.centercol {
    -	margin-left: 190px;
    -	margin-right:20px;
    -	max-width: 100%;
    -}
    -
    -.leftcol {
    -	width: 160px;
    -}
    -
    -.menu_header, .menu_item {
    -	font-size: inherit;
    -}
    -
    -.menu_item:hover {
    -  background: #EEEEEE; 
    -}
    -
    diff --git a/doc/downloads.html b/doc/downloads.html
    deleted file mode 100644
    index be1d11be..00000000
    --- a/doc/downloads.html
    +++ /dev/null
    @@ -1,222 +0,0 @@
    -
    -
    -
    -
    -
    -    
    -    
    -
    -        
    -
    -    
    -    
    -    
    -    
    -    
    -        
    -            
    -
    -                                                    
    -            
    -            
    -           
    -                                     
    - 
    -                        
    -            
    -            
    -                            
    -            
    -            Apache log4net: Downloads
    -            
    -                    
    -
    -        
    -                    
    -          
    -
    -            
    -                             
    -     
    -       
    -       
    -     
    -   
    -               
    -
    -
    -       
    - - - - -

    log4net Downloads

    -
    -

    Project Status

    -
    -

    - log4net has graduated from the Incubator project, however at the time - the following releases were made, log4net was still undergoing incubation, - therefore these releases are not officially endorsed by the ASF. -

    -

    - Future releases of log4net will be officially endorsed by the ASF. -

    -
    -

    Stable Releases

    -
    -

    - The following stable releases are available: -

    - -
    -

    Archive Releases

    -
    - -

    - Previous releases of log4net are available from the sourceforge site: -

    - -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/history.html b/doc/history.html deleted file mode 100644 index c57bd0f2..00000000 --- a/doc/history.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Project History - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Project History

    -
    -

    - The log4net project was started by Neoworks Limited - in June 2001. It was created as an internal project within Neoworks to port the Apache - log4j code base to the Microsoft .NET Framework. The code base was initially branched - from a pre-alpha log4j 1.2. -

    -

    - In July 2001 a Sourceforge project was started - and log4net was published under the Apache Software License. The first public release of - log4net was made in September 2001. A further 10 releases were made on the sourceforge - site. -

    -

    - In December 2003 the Apache Logging Services project was created. - In February 2004 log4net was donated by Neoworks to the Apache Software Foundation - to become a member of the Logging Services project. -

    -

    - In February 2007 log4net graduated from the Apache Incubator project to become a - fully fledged Apache project. Apache log4net is a subproject of the Logging Services project. -

    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index 390e60ec..00000000 --- a/doc/index.html +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Home - - - - - - - - - - - - - - - - - -
    - - - - -

    About Apache log4net

    -
    -

    Introduction

    -
    -

    - log4net is a tool to help the programmer output log statements to a variety - of output targets. log4net is a port of the excellent log4j framework to the - .NET runtime. We have kept the framework similar in spirit to the original log4j - while taking advantage of new features in the .NET runtime. - For more information on log4net see the features document. -

    -

    - log4net is part of the Apache Logging Services - project. The Logging Services project is intended to provide cross-language logging - services for purposes of application debugging and auditing. -

    -
    -

    Contributors

    -
    -

    Active Committers

    -
    -
      -
    • -

      - Curt Arnold -

      -
    • -
    • -

      - Nicko Cadell -

      -
    • -
    • -

      - Niall Daley -

      -
    • -
    • -

      - Gert Driesen -

      -
    • -
    • -

      - Ron Grabowski -

      -
    • -
    -
    -

    Community Contributors

    -
    -
      -
    • -

      - Julian Biddle -

      -
    • -
    • -

      - Daniel Cazzulino -

      -
    • -
    • -

      - Aspi Havewala -

      -
    • -
    • -

      - Rick Hobbs -

      -
    • -
    • -

      - Lance Nehring -

      -
    • -
    • -

      - Angelika Schnagl -

      -
    • -
    • -

      - Edward Smit -

      -
    • -
    • -

      - Douglas de la Torre -

      -
    • -
    • -

      - Thomas Voss -

      -
    • -
    -
    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/license.html b/doc/license.html deleted file mode 100644 index c738cde8..00000000 --- a/doc/license.html +++ /dev/null @@ -1,416 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: License - - - - - - - - - - - - - - - - - -
    - - - - -

    Apache log4net License

    -
    -

    Current License

    -
    -

    - The Apache Software License Version 2.0 applies to all releases of - log4net starting with log4net 1.2.1. -

    - -
    -                                 Apache License
    -                           Version 2.0, January 2004
    -                        http://www.apache.org/licenses/
    -
    -   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    -
    -   1. Definitions.
    -
    -      "License" shall mean the terms and conditions for use, reproduction,
    -      and distribution as defined by Sections 1 through 9 of this document.
    -
    -      "Licensor" shall mean the copyright owner or entity authorized by
    -      the copyright owner that is granting the License.
    -
    -      "Legal Entity" shall mean the union of the acting entity and all
    -      other entities that control, are controlled by, or are under common
    -      control with that entity. For the purposes of this definition,
    -      "control" means (i) the power, direct or indirect, to cause the
    -      direction or management of such entity, whether by contract or
    -      otherwise, or (ii) ownership of fifty percent (50%) or more of the
    -      outstanding shares, or (iii) beneficial ownership of such entity.
    -
    -      "You" (or "Your") shall mean an individual or Legal Entity
    -      exercising permissions granted by this License.
    -
    -      "Source" form shall mean the preferred form for making modifications,
    -      including but not limited to software source code, documentation
    -      source, and configuration files.
    -
    -      "Object" form shall mean any form resulting from mechanical
    -      transformation or translation of a Source form, including but
    -      not limited to compiled object code, generated documentation,
    -      and conversions to other media types.
    -
    -      "Work" shall mean the work of authorship, whether in Source or
    -      Object form, made available under the License, as indicated by a
    -      copyright notice that is included in or attached to the work
    -      (an example is provided in the Appendix below).
    -
    -      "Derivative Works" shall mean any work, whether in Source or Object
    -      form, that is based on (or derived from) the Work and for which the
    -      editorial revisions, annotations, elaborations, or other modifications
    -      represent, as a whole, an original work of authorship. For the purposes
    -      of this License, Derivative Works shall not include works that remain
    -      separable from, or merely link (or bind by name) to the interfaces of,
    -      the Work and Derivative Works thereof.
    -
    -      "Contribution" shall mean any work of authorship, including
    -      the original version of the Work and any modifications or additions
    -      to that Work or Derivative Works thereof, that is intentionally
    -      submitted to Licensor for inclusion in the Work by the copyright owner
    -      or by an individual or Legal Entity authorized to submit on behalf of
    -      the copyright owner. For the purposes of this definition, "submitted"
    -      means any form of electronic, verbal, or written communication sent
    -      to the Licensor or its representatives, including but not limited to
    -      communication on electronic mailing lists, source code control systems,
    -      and issue tracking systems that are managed by, or on behalf of, the
    -      Licensor for the purpose of discussing and improving the Work, but
    -      excluding communication that is conspicuously marked or otherwise
    -      designated in writing by the copyright owner as "Not a Contribution."
    -
    -      "Contributor" shall mean Licensor and any individual or Legal Entity
    -      on behalf of whom a Contribution has been received by Licensor and
    -      subsequently incorporated within the Work.
    -
    -   2. Grant of Copyright License. Subject to the terms and conditions of
    -      this License, each Contributor hereby grants to You a perpetual,
    -      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    -      copyright license to reproduce, prepare Derivative Works of,
    -      publicly display, publicly perform, sublicense, and distribute the
    -      Work and such Derivative Works in Source or Object form.
    -
    -   3. Grant of Patent License. Subject to the terms and conditions of
    -      this License, each Contributor hereby grants to You a perpetual,
    -      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    -      (except as stated in this section) patent license to make, have made,
    -      use, offer to sell, sell, import, and otherwise transfer the Work,
    -      where such license applies only to those patent claims licensable
    -      by such Contributor that are necessarily infringed by their
    -      Contribution(s) alone or by combination of their Contribution(s)
    -      with the Work to which such Contribution(s) was submitted. If You
    -      institute patent litigation against any entity (including a
    -      cross-claim or counterclaim in a lawsuit) alleging that the Work
    -      or a Contribution incorporated within the Work constitutes direct
    -      or contributory patent infringement, then any patent licenses
    -      granted to You under this License for that Work shall terminate
    -      as of the date such litigation is filed.
    -
    -   4. Redistribution. You may reproduce and distribute copies of the
    -      Work or Derivative Works thereof in any medium, with or without
    -      modifications, and in Source or Object form, provided that You
    -      meet the following conditions:
    -
    -      (a) You must give any other recipients of the Work or
    -          Derivative Works a copy of this License; and
    -
    -      (b) You must cause any modified files to carry prominent notices
    -          stating that You changed the files; and
    -
    -      (c) You must retain, in the Source form of any Derivative Works
    -          that You distribute, all copyright, patent, trademark, and
    -          attribution notices from the Source form of the Work,
    -          excluding those notices that do not pertain to any part of
    -          the Derivative Works; and
    -
    -      (d) If the Work includes a "NOTICE" text file as part of its
    -          distribution, then any Derivative Works that You distribute must
    -          include a readable copy of the attribution notices contained
    -          within such NOTICE file, excluding those notices that do not
    -          pertain to any part of the Derivative Works, in at least one
    -          of the following places: within a NOTICE text file distributed
    -          as part of the Derivative Works; within the Source form or
    -          documentation, if provided along with the Derivative Works; or,
    -          within a display generated by the Derivative Works, if and
    -          wherever such third-party notices normally appear. The contents
    -          of the NOTICE file are for informational purposes only and
    -          do not modify the License. You may add Your own attribution
    -          notices within Derivative Works that You distribute, alongside
    -          or as an addendum to the NOTICE text from the Work, provided
    -          that such additional attribution notices cannot be construed
    -          as modifying the License.
    -
    -      You may add Your own copyright statement to Your modifications and
    -      may provide additional or different license terms and conditions
    -      for use, reproduction, or distribution of Your modifications, or
    -      for any such Derivative Works as a whole, provided Your use,
    -      reproduction, and distribution of the Work otherwise complies with
    -      the conditions stated in this License.
    -
    -   5. Submission of Contributions. Unless You explicitly state otherwise,
    -      any Contribution intentionally submitted for inclusion in the Work
    -      by You to the Licensor shall be under the terms and conditions of
    -      this License, without any additional terms or conditions.
    -      Notwithstanding the above, nothing herein shall supersede or modify
    -      the terms of any separate license agreement you may have executed
    -      with Licensor regarding such Contributions.
    -
    -   6. Trademarks. This License does not grant permission to use the trade
    -      names, trademarks, service marks, or product names of the Licensor,
    -      except as required for reasonable and customary use in describing the
    -      origin of the Work and reproducing the content of the NOTICE file.
    -
    -   7. Disclaimer of Warranty. Unless required by applicable law or
    -      agreed to in writing, Licensor provides the Work (and each
    -      Contributor provides its Contributions) on an "AS IS" BASIS,
    -      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    -      implied, including, without limitation, any warranties or conditions
    -      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
    -      PARTICULAR PURPOSE. You are solely responsible for determining the
    -      appropriateness of using or redistributing the Work and assume any
    -      risks associated with Your exercise of permissions under this License.
    -
    -   8. Limitation of Liability. In no event and under no legal theory,
    -      whether in tort (including negligence), contract, or otherwise,
    -      unless required by applicable law (such as deliberate and grossly
    -      negligent acts) or agreed to in writing, shall any Contributor be
    -      liable to You for damages, including any direct, indirect, special,
    -      incidental, or consequential damages of any character arising as a
    -      result of this License or out of the use or inability to use the
    -      Work (including but not limited to damages for loss of goodwill,
    -      work stoppage, computer failure or malfunction, or any and all
    -      other commercial damages or losses), even if such Contributor
    -      has been advised of the possibility of such damages.
    -
    -   9. Accepting Warranty or Additional Liability. While redistributing
    -      the Work or Derivative Works thereof, You may choose to offer,
    -      and charge a fee for, acceptance of support, warranty, indemnity,
    -      or other liability obligations and/or rights consistent with this
    -      License. However, in accepting such obligations, You may act only
    -      on Your own behalf and on Your sole responsibility, not on behalf
    -      of any other Contributor, and only if You agree to indemnify,
    -      defend, and hold each Contributor harmless for any liability
    -      incurred by, or claims asserted against, such Contributor by reason
    -      of your accepting any such warranty or additional liability.
    -
    -   END OF TERMS AND CONDITIONS
    -
    -   APPENDIX: How to apply the Apache License to your work.
    -
    -      To apply the Apache License to your work, attach the following
    -      boilerplate notice, with the fields enclosed by brackets "[]"
    -      replaced with your own identifying information. (Don't include
    -      the brackets!)  The text should be enclosed in the appropriate
    -      comment syntax for the file format. We also recommend that a
    -      file or class name and description of purpose be included on the
    -      same "printed page" as the copyright notice for easier
    -      identification within third-party archives.
    -
    -   Copyright [yyyy] [name of copyright owner]
    -
    -   Licensed 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.
    -
    -                
    - -

    - The License is accompanied by this NOTICE: -

    - -
    -   **
    -   **  NOTICE file corresponding to the section 4 (d) of the Apache License, 
    -   **  Version 2.0, in this case for the Apache log4net distribution.
    -   **
    -
    -   Please read the LICENSE files present in the root directory of this 
    -   distribution.
    -
    -   Apache log4net
    -   Copyright 2001-2007 The Apache Software Foundation
    -
    -   This product includes software developed at
    -   The Apache Software Foundation (http://www.apache.org/).
    -
    -                
    - -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/building.html b/doc/release/building.html deleted file mode 100644 index b58d413f..00000000 --- a/doc/release/building.html +++ /dev/null @@ -1,360 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Building log4net - - - - - - - - - - - - - - - - - -
    - - - - -

    Building log4net

    -
    -

    Contents

    - -

    - The log4net release builds are built using NAnt. Log4net can also be built - using Visual Studio .NET 2002, 2003, or 2005. -

    -

    - To build a release build of log4net you will need to create a strong - name key file. See the Strong Name section below. -

    -

    Visual Studio

    -
    -

    - Visual Studio .NET 2002, 2003 and 2005 are supported build platforms for log4net. -

    -

    Visual Studio .NET 2002

    -
    -

    - The log4net distribution includes a solution and project file - for Visual Studio .NET 2002. Open the log4net.sln - from the src directory in the distribution. -

    -

    - The log4net project requires only the following references: -

    -
      -
    • System
    • -
    • System.Data
    • -
    • System.Web
    • -
    • System.XML
    • -
    -
    -

    Visual Studio .NET 2003

    -
    -

    - Open the Visual Studio .NET 2002 solution file as above. - Visual Studio will convert the solution and project files - to Visual Studio .NET 2003 format. -

    -

    - After converting the log4net project you must change the - Conditional Compilation Constants specified for the - log4net project. Open the project properties dialog and - select the Configuration Properties/Build sheet. - Replace the NET_1_0 constant with NET_1_1. - Remember to do this for both Debug and Release configurations. -

    -

    - The log4net project file is not suitable for building log4net - for the .NET Compact Framework. To build for the Compact Framework - you must create a new C# project for Smart Devices. Configure the - project as a library project. Add all the C# files from the - src directory in the distribution. -

    -
    -

    Visual Studio 2005

    -
    -

    - Open the Visual Studio .NET 2002 solution file as above. - Visual Studio will convert the solution and project files - to Visual Studio .NET 2003 format. -

    -

    - After converting the log4net project you must change the - Conditional compilation symbols specified for the - log4net project. Open the project properties page and - select the Build sheet. - Replace the NET_1_0 symbol with NET_2_0. - Remember to do this for both Debug and Release configurations. -

    -

    - In addition the log4net project requires the following new references: -

    -
      -
    • System.Configuration
    • -
    -

    - The log4net project file is not suitable for building log4net - for the .NET Compact Framework. To build for the Compact Framework - you must create a new C# project for Smart Devices. Configure the - project as a library project. Add all the C# files from the - src directory in the distribution. -

    -
    -
    -

    NAnt

    -
    -

    - The log4net distribution is built using the NAnt tool. - A recent NAnt version 0.85 nightly build is required to build log4net, this is - available from nant.sourceforge.net. -

    -

    - To support building log4net for the SSCLI framework the NAnt configuration - files need to be updated to specify the SSCLI framework directory. -

    -

    - To build log4net from the command line, change directory to the root of the - log4net distribution, ensure that the nant executable is in the - PATH, and then run the following command: -

    -
    -nant -buildfile:log4net.build compile-all
    -

    - This command will build log4net for all the supported frameworks - that are available on the current machine. To list all the build - targets that are available run the following command: -

    -
    -nant -buildfile:log4net.build -projecthelp
    -

    - Under windows the build.cmd can be used - to script the nant build. This can be called from a different - directory and will locate the correct log4net.build file to use. - For example: -

    -
    -build.cmd compile-all
    -
    -

    Strong Name

    -
    -

    - In order to build the Release builds of log4net a Strong - Name key is required. -

    -

    - Use the sn.exe tool in the - .NET Framework SDK to generate a strong name key pair. -

    -
    -sn -k log4net.snk
    -

    - The log4net.snk file should be placed in the root of the - log4net distribution, in the same folder as the log4net.build - file. -

    -
    -

    SDK Reference

    -
    -

    - NDoc 1.3 is used to build the log4net SDK documentation. - NDoc is available from ndoc.sourceforge.net. -

    -
    -

    HTML Documentation

    -
    -

    - The log4net HTML documentation is built using Velocity. - The source are XML files in the xdocs/src directory. - Building the documentation requires Java, Ant, and Velocity. - Run ant from within the xdocs directory. -

    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/config-examples.html b/doc/release/config-examples.html deleted file mode 100644 index e4980eb9..00000000 --- a/doc/release/config-examples.html +++ /dev/null @@ -1,1320 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Config Examples - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Config Examples

    -
    -

    Contents

    - -

    Overview

    -
    -

    - This document presents example configurations for the built-in appenders. - These configurations are designed to work with the - log4net.Config.DOMConfigurator and the - log4net.Repository.Hierarchy.Hierarchy. -

    -

    - These examples are by no means exhaustive configurations for the appenders. - For a full list of the parameters that can be specified to each appender and - more details on each options see the SDK documentation for the appender. -

    -
    -

    AdoNetAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.AdoNetAppender. -

    -

    - The configuration of the AdoNetAppender depends on the - provider selected for the target database. Here are some examples. -

    -

    MS SQL Server

    -
    -

    - The following example shows how to configure the AdoNetAppender - to log messages to a SQL Server database. The events are written in batches of 100 - (BufferSize). The ConnectionType specifies the fully qualified type name - for the System.Data.IDbConnection to use to connect to the - database. The ConnectionString is database provider specific. - The CommandText is either a prepared statement or a stored procedure, in this - case it is a prepared statement. Each parameter to the prepared statement or stored procedure - is specified with its name, database type and a layout that renders the value for the - parameter. -

    -

    - The database table definition is: -

    - -
    -CREATE TABLE [dbo].[Log] (
    -    [Id] [int] IDENTITY (1, 1) NOT NULL,
    -    [Date] [datetime] NOT NULL,
    -    [Thread] [varchar] (255) NOT NULL,
    -    [Level] [varchar] (50) NOT NULL,
    -    [Logger] [varchar] (255) NOT NULL,
    -    [Message] [varchar] (4000) NOT NULL,
    -    [Exception] [varchar] (2000) NULL
    -)
    -                    
    - -

    - The appender configuration is: -

    - -
    -<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
    -    <bufferSize value="100" />
    -    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    -    <connectionString value="data source=[database server];initial catalog=[database name];integrated security=false;persist security info=True;User ID=[user];Password=[password]" />
    -    <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
    -    <parameter>
    -        <parameterName value="@log_date" />
    -        <dbType value="DateTime" />
    -        <layout type="log4net.Layout.RawTimeStampLayout" />
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@thread" />
    -        <dbType value="String" />
    -        <size value="255" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%thread" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@log_level" />
    -        <dbType value="String" />
    -        <size value="50" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%level" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@logger" />
    -        <dbType value="String" />
    -        <size value="255" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%logger" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@message" />
    -        <dbType value="String" />
    -        <size value="4000" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%message" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@exception" />
    -        <dbType value="String" />
    -        <size value="2000" />
    -        <layout type="log4net.Layout.ExceptionLayout" />
    -    </parameter>
    -</appender>
    -                    
    - -
    -

    MS Access

    -
    -

    - This example shows how to write events to an Access Database. -

    - -
    -<appender name="AdoNetAppender_Access" type="log4net.Appender.AdoNetAppender">
    -    <connectionString value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\log\access.mdb;User Id=;Password=;" />
    -    <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />
    -    <parameter>
    -        <parameterName value="@log_date" />
    -        <dbType value="String" />
    -        <size value="255" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%date" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@thread" />
    -        <dbType value="String" />
    -        <size value="255" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%thread" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@log_level" />
    -        <dbType value="String" />
    -        <size value="50" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%level" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@logger" />
    -        <dbType value="String" />
    -        <size value="255" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%logger" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@message" />
    -        <dbType value="String" />
    -        <size value="1024" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%message" />
    -        </layout>
    -    </parameter>
    -</appender>
    -                    
    - -
    -

    Oracle9i

    -
    -

    - This example shows how to write events to an Oracle9i Database. -

    -

    - The database table definition is: -

    - -
    -create table log (
    -   Datetime timestamp(3),
    -   Thread varchar2(255),
    -   Log_Level varchar2(255),
    -   Logger varchar2(255),
    -   Message varchar2(4000)
    -   );
    -                    
    - -

    - The appender configuration is: -

    - -
    -<appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNetAppender">
    -    <connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    -    <connectionString value="data source=[mydatabase];User ID=[user];Password=[password]" />
    -    <commandText value="INSERT INTO Log (Datetime,Thread,Log_Level,Logger,Message) VALUES (:log_date, :thread, :log_level, :logger, :message)" />
    -    <bufferSize value="128" />
    -    <parameter>
    -        <parameterName value=":log_date" />
    -        <dbType value="DateTime" />
    -        <layout type="log4net.Layout.RawTimeStampLayout" />
    -    </parameter>
    -    <parameter>
    -        <parameterName value=":thread" />
    -        <dbType value="String" />
    -        <size value="255" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%thread" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value=":log_level" />
    -        <dbType value="String" />
    -        <size value="50" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%level" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value=":logger" />
    -        <dbType value="String" />
    -        <size value="255" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%logger" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value=":message" />
    -        <dbType value="String" />
    -        <size value="4000" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%message" />
    -        </layout>
    -    </parameter>
    -</appender>
    -                    
    - -
    -

    Oracle8i

    -
    -

    - This example shows how to write events to an Oracle8i Database. -

    -

    - The database table definition is: -

    - -
    -CREATE TABLE CSAX30.LOG
    -(
    -      THREAD      VARCHAR2(255),
    -      LOG_LEVEL   VARCHAR2(255),
    -      LOGGER      VARCHAR2(255),
    -      MESSAGE     VARCHAR2(4000)
    -)
    -TABLESPACE CSAX30D LOGGING
    -                    
    - -

    - The appender configuration is: -

    - -
    -<appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNetAppender">
    -    <connectionType value ="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    -    <connectionString value="data source=<dsname>;User ID=<userid>;Password=<password>" />
    -    <commandText value="INSERT INTO Log (Log_Level,Logger,Message) VALUES (:log_level, :logger, :message)" />
    -    <bufferSize value="250" />
    -    <parameter>
    -        <parameterName value=":log_level" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%level" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value=":logger" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%logger" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value=":message" />
    -        <dbType value="String" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%message" />
    -        </layout>
    -    </parameter>
    -</appender>
    -                    
    - -
    -

    IBM DB2

    -
    -

    - This example shows how to write events to an IBM DB2 8.2 Database. - The following syntax should also work with older DB2 database servers. -

    -

    - The database table definition is: -

    - -
    -CREATE TABLE "myschema.LOG" (
    -    "ID" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (
    -        START WITH +1
    -        INCREMENT BY +1
    -        MINVALUE +1
    -        MAXVALUE +2147483647
    -        NO CYCLE
    -        NO CACHE
    -        NO ORDER
    -    ),
    -    "DATE" TIMESTAMP NOT NULL,
    -    "THREAD" VARCHAR(255) NOT NULL,
    -    "LEVEL" VARCHAR(500) NOT NULL,
    -    "LOGGER" VARCHAR(255) NOT NULL,
    -    "MESSAGE" VARCHAR(4000) NOT NULL,
    -    "EXCEPTION" VARCHAR(2000)
    -)
    -IN "LRGTABLES";
    -                    
    - -

    - The appender configuration is: -

    - -
    -<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
    -    <bufferSize value="100" />
    -    <connectionType value="IBM.Data.DB2.DB2Connection,IBM.Data.DB2, Version=8.1.2.1" />
    -    <connectionString value="server=192.168.0.0;database=dbuser;user Id=username;password=password;persist security info=true" />
    -    <commandText value="INSERT INTO myschema.Log (Date,Thread,Level,Logger,Message,Exception) VALUES (@log_date,@thread,@log_level,@logger,@message,@exception)" />
    -    <parameter>
    -        <parameterName value="@log_date" />
    -        <dbType value="DateTime" />
    -        <layout type="log4net.Layout.RawTimeStampLayout" />
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@thread" />
    -        <dbType value="String" />
    -        <size value="255" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%thread" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@log_level" />
    -        <dbType value="String" />
    -        <size value="500" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%level" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@logger" />
    -        <dbType value="String" />
    -        <size value="255" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%logger" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@message" />
    -        <dbType value="String" />
    -        <size value="4000" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%message" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@exception" />
    -        <dbType value="String" />
    -        <size value="2000" />
    -        <layout type="log4net.Layout.ExceptionLayout" />
    -    </parameter>
    -</appender>
    -                    
    - -
    -

    SQLite

    -
    -

    - This example shows how to write events to a SQLite Database. - This was tested against v0.21 of the - SQLite .NET provider. -

    -

    - SQLite doesn't have strongly-typed columns or field lengths but its - recommended you still include this information for readability. - The database table definition is: -

    - -
    -CREATE TABLE Log (
    -    LogId        INTEGER PRIMARY KEY,
    -    Date        DATETIME NOT NULL,
    -    Level        VARCHAR(50) NOT NULL,
    -    Logger        VARCHAR(255) NOT NULL,
    -    Message        TEXT DEFAULT NULL
    -);
    -                    
    - -

    - The appender configuration is: -

    - -
    -<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
    -    <bufferSize value="100" />
    -    <connectionType value="Finisar.SQLite.SQLiteConnection, SQLite.NET, Version=0.21.1869.3794, Culture=neutral, PublicKeyToken=c273bd375e695f9c" />
    -    <connectionString value="Data Source=c:\\inetpub\\wwwroot\\logs\\log4net.db;Version=3;" />
    -    <commandText value="INSERT INTO Log (Date, Level, Logger, Message) VALUES (@Date, @Level, @Logger, @Message)" />
    -    <parameter>
    -        <parameterName value="@Date" />
    -        <dbType value="DateTime" />
    -        <layout type="log4net.Layout.RawTimeStampLayout" />
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@Level" />
    -        <dbType value="String" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%level" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@Logger" />
    -        <dbType value="String" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%logger" />
    -        </layout>
    -    </parameter>
    -    <parameter>
    -        <parameterName value="@Message" />
    -        <dbType value="String" />
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%message" />
    -        </layout>
    -    </parameter>
    -</appender>
    -                    
    - -
    -
    -

    AspNetTraceAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.AspNetTraceAppender. -

    -

    - The following example shows how to configure the AspNetTraceAppender - to log messages to the ASP.NET TraceContext. The messages are written to the - System.Web.TraceContext.Write method if they are below - level WARN. If they are WARN or above they are written to the - System.Web.TraceContext.Warn method. -

    - -
    -<appender name="AspNetTraceAppender" type="log4net.Appender.AspNetTraceAppender" >
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    BufferingForwardingAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.BufferingForwardingAppender. -

    -

    - The following example shows how to configure the BufferingForwardingAppender - to buffer 100 messages before delivering them to the ConsoleAppender. -

    - -
    -<appender name="BufferingForwardingAppender" type="log4net.Appender.BufferingForwardingAppender" >
    -    <bufferSize value="100"/>
    -    <appender-ref ref="ConsoleAppender" />
    -</appender>
    -                
    - -

    - This example shows how to deliver only significant events. A LevelEvaluator - is specified with a threshold of WARN. This means that the events will only - be delivered when a message with level of WARN or higher level is logged. - Up to 512 (BufferSize) previous messages of any level will also be delivered to provide context - information. Messages not sent will be discarded. -

    - -
    -<appender name="BufferingForwardingAppender" type="log4net.Appender.BufferingForwardingAppender" >
    -    <bufferSize value="512" />
    -    <lossy value="true" />
    -    <evaluator type="log4net.Core.LevelEvaluator">
    -        <threshold value="WARN"/>
    -    </evaluator>
    -    <appender-ref ref="ConsoleAppender" />
    -</appender>
    -                
    - -
    -

    ColoredConsoleAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.ColoredConsoleAppender. -

    -

    - The following example shows how to configure the ColoredConsoleAppender - to log messages to the console. By default the messages are sent to the console - standard output stream. This example shows how to highlight error messages. -

    - -
    -<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
    -    <mapping>
    -        <level value="ERROR" />
    -        <foreColor value="White" />
    -        <backColor value="Red, HighIntensity" />
    -    </mapping>
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example shows how to colorize multiple levels. -

    - -
    -<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
    -    <mapping>
    -        <level value="ERROR" />
    -        <foreColor value="White" />
    -        <backColor value="Red, HighIntensity" />
    -    </mapping>
    -    <mapping>
    -        <level value="DEBUG" />
    -        <backColor value="Green" />
    -    </mapping>
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    ConsoleAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.ConsoleAppender. -

    -

    - The following example shows how to configure the ConsoleAppender - to log messages to the console. By default the messages are sent to the console - standard output stream. -

    - -
    -<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example shows how to direct the log messages to the console error stream. -

    - -
    -<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    -    <target value="Console.Error" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    EventLogAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.EventLogAppender. -

    -

    - The following example shows how to configure the EventLogAppender to log - to the Application event log on the local machine using the - event Source of the AppDomain.FriendlyName. -

    - -
    -<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example shows how to configure the EventLogAppender to - use a specific event Source. -

    - -
    -<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
    -    <applicationName value="MyApp" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - For more information on how to setup the event log to allow the - EventLogAppender to write to it, see the - FAQ: Why doesn't the EventLogAppender work?. -

    -
    -

    FileAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.FileAppender. -

    -

    - The following example shows how to configure the FileAppender - to write messages to a file. The file specified is log-file.txt. The file will - be appended to rather than overwritten each time the logging process starts. -

    - -
    -<appender name="FileAppender" type="log4net.Appender.FileAppender">
    -    <file value="log-file.txt" />
    -    <appendToFile value="true" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example shows how to configure the file name to write to using - an environment variable TMP. The encoding to use to write - to the file is also specified. -

    - -
    -<appender name="FileAppender" type="log4net.Appender.FileAppender">
    -    <file value="${TMP}\log-file.txt" />
    -    <appendToFile value="true" />
    -    <encoding value="unicodeFFFE" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example shows how to configure the appender to use the minimal locking - model that allows multiple processes to write to the same file. -

    - -
    -<appender name="FileAppender" type="log4net.Appender.FileAppender">
    -    <file value="${TMP}\log-file.txt" />
    -    <appendToFile value="true" />
    -    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    ForwardingAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.ForwardingAppender. -

    -

    - The following example shows how to configure the ForwardingAppender. - The forwarding appender allows a set of constraints to be used to decorate an appender. - In this example the ConsoleAppender is decorated with a Threshold of - level WARN. This means that an event directed to the ConsoleAppender - directly will be logged regardless of its level, but an event directed to the ForwardingAppender - will only be passed on to the ConsoleAppender if its level is WARN - or higher. This appender is used only in special circumstances. -

    - -
    -<appender name="ForwardingAppender" type="log4net.Appender.ForwardingAppender" >
    -    <threshold value="WARN"/>
    -    <appender-ref ref="ConsoleAppender" />
    -</appender>
    -                
    - -
    -

    MemoryAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.MemoryAppender. -

    -

    - It is unlikely that the MemoryAppender will be configured - using a config file, but if you want to do it here's how. -

    - -
    -<appender name="MemoryAppender" type="log4net.Appender.MemoryAppender">
    -    <onlyFixPartialEventData value="true" />
    -</appender>
    -                
    - -
    -

    NetSendAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.NetSendAppender. -

    -

    - The following example shows how to configure the NetSendAppender - to deliver messages to a specific user's screen. As this appender is typically only - used for important notifications a Threshold of level Error - is specified. This example delivers the messages to the user nicko on the - machine SQUARE. However things are not always straight forward using the Windows - Messenger Service, one possible outcome using this configuration is that the Server - will broadcast looking for a WINS server which it will then ask to deliver the message - to the Recipient, the WINS server will deliver it to the first terminal that the - user logged in from. -

    - -
    -<appender name="NetSendAppender" type="log4net.Appender.NetSendAppender">
    -    <threshold value="ERROR" />
    -    <server value="SQUARE" />
    -    <recipient value="nicko" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    OutputDebugStringAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.OutputDebugStringAppender. -

    -

    - The following example shows how to configure the OutputDebugStringAppender - to write logging messages to the OutputDebugString API. -

    - -
    -<appender name="OutputDebugStringAppender" type="log4net.Appender.OutputDebugStringAppender" >
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    RemotingAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.RemotingAppender. -

    -

    - The following example shows how to configure the RemotingAppender - to deliver logging events to a specified Sink (in this example - the sink is tcp://localhost:8085/LoggingSink). - In this example the events are delivered in blocks of 95 events because - of the BufferSize. No events are discarded. The OnlyFixPartialEventData - option allows the appender to ignore certain logging event properties that - can be very slow to generate (e.g. the calling location information). -

    - -
    -<appender name="RemotingAppender" type="log4net.Appender.RemotingAppender" >
    -    <sink value="tcp://localhost:8085/LoggingSink" />
    -    <lossy value="false" />
    -    <bufferSize value="95" />
    -    <onlyFixPartialEventData value="true" />
    -</appender>
    -                
    - -

    - This example configures the RemotingAppender to - deliver the events only when an event with level ERROR - or above is logged. When the events are delivered, up to 200 (BufferSize) - previous events (regardless of level) will be delivered to provide context. - Events not delivered will be discarded. -

    - -
    -<appender name="RemotingAppender" type="log4net.Appender.RemotingAppender" >
    -    <sink value="tcp://localhost:8085/LoggingSink" />
    -    <lossy value="true" />
    -    <bufferSize value="200" />
    -    <onlyFixPartialEventData value="true" />
    -    <evaluator type="log4net.Core.LevelEvaluator">
    -        <threshold value="ERROR"/>
    -    </evaluator>
    -</appender>
    -                
    - -
    -

    RollingFileAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.RollingFileAppender. -

    -

    - The RollingFileAppender builds on the - FileAppender and has the same options - as that appender. -

    -

    - The following example shows how to configure the RollingFileAppender - to write to the file log.txt. The file written to will always be called log.txt - because the StaticLogFileName param is specified. The file will be rolled based on - a size constraint (RollingStyle). Up to 10 (MaxSizeRollBackups) - old files of 100 KB each (MaximumFileSize) will be kept. These rolled files will be - named: log.txt.1, log.txt.2, log.txt.3, etc... -

    - -
    -<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    -    <file value="log.txt" />
    -    <appendToFile value="true" />
    -    <rollingStyle value="Size" />
    -    <maxSizeRollBackups value="10" />
    -    <maximumFileSize value="100KB" />
    -    <staticLogFileName value="true" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example show how to configure the RollingFileAppender - to roll log files on a date period. This example will roll the log file every minute! - To change the rolling period adjust the DatePattern value. - For example, a date pattern of "yyyyMMdd" will roll every day. - See System.Globalization.DateTimeFormatInfo for a list of available patterns. -

    - -
    -<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    -    <file value="logfile" />
    -    <appendToFile value="true" />
    -    <rollingStyle value="Date" />
    -    <datePattern value="yyyyMMdd-HHmm" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example show how to configure the RollingFileAppender - to roll log files on a date period and within a date period on file size. For each day - only the last 10 files of 1MB will be kept. -

    - -
    -<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    -    <file value="logfile" />
    -    <appendToFile value="true" />
    -    <rollingStyle value="Composite" />
    -    <datePattern value="yyyyMMdd" />
    -    <maxSizeRollBackups value="10" />
    -    <maximumFileSize value="1MB" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example show how to configure the RollingFileAppender - to roll log files once per program execution. The appendToFile - property is set to false to prevent the appender from overwriting - the existing files. The maxSizeRollBackups is set to negative - 1 to allow an infinite number of backup files. The file size does have to be limited but - here it is set to 50 Gigabytes which, if a log file exceeds this size limit during a single - run then it will also be rolled. -

    - -
    -<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    -    <file value="logfile.txt" />
    -    <appendToFile value="false" />
    -    <rollingStyle value="Size" />
    -    <maxSizeRollBackups value="-1" />
    -    <maximumFileSize value="50GB" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    SmtpAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.SmtpAppender. -

    -

    - The following example shows how to configure the SmtpAppender - to deliver log events via SMTP email. The To, From, Subject and - SmtpHost are required parameters. - This example shows how to deliver only significant events. A LevelEvaluator - is specified with a threshold of WARN. This means that an email - will be sent for each WARN or higher level message that is logged. - Each email will also contain up to 512 (BufferSize) previous messages of any level to - provide context. Messages not sent will be discarded. -

    - -
    -<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
    -    <to value="to@domain.com" />
    -    <from value="from@domain.com" />
    -    <subject value="test logging message" />
    -    <smtpHost value="SMTPServer.domain.com" />
    -    <bufferSize value="512" />
    -    <lossy value="true" />
    -    <evaluator type="log4net.Core.LevelEvaluator">
    -        <threshold value="WARN"/>
    -    </evaluator>
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example shows how to configure the SmtpAppender - to deliver all messages in emails with 512 (BufferSize) messages per - email. -

    - -
    -<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
    -    <to value="to@domain.com" />
    -    <from value="from@domain.com" />
    -    <subject value="test logging message" />
    -    <smtpHost value="SMTPServer.domain.com" />
    -    <bufferSize value="512" />
    -    <lossy value="false" />
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
    -    </layout>
    -</appender>
    -                
    - -

    - This example shows a more verbose formatting layout for the mail messages. -

    - -
    -<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender,log4net">
    -    <to value="to@domain.com" />
    -    <from value="from@domain.com" />
    -    <subject value="test logging message" />
    -    <smtpHost value="SMTPServer.domain.com" />
    -    <bufferSize value="512" />
    -    <lossy value="false" />
    -    <evaluator type="log4net.Core.LevelEvaluator,log4net">
    -        <threshold value="WARN" />
    -    </evaluator>
    -    <layout type="log4net.Layout.PatternLayout,log4net">
    -        <conversionPattern value="%property{log4net:HostName} :: %level :: %message %newlineLogger: %logger%newlineThread: %thread%newlineDate: %date%newlineNDC: %property{NDC}%newline%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    SmtpPickupDirAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.SmtpPickupDirAppender. -

    -

    - The SmtpPickupDirAppender is configured similarly - to the SmtpAppender. The only difference is that rather - than specify a SmtpHost parameter a PickupDir must be specified. -

    -

    - The PickupDir parameter is a path that must exist and the code executing the - appender must have permission to create new files and write to them in this directory. - The path is relative to the application's base directory (AppDomain.BaseDirectory). -

    -

    - The following example shows how to configure the SmtpPickupDirAppender - to deliver log events via SMTP email. The To, From, Subject and - PickupDir are required parameters. - This example shows how to deliver only significant events. A LevelEvaluator - is specified with a threshold of WARN. This means that an email - will be sent for each WARN or higher level message that is logged. - Each email will also contain up to 512 (BufferSize) previous messages of any level to - provide context. Messages not sent will be discarded. -

    - -
    -<appender name="SmtpPickupDirAppender" type="log4net.Appender.SmtpPickupDirAppender">
    -    <to value="to@domain.com" />
    -    <from value="from@domain.com" />
    -    <subject value="test logging message" />
    -    <pickupDir value="C:\SmtpPickup" />
    -    <bufferSize value="512" />
    -    <lossy value="true" />
    -    <evaluator type="log4net.Core.LevelEvaluator">
    -        <threshold value="WARN"/>
    -    </evaluator>
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    TraceAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.TraceAppender. -

    -

    - The following example shows how to configure the TraceAppender - to log messages to the System.Diagnostics.Trace system. - This is the tracing system supplied with the .net base class libraries. - See the MSDN documentation for the System.Diagnostics.Trace - class for more details on how to configure the trace system. -

    - -
    -<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -

    UdpAppender

    -
    -

    - For full details see the SDK Reference entry: log4net.Appender.UdpAppender. -

    -

    - The following example shows how to configure the UdpAppender - to send events to a RemoteAddress on the specified RemotePort. -

    - -
    -<appender name="UdpAppender" type="log4net.Appender.UdpAppender">
    -    <localPort value="8080" />
    -    <remoteAddress value="224.0.0.1" />
    -    <remotePort value="8080" />
    -    <layout type="log4net.Layout.PatternLayout, log4net">
    -        <conversionPattern value="%-5level %logger [%property{NDC}] - %message%newline" />
    -    </layout>
    -</appender>
    -                
    - -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/example-apps.html b/doc/release/example-apps.html deleted file mode 100644 index 2d881e50..00000000 --- a/doc/release/example-apps.html +++ /dev/null @@ -1,712 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Examples - - - - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Examples

    -
    -

    Contents

    - -

    Overview

    -
    -

    - The following examples are only available in the log4net release download, not - on-line. To obtain the examples download one of the log4net releases. - -

    -
    -

    Building Examples

    -
    -

    Building An Example

    -
    -

    - A single example can be build by running nant from - the example directory. -

    -

    - For example running nant in the - examples\net\1.0\Tutorials\ConsoleApp\cs directory - will build the C# version of the .NET 1.0 ConsoleApp example. -

    -

    - nant can be run in any directory containing a - nant.build file. The typical behavior of the build file - is to build all projects under the current directory. -

    -

    - For example running nant in the - examples\net\1.1 directory - will build all the examples for the .NET 1.1 platform. -

    -
    -

    Building All Examples

    -
    -

    - To build all the examples either run nant in the - examples directory or you can specify the - compile-examples target to the main log4net nant build. -

    -
    -

    Visual Studio .NET

    -
    -

    - There are Visual Studio .NET 2002 project files for the .NET 1.0 framework. - The solution files for C# and VB are in the examples\net\1.0 - folder. -

    -

    - For the Managed C++ project there is a Visual Studio .NET 2003 project file - in the examples\net\1.1 folder. -

    -
    -
    -

    Examples

    -
    -

    Tutorial - ConsoleApp

    -
    -

    - ConsoleApp shows how to write a simple console application that initializes - logging and logs various events. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    - -

    - To run this example execute ConsoleApp.exe from the build output directory. -

    -
    -

    Tutorial - WebApp

    -
    -

    - ConsoleApp shows how to write a simple ASP.NET web application that initializes - logging and logs various events. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - .NET 1.0: - C#, - VB -
    • -
    -

    - To run this example you need to have an ASP.NET container application to - host the web application, for example IIS. In IIS create a new virtual - directory pointing to the WebApp src directory. Configure IIS to recognize - this virtual directory as an application. Open up a web browser, navigate to - the virtual directory and to the WebForm1.aspx page within it. -

    -
    -

    Remoting - RemotingClient

    -
    -

    - The RemotingClient application is a simple console application that configures - log4net with the RemotingAppender. This appender will attempt to deliver the - logging events to a remoting listener. This example should be run in conjunction - with the RemotingServer. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - .NET 1.0: - C# -
    • -
    -

    - To run this example execute RemotingClient.exe from the build output directory. -

    -
    -

    Remoting - RemotingServer

    -
    -

    - The RemotingServer application is a simple console application that listens for - logging events from a remote RemotingAppender and then logs them through the - local log4net instance. This example should be run in conjunction - with the RemotingClient. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - .NET 1.0: - C# -
    • -
    -

    - To run this example execute RemotingServer.exe from the build output directory. - While this process is running execute the RemotingClient.exe program on - the same machine. The logging events from the client are transferred to the server. -

    -
    -

    Repository - SimpleModule

    -
    -

    - The SimpleModule is a class library that is intended to be used as part of - the SimpleApp example, - This class library uses the log4net.Config.Repository - attribute to create a separate configuration space from other assemblies. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - MONO 1.0: - C# -
    • -
    • - .NET 1.0: - C#, - VB -
    • -
    • - .NET 1.1: - JScript.NET -
    • -
    • - SSCLI 1.0: - C# -
    • -
    -

    - This library is intended to be used as part of the SimpleApp example. -

    -
    -

    Repository - SharedModule

    -
    -

    - The SharedModule is a class library that is intended to be used as part of - the SimpleApp example, - This class library uses log4net but does not attempt to configure logging. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - MONO 1.0: - C# -
    • -
    • - .NET 1.0: - C#, - VB -
    • -
    • - .NET 1.1: - JScript.NET -
    • -
    • - SSCLI 1.0: - C# -
    • -
    -

    - This library is intended to be used as part of the SimpleApp example. -

    -
    -

    Repository - SimpleApp

    -
    -

    - The SimpleApp example uses the SimpleModule and SharedModule to demonstrate - the ways in which multiple assemblies within the same process may be - separately configured. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - MONO 1.0: - C# -
    • -
    • - .NET 1.0: - C#, - VB -
    • -
    • - .NET 1.1: - JScript.NET -
    • -
    • - SSCLI 1.0: - C# -
    • -
    -

    - To run this example execute SimpleApp.exe from the build output directory. -

    -
    -

    Extensibility - EventIDLogApp

    -
    -

    - The EventIDLogApp example demonstrates using the log4net.Ext.EventID extension. - The extension needs to be built separately from the - extensions\net\1.0\log4net.Ext.EventID directory. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - .NET 1.0: - C# -
    • -
    -

    - To run this example execute EventIDLogApp.exe from the build output directory. -

    -
    -

    Extensibility - TraceLogApp

    -
    -

    - The TraceLogApp example demonstrates using the log4net.Ext.Trace extension. - The extension needs to be built separately from the - extensions\net\1.0\log4net.Ext.Trace directory. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - .NET 1.0: - C# -
    • -
    -

    - To run this example execute TraceLogApp.exe from the build output directory. -

    -
    -

    SampleAppenders

    -
    -

    - This project includes the following example appenders. -

    -
      -
    • - AsyncAppender -
    • -
    • - FastDbAppender -
    • -
    • - FireEventAppender -
    • -
    • - MessageBoxAppender -
    • -
    • - MessageObjectExpanderAppender -
    • -
    • - MsmqAppender -
    • -
    • - PatternFileAppender -
    • -
    • - SimpleSmtpAppender -
    • -
    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - .NET 1.0: - C# -
    • -
    -

    - To run this example execute SampleAppendersApp.exe from the build output directory. -

    -
    -

    SampleLayouts

    -
    -

    - This project includes the following example layouts. -

    -
      -
    • - ForwardingLayout -
    • -
    • - LineWrappingLayout -
    • -
    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - .NET 1.0: - C# -
    • -
    -

    - To run this example execute SampleLayoutsApp.exe from the build output directory. -

    -
    -

    Performance - NotLogging

    -
    -

    - The NotLogging example benchmarks the performance of log4net logging statements in - user code in various scenarios including when logging is disabled. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - MONO 1.0: - C# -
    • -
    • - .NET 1.0: - C#, - VB -
    • -
    -

    -

    -
    -

    WmiAppender

    -
    -

    - The WmiAppender sample shows an example appender that fires events through - Windows Management Instrumentation. -

    -

    - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

    -
      -
    • - .NET 1.0: - C# -
    • -
    -

    -

    -
    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/faq.html b/doc/release/faq.html deleted file mode 100644 index d9351eab..00000000 --- a/doc/release/faq.html +++ /dev/null @@ -1,1240 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Frequently Asked Questions - - - - - - - - - - - - - - - - - -
    - - - - -

    Apache log4net Frequently Asked Questions

    -
    -

    Contents

    -
    - Information
    - - Configuration
    - - Implementing Logging
    - - Customization
    - - Troubleshooting
    - - Miscellaneous
    - -
    -

    Information

    -
    -

    What is log4net?

    -
    -

    - log4net is a tool to help the programmer output log statements to a variety of - output targets. -

    -

    - In case of problems with an application, it is helpful to enable logging so - that the problem can be located. With log4net it is possible to enable logging at - runtime without modifying the application binary. The log4net package is designed - so that log statements can remain in production code without incurring a - high performance cost. It follows that the speed of logging (or rather not - logging) is crucial. -

    -

    - At the same time, log output can be so voluminous that it quickly becomes - overwhelming. One of the distinctive features of log4net (and common to all of - the log4x libraries) is the notion of hierarchical - loggers. Using these loggers it is possible to selectively control - which log statements are output at arbitrary granularity. -

    -

    - log4net is designed with two distinct goals in mind: speed and flexibility. There - is a tight balance between these two requirements. -

    -
    -

    Back to Top

    -

    Is log4net a reliable logging system?

    -
    -

    - No. log4net is not reliable. It is a best-effort and fail-stop logging system. -

    -

    - By fail-stop, we mean that log4net will not throw unexpected exceptions at - run-time potentially causing your application to crash. If for any reason, log4net - throws an uncaught exception (except for ArgumentException and - ArgumentNullException which may be thrown), please send an email - to the - log4net-user@logging.apache.org mailing list. Uncaught exceptions - are handled as serious bugs requiring immediate attention. -

    -

    - Moreover, log4net will not revert to System.Console.Out - or System.Console.Error when its designated - output stream is not opened, is not writable or becomes full. This avoids - corrupting an otherwise working program by flooding the user's terminal because - logging fails. However, log4net will output a single message to - System.Console.Error and System.Diagnostics.Trace - indicating that logging can not be performed. -

    -
    -

    Back to Top

    -

    What are the prerequisites for log4net?

    -
    -

    - log4net runs on many different frameworks and each framework has its own requirements. - As a rule of thumb you will need an ECMA-335 compliant CLI runtime, for example, - the Microsoft .NET runtime 1.0 (1.0.3705) or 1.1 (1.1.4322). -

    -

    - Not all frameworks are created equal and some features have been excluded from - some of the builds. See the Framework Support - document for more information. -

    -
    -

    Back to Top

    -

    Is there example code for using log4net?

    -
    -

    - There is a directory containing examples in log4net\examples. - The examples are broken down by framework. -

    -
    -

    Back to Top

    -

    What are the features of log4net?

    -
    -
      -
    • - log4net is optimized for speed.
    • -
    • - log4net is based on a named logger hierarchy.
    • -
    • - log4net is fail-stop but not reliable.
    • -
    • - log4net is thread-safe.
    • -
    • - log4net is not restricted to a predefined set of facilities.
    • -
    • - Logging behavior can be set at runtime using a configuration file. - Configuration files are in XML format.
    • -
    • - log4net is designed to handle exceptions from the start.
    • -
    • - log4net can direct its output to many sinks including: a file, the console, the NT EventLog or even e-mail.
    • -
    • - log4net categorizes logging into levels: DEBUG, INFO, WARN, ERROR and FATAL.
    • -
    • - The format of the log output can be easily changed by implementing a new layout class.
    • -
    • - The target of the log output as well as the writing strategy can be altered by - writing a new appender class.
    • -
    • - log4net supports multiple output appenders per logger.
    • -
    -

    - See the features overview document for more information on the features of log4net. -

    -
    -

    Back to Top

    -

    Is log4net thread-safe?

    -
    -

    - Yes, log4net is thread-safe. -

    -
    -

    Back to Top

    -

    What does log output look like?

    -
    -

    - The log output can be customized in many ways. Moreover, one can completely - override the output format by implementing one's own ILayout -

    -

    - Here is an example output using PatternLayout with the conversion - pattern %timestamp [%thread] %-5level %logger{2} %ndc - %message%newline -

    - -
    -176 [main] INFO  examples.Sort - Populating an array of 2 elements in reverse order.
    -225 [main] INFO  examples.SortAlgo - Entered the sort method.
    -262 [main] DEBUG SortAlgo.OUTER i=1 - Outer loop.
    -276 [main] DEBUG SortAlgo.SWAP i=1 j=0 - Swapping intArray[0] = 1 and intArray[1] = 0
    -290 [main] DEBUG SortAlgo.OUTER i=0 - Outer loop.
    -304 [main] INFO  SortAlgo.DUMP - Dump of integer array:
    -317 [main] INFO  SortAlgo.DUMP - Element [0] = 0
    -331 [main] INFO  SortAlgo.DUMP - Element [1] = 1
    -343 [main] INFO  examples.Sort - The next log statement should be an error message.
    -346 [main] ERROR SortAlgo.DUMP - Tried to dump an uninitialized array.
    -467 [main] INFO  examples.Sort - Exiting main method.
    - -

    - The first field is the number of milliseconds elapsed since the start of the - program. The second field is the thread outputting the log statement. The third - field is the level of the log statement. The fourth field is the rightmost - two components of the name of the logger making the log request. The fifth field (just - before the '-') is the nested diagnostic context (NDC). Note the - nested diagnostic context may be empty as in the first two statements. The text - after the '-' is the message of the statement. -

    -
    -

    Back to Top

    -

    What are Loggers?

    -
    -

    - The logger concept lies at the heart of log4net's configuration. Loggers are organized into a - hierarchy and give the programmer run-time control on which logging statements - are printed or not. -

    -

    - Loggers are assigned levels through the configuration of log4net. A log statement is - routed through to the appender depending on its level and its logger. -

    -
    -

    Back to Top

    -

    Why should I donate my extensions to log4net back to the project?

    -
    -

    - Contrary to the GNU Public License (GPL) the Apache Software License does not - make any claims over your extensions. By extensions, we mean totally new code - that invokes existing log4net code. You are free to do whatever you wish with - your proprietary log4net extensions. In particular, you may choose to - never release your extensions to the wider public. For details see the - Apache License, Version 2.0. -

    -

    - We are very careful not to unnecessarily change the log4net client API so that newer log4net - releases are backward compatible with previous versions. We are a lot less - scrupulous with the internal log4net API. Thus, if your extension is designed to - work with the internals of a specific log4net version, then when the next release - of log4net comes out, you will probably need to adapt your proprietary extensions to the - new release. Thus, you will be forced to spend precious resources in order to - keep up with log4net changes. This is commonly referred to as the "stupid-tax". - By donating the code and making it part of the standard distribution, you save - yourself the unnecessary maintenance work. -

    -

    - If your extensions are useful then someone will eventually write an extension - providing the same or very similar functionality. Your development effort will - be wasted. -

    -

    - Unless the proprietary log4net extension is business critical, there is little - reason for not donating your extensions back to the project. -

    -
    -

    Back to Top

    -

    What should I keep in mind when contributing code?

    -
    -
      -
    1. - Stick to the existing indentation style even if you hate it. -

      - Alternating between indentation styles makes it hard to understand the source - code. Make it hard on yourself but easier on others. -

      -
    2. -
    3. - Thoroughly test your code. -

      - There is nothing more irritating than finding the bugs in debugging (i.e. logging) code. -

      -
    4. -
    5. - Keep it simple, small and fast. -

      - It's all about the application not about logging. -

      -
    6. -
    7. - Did I mention sticking with the indentation style?
    8. -
    -
    -

    Back to Top

    -

    How fast do bugs in log4net get fixed?

    -
    -

    - As fast as they get reported ;-) -

    -
    -

    Back to Top

    -

    What is the history of log4net?

    -
    -

    - log4net is a port of the popular log4j logging library. - The initial port was done in June 2001, since then we have tried to remain in the - spirit of the original log4j. See the log4net history page for more details. -

    -
    -

    Back to Top

    -

    Where can I find the latest distribution of log4net?

    -
    -

    - The log4net home page is a good place to start. -

    -
    -

    Back to Top

    -
    -

    Configuration

    -
    -

    How can I change log behavior at runtime?

    -
    -

    - Logging behavior can be set using configuration files which are parsed at runtime. - Using configuration files the programmer can define loggers and set their - levels. -

    -

    - Configuration files are specified in XML. See log4net.Config.XmlConfigurator - for more details. -

    -

    - See the various log4net.Layout and log4net.Appender - components for specific configuration options. -

    -
    -

    Back to Top

    -

    How do I completely disable all logging at runtime?

    -
    -

    - Setting the Threshold on the Hierarchy to Level OFF will disable all - logging from that Hierarchy. This can be done in the log4net configuration file - by setting the "threshold" attribute on the log4net configuration element to "OFF". - For example: -

    - -
    -<log4net threshold="OFF" />
    - -
    -

    Back to Top

    -

    What are the configurable options for an appender?

    -
    -

    - log4net uses public properties to configure components such as - Appenders, Layouts, Loggers etc. -

    -

    - Thus, any writable public property in on the appender corresponds to a - configurable option. For example, in RollingFileAppender the - public int MaxSizeRollBackups { set; } property corresponds to - the MaxSizeRollBackups option. -

    -

    - Layouts options are also defined by their writable properties. Same goes for most - other log4net components. -

    -
    -

    Back to Top

    -

    Is it possible to direct log output to different appenders by level?

    -
    -

    - Yes it is. Setting the Threshold option of any appender extending - AppenderSkeleton, (most log4net appenders extend - AppenderSkeleton) will filter out all log events - with a lower level than the value of the threshold option. -

    -

    - For example, setting the threshold of an appender to DEBUG will also allow INFO, - WARN, ERROR and FATAL messages to log along with DEBUG messages. (DEBUG is the - lowest level). This is usually acceptable as there is little use for DEBUG - messages without the surrounding INFO, WARN, ERROR and FATAL messages. - Similarly, setting the threshold of an appender to ERROR will filter out DEBUG, - INFO and WARN messages but not ERROR or FATAL messages. -

    -

    - This policy usually best encapsulates what the user actually wants to do, as - opposed to her mind-projected solution. -

    -

    - If you must filter events by exact level match, then you can attach a - LevelMatchFilter to any appender to filter out logging - events by exact level match. -

    -
    -

    Back to Top

    -

    Is there a way to get log4net to automatically reload a configuration file if it changes?

    -
    -

    - Yes. The XmlConfigurator supports automatic - reloading through the ConfigureAndWatch APIs. See the API - documentation for more details. -

    -
    -

    Back to Top

    -

    Can I load an appender from another assembly?

    -
    -

    - Yes. When specifying the type in the configuration file you can give the assembly - qualified name of the type. For example: -

    - -
    -<appender name="..." type="MyNamespace.MyAppender, MyAssembly">
    - -

    - The .NET runtime will try to locate the assembly called MyAssembly. - How .NET locates assemblies is beyond the scope of this FAQ. -

    -

    - When loading an assembly from the GAC the fully qualified assembly name, - including the version, culture and public key must be specified. This is - in the standard syntax supported by System.Type.GetType. - See the next FAQ on how to get the version and public key for an assembly. -

    -
    -

    Back to Top

    -

    How do I get the Public Key for an assembly?

    -
    -

    - The fully qualified name for an assembly includes the version, culture and - public key. The public key is derived from the strong name used to identify - the publisher. When referencing an assembly from the GAC the fully qualified - name must be used. To get the version, culture and public key you can use a - tool like the excellent .NET Reflector from Lutz Roeder available from - http://www.aisto.com/roeder/dotnet. -

    -
    -

    Back to Top

    -

    How do I insert newlines into the layout header?

    -
    -

    - Newlines in the config file need to be escaped using an XML numeric character reference. - The sequence that represents a CR LF is &#13; &#10;. The following example adds - a header and footer to the output each followed by a newline. -

    - -
    -<layout type="log4net.Layout.PatternLayout">
    -    <header value="[Header]&#13;&#10;" />
    -    <footer value="[Footer]&#13;&#10;" />
    -    <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    -</layout>
    - -
    -

    Back to Top

    -

    How do I use a pattern to set the value of a string property?

    -
    -

    - Log4net supports a pattern syntax for setting string properties similar to the - PatternLayout used to format the output messages. - This pattern syntax can be used by specifying type="log4net.Util.PatternString" - on the string property in the config file. This tells the config parser to pass the - value to the PatternString type before converting the result - to a string. For details on the patterns supported see the - PatternString SDK Reference. -

    -

    - The following example sets the file name for a FileAppender to include the - current process id by specifying the %processid pattern in the - File property. -

    - -
    -<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
    -    <file type="log4net.Util.PatternString" value="log-file-[%processid].txt" />
    -    <layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
    -</appender>
    - -
    -

    Back to Top

    -
    -

    Implementing Logging

    -
    -

    Are there any suggested ways for naming loggers?

    -
    -

    - Yes, there are. -

    -

    - You can name logging loggers by locality. It turns out that - instantiating a logger in each class, with the logger name equal to the - fully-qualified name of the class, is a useful and straightforward approach of - defining loggers. This approach has many benefits: -

    -
      -
    • - It is very simple to implement.
    • -
    • - It is very simple to explain to new developers.
    • -
    • - It automatically mirrors your application's own modular design.
    • -
    • - It can be further refined at will.
    • -
    • - Printing the logger automatically gives information on the locality of the - log statement.
    • -
    -

    - However, this is not the only way for naming loggers. A common alternative - is to name loggers by functional areas. For example, the - "database" logger, "remoting" logger, "security" logger, or the "XML" - logger. -

    -

    - You may choose to name loggers by functionality and subcategorize by - locality, as in "DATABASE.MyApp.MyClass" or - "DATABASE.MyApp.MyModule.MyOtherClass". -

    -

    - You are totally free in choosing the names of your loggers. The - log4net package merely allows you to manage your names in a hierarchy. However, - it is your responsibility to define this hierarchy. -

    -

    - Note: by naming loggers by locality one tends to name things by - functionality, since in most cases the locality relates closely to - functionality. -

    -
    -

    Back to Top

    -

    How do I get the fully-qualified name of a class in a static block?

    -
    -

    - You can easily retrieve the fully-qualified name of a class in a static block - for class X, with the statement typeof(X).Name. - Note that X is the class name and span an instance. - However because the LogManager.GetLogger method is overloaded - to take an instance of Type as well as string - usually only the type of the class is required. -

    -

    - Here is the suggested usage template: -

    - -
    -public class Foo
    -{
    -    private static readonly ILog log = LogManager.GetLogger(typeof(Foo));
    -    ... other code
    -}
    - -

    - An equivalent and more portable solution, though slightly longer, is to use the declaring type - of the static constructor. -

    - -
    -public class Foo
    -{
    -    private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    -    ... other code
    -}
    - -

    - Note: the .NET Compact Framework 1.0 does not support System.Reflection.MethodBase.GetCurrentMethod(). -

    -
    -

    Back to Top

    -

    What is the fastest way of (not) logging?

    -
    -

    - For some logger log, writing, -

    - -
    -log.Debug("Entry number: " + i + " is " + entry[i]);
    - -

    - incurs the cost of constructing the message parameter, that is converting both - integer i and entry[i] to - a string, and concatenating intermediate strings. This, regardless of whether - the message will be logged or not. -

    -

    - If you are worried about speed, then write -

    - -
    -if(log.IsDebugEnabled) 
    -{
    -    log.Debug("Entry number: " + i + " is " + entry[i]);
    -}
    - -

    - This way you will not incur the cost of parameter construction if debugging is - disabled for logger log. On the other hand, if the logger is - debug enabled, you will incur the cost of evaluating whether the logger is - enabled or not, twice: once in IsDebugEnabled and once in Debug. - This is an insignificant overhead since evaluating a logger takes less than - 1% of the time it takes to actually log a statement. -

    -
    -

    Back to Top

    -

    What is REALLY the FASTEST way of (not) logging?

    -
    -

    - So you don't think that the previous FAQ is really the fastest way - of not logging? Well there is a faster way but it does have some - drawbacks. Starting from: -

    - -
    -if(log.IsDebugEnabled) 
    -{
    -    log.Debug("Entry number: " + i + " is " + entry[i]);
    -}
    - -

    - It is possible to further eliminate the calls to IsDebugEnabled - so that the call is only made once per logger. If you are using one logger - for each class then you can store the enabled state for the logger in a static - variable in the class and then test against this variable: -

    - -
    -public class FastLogger
    -{
    -    private static readonly ILog log = LogManager.GetLogger(typeof(FastLogger));
    -    private static readonly bool isDebugEnabled = log.IsDebugEnabled;
    -
    -    public void MyMethod()
    -    {
    -        if(isDebugEnabled) 
    -        {
    -            log.Debug("Entry number: " + i + " is " + entry[i]);
    -        }
    -    }
    -}
    - -

    - So why exactly is this faster? Well to start with the IsDebugEnabled - is not called for each log statement, it is called once per logger. Furthermore as the - isDebugEnabled variable is private static readonly - the JIT compiler can at run-time optimize out the if test altogether. - This means that at runtime the JIT compiler won't even compile the logging statements into native code, i.e. - all the logging just disappears. -

    -

    - So what is the downside to using this? Well one of the clever features of log4net is that - you can change the logging configuration while your program is running. If you need to - investigate an issue in your application, you don't have to stop the application, setup the - logging and restart the application, you can change the logging configuration and the - log4net will reload it (see XmlConfigurator.ConfigureAndWatch APIs for more - information). However if the JIT has compiled out all of the logging statements - then they are gone and you can't get them back by reloading the configuration file. Effectively - this means that the logging configuration can only be set when the application loads and - it cannot be changed at runtime. It is up to you to decide if you need ultimate speed or need - to be able to reload the logging configuration while the application is running. -

    -
    -

    Back to Top

    -

    Can the outputs of multiple client request go to different log files?

    -
    -

    - Many developers are confronted with the problem of distinguishing the log - output originating from the same class but different client requests. They come - up with ingenious mechanisms to fan out the log output to different files. In - most cases, this is not the right approach. -

    -

    - It is simpler to use a context property or stack (ThreadContext). - Typically, one would ThreadContext.Properties["ID"] = "XXX" - client specific information, such as the client's hostname, ID or any other - distinguishing information when starting to handle the client's request. - Thereafter, log output will automatically include the context data - so that you can distinguish logs from different client requests even if they - are output to the same file. -

    -

    - See the ThreadContext and the PatternLayout classes for more - information. -

    -
    -

    Back to Top

    -

    Logger instances seem to be create only. Why isn't there a method to remove logger instances?

    -
    -

    - It is quite nontrivial to define the semantics of a "removed" logger which is - still referenced by the user. -

    -
    -

    Back to Top

    -

    How do I get multiple process to log to the same file?

    -
    -

    - By default the FileAppender holds an exclusive write - lock on the log file while it is logging. This prevents other processes from - writing to the file. The FileAppender can be configured - to use a different locking model, MinimalLock, that - only acquires the write lock while a log is being written. This allows multiple - processes to interleave writes to the same file, albeit with a loss in performance. - See the FileAppender config examples - for an example MinimalLock configuration. -

    -

    - While the MinimalLock model may be used to interleave - writes to a single file it may not be the optimal solution, especially when - logging from multiple machines. Alternatively you may have one or more processes - log to RemotingAppenders. - Using the RemoteLoggingServerPlugin (or - IRemoteLoggingSink) a process can receive all the events and - log them to a single log file. -

    -
    -

    Back to Top

    -

    If I have many processes across multiple hosts (possibly across multiple time zones) logging to the same file using the RemotingAppender, what happens to timestamps?

    -
    -

    - The timestamp is created when the logging event is created. That is so say, - when the Debug, Info, - Warn, Error - or Fatal method is invoked. This is unaffected by the time at - which they may arrive at a remote server. Since the timestamps are - transmitted in UTC format by the RemotingAppender, - they all appear in the same time zone as - the host creating the logfile. Since the clocks of various machines may not be - synchronized, this may account for time interval inconsistencies between events - generated on different hosts. -

    -
    -

    Back to Top

    -

    When should I log my first message?

    -
    -

    - The simple answer is as soon as possible. The long answer is more complex. -

    -

    - If you are configuring log4net programmatically, i.e. by calling the - XmlConfigurator.Configure method then you should do so - before you begin logging and it is reasonable to do this very soon after application - start. -

    -

    - If you are configuring log4net by specifying assembly level attributes on - your assembly then the configuration will be loaded once the first call to - the LogManager.GetLogger is made. It is necessary - that the first call to LogManager.GetLogger made - during the process (or AppDomain) is made from the assembly that has the - configuration attributes. Log4net will look only once and only on the first - calling assembly for the configuration attributes. -

    -
    -

    Back to Top

    -
    -

    Customization

    -
    -

    Can the log output format be customized?

    -
    -

    - Yes. You can implement the log4net.Layout.ILayout - interface to create you own customized log format, or you can extend the - LayoutSkeleton class which provides a default - implementation of the ILayout interface. - Appenders can be parameterized to use the layout of your choice. -

    -
    -

    Back to Top

    -

    Can I write a custom appender?

    -
    -

    - Yes. You can implement the log4net.Appender.IAppender - interface to create you own customized appender. We recommend that you extend the - log4net.Appender.AppenderSkeleton class rather than - starting from scratch. You should implement your custom code in a assembly - separate from the log4net assembly. To get started it is worth looking at the - source of the log4net.Appender.TraceAppender as an - example of the minimum amount of code required to get an appender working. -

    -

    - To configure log4net to use your custom appender you need to specify the - assembly qualified name of the appender type in the config file. For - example: -

    - -
    -<appender name="..." type="MyNamespace.MyAppender, MyAssembly">
    - -

    - The .NET runtime will try to locate the assembly called MyAssembly. - How .NET locates assemblies is beyond the scope of this FAQ. -

    -
    -

    Back to Top

    -
    -

    Troubleshooting

    -
    -

    How do I enable log4net internal debugging?

    -
    -

    - There are 2 different ways to enable internal debugging in log4net. - These are listed below. The preferred method is to specify - the log4net.Internal.Debug option in the application's - config file. -

    -
      -
    • -

      - Internal debugging can also be enabled by setting a value in the application's - configuration file (not the log4net configuration file, unless the log4net config - data is embedded in the application's config file). The log4net.Internal.Debug - application setting must be set to the value true. - For example: -

      -
      -<?xml version="1.0" encoding="utf-8" ?>
      -<configuration>
      -    <appSettings>
      -        <add key="log4net.Internal.Debug" value="true"/>
      -    </appSettings>
      -</configuration>
      -

      - This setting is read immediately on startup an will cause all internal - debugging messages to be emitted. -

      -
    • -
    • -

      - To enable log4net's internal debug programmatically you need - to set the log4net.Util.LogLog.InternalDebugging - property to true. Obviously the sooner this - is set the more debug will be produced. -

      -
    • -
    -

    - Internal debugging messages are written to the console and to the - System.Diagnostics.Trace - system. If the application does not have a console the messages logged - there will be lost. Note that an application can redirect the console - stream by setting the System.Console.Out. The - Trace system will by default send the message to an attached debugger - (where the messages will appear in the output window). If the process - does not have a debugger attached then the messages are sent to the - system debugger. A utility like DebugView from - http://www.sysinternals.com - may be used to capture these messages. -

    -

    - As log4net internal debug messages are written to the System.Diagnostics.Trace - system it is possible to redirect those messages to a local file. You can define - a trace listener by adding the following to your application's .config file: -

    -
    -<configuration>
    -    ...
    -    
    -    <system.diagnostics>
    -        <trace autoflush="true">
    -            <listeners>
    -                <add 
    -                    name="textWriterTraceListener" 
    -                    type="System.Diagnostics.TextWriterTraceListener" 
    -                    initializeData="C:\tmp\log4net.txt" />
    -            </listeners>
    -        </trace>
    -    </system.diagnostics>
    -
    -    ...
    -</configuration>
    -

    - Make sure that the process running your application has permission - to write to this file. -

    -
    -

    Back to Top

    -

    Why doesn't the EventLogAppender work?

    -
    -

    - If you are not getting events delivered to the event log this usually indicates - a permissions problem. Basically if the event log does not exist the EventLogAppender - tries to create it, but you need local administrator permissions to create event logs - (just to write into the right bit of the registry). You don't need administrator - permissions to log to an existing event log, but it must exist. If you are using the - event log from a web application or service using the event log can be a little tricky. -

    -

    - A web application will run as the user account ASPNET. This account deliberately has - few permissions to reduce the chances of someone hacking into the web server. While the - account has permission to write to the event log it does not have permission to create - event sources (registry create and write access), which are needed to write to the event log. -

    -

    - There are a couple of solutions: -

    -
      -
    1. -

      - Make the ASPNET user a member of the Administrators group. This will work because the - user will then have the required permissions. This is not recommended - for production use. -

      -
    2. -
    3. -

      - As the event source only needs to be created once for the machine, create an installer - and configure it to create the event source. - The installer will need to be run as Administrator (don't they all). See - System.Diagnostics.EventLogInstaller in the Microsoft .NET - Framework SDK for an example of how to create a simple event log installer. -

      -
    4. -
    -

    - There is a Microsoft Knowledge Base article that covers this issue and how to resolve - it. - PRB: "Requested Registry Access Is Not Allowed" Error Message When ASP.NET - Application Tries to Write New EventSource in the EventLog. -

    -
    -

    Back to Top

    -

    Why can't I log to a FileAppender from a web application?

    -
    -

    - The web application runs as a special user account on the web server - called ASPNET. This account has restricted permissions to protect the - web server from attacks. By default this account may not have permission - to write to the file system. Make sure that the ASPNET account has - permission to create and write to files in the directory chosen for - logging. -

    -
    -

    Back to Top

    -

    Why doesn't the logging in my service work?

    -
    -

    - A windows service runs as a user account specified in the services - control panel. This account may have restricted permissions, make - sure that the account has permission to create and write to files - in the directory chosen for logging. -

    -

    - A windows service is launched by windows. The current directory in - a service is set to the windows system directory (e.g. - C:\Windows\System32). If you are loading - the configuration file from the current directory then be aware - that this path will not be the location of your assemblies. - The best way to get the path to your assemblies is to use - AppDomain.BaseDirectory. - Note that the log4net internals never use the current directory. -

    -
    -

    Back to Top

    -

    I am having trouble using the AdoNetAppender to connect to my database?

    -
    -

    - For details on the different ways in which ADO.NET can connect to a database see: - Connecting to a Data Source Using ADO.NET. -

    -

    - If you need to use ODBC to connect to your database then please note that the - ADO.NET ODBC drivers are not included in the standard .NET framework redistributable. - You can download the drivers from microsoft download at: - ODBC .NET Data Provider. -

    -
    -

    Back to Top

    -

    How do I report bugs?

    -
    -

    - See the support page for details. -

    -
    -

    Back to Top

    -
    -

    Miscellaneous

    -
    -

    How do I make log4net appear in the Visual Studio Add References dialog?

    -
    -

    - There is a good discussion of this topic on Robert McLaws blog: - Building a Better Server Control Experience, Part 2. -

    -
    -

    Back to Top

    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/features.html b/doc/release/features.html deleted file mode 100644 index 67d14e95..00000000 --- a/doc/release/features.html +++ /dev/null @@ -1,462 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Features - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Features

    -
    -

    Contents

    - -

    Overview

    -
    -

    - log4net is a tool to help the programmer output log statements to a - variety of output targets. In case of problems with an application, - it is helpful to enable logging so that the problem can be located. - With log4net it is possible to enable logging at runtime without - modifying the application binary. The log4net package is designed so - that log statements can remain in shipped code without incurring a - high performance cost. It follows that the speed of logging (or - rather not logging) is crucial. -

    -

    - At the same time, log output can be so voluminous that it quickly becomes - overwhelming. One of the distinctive features of log4net is the notion of - hierarchical loggers. Using these loggers it is possible to selectively - control which log statements are output at arbitrary granularity. -

    -

    - log4net is designed with two distinct goals in mind: speed and flexibility -

    -
    -

    Features

    -
    -
      -
    • Support for multiple frameworks

    • -
    • Output to multiple logging targets

    • -
    • Hierarchical logging architecture

    • -
    • XML Configuration

    • -
    • Dynamic Configuration

    • -
    • Logging Context

    • -
    • Proven architecture

    • -
    • Modular and extensible design

    • -
    • High performance with flexibility

    • -
    -
    -

    Support for multiple frameworks

    -
    -

    - log4net runs on all ECMA CLI 1.0 compatible runtimes. - log4net has specific builds for the following frameworks: -

    -
      -
    • Microsoft .NET Framework 1.0 (1.0.3705)
    • -
    • Microsoft .NET Framework 1.1 (1.1.4322)
    • -
    • Microsoft .NET Framework 2.0 (2.0.50727)
    • -
    • Microsoft .NET Compact Framework 1.0
    • - -
    • Mono 1.0
    • -
    • Mono 2.0
    • -
    • Microsoft Shared Source CLI 1.0
    • -
    • CLI 1.0 Compatible
    • -
    -

    - Note: Due to the .NET frameworks support for backward compatibility - log4net will run on future versions of the runtimes listed above. -

    -
    -

    Output to multiple logging targets

    -
    -

    - log4net ships with the following appenders (not on all frameworks): -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Type - Description
    log4net.Appender.AdoNetAppender - Writes logging events to a database using either prepared statements or stored - procedures. -
    log4net.Appender.AnsiColorTerminalAppender - Writes color highlighted logging events to a an ANSI terminal window. -
    log4net.Appender.AspNetTraceAppender - Writes logging events to the ASP trace context. These can then be rendered at - the end of the ASP page or on the ASP trace page. -
    log4net.Appender.ColoredConsoleAppender - Writes color highlighted logging events to the application's Windows Console. -
    log4net.Appender.ConsoleAppender - Writes logging events to the application's Console. The events may go to either - the standard our stream or the standard error stream. -
    log4net.Appender.EventLogAppender - Writes logging events to the Windows Event Log. -
    log4net.Appender.FileAppender - Writes logging events to a file in the file system. -
    log4net.Appender.LocalSyslogAppender - Writes logging events to the local syslog service (UNIX only). -
    log4net.Appender.MemoryAppender - Stores logging events in an in memory buffer. -
    log4net.Appender.NetSendAppender - Writes logging events to the Windows Messenger service. These messages are - displayed in a dialog on a users terminal. -
    log4net.Appender.OutputDebugStringAppender - Writes logging events to the debugger. If the application has no - debugger, the system debugger displays the string. If the application has no - debugger and the system debugger is not active, the message is ignored. -
    log4net.Appender.RemoteSyslogAppender - Writes logging events to a remote syslog service using UDP networking. -
    log4net.Appender.RemotingAppender - Writes logging events to a remoting sink using .NET remoting. -
    log4net.Appender.RollingFileAppender - Writes logging events to a file in the file system. The RollingFileAppender can - be configured to log to multiple files based upon date or file size - constraints. -
    log4net.Appender.SmtpAppender - Sends logging events to an email address. -
    log4net.Appender.TelnetAppender - Clients connect via Telnet to receive logging events. -
    log4net.Appender.TraceAppender - Writes logging events to the .NET trace system. -
    log4net.Appender.UdpAppender - Sends logging events as connectionless UDP datagrams to a remote host or a - multicast group using a UdpClient. -
    -
    -

    -

    -

    Hierarchical logging architecture

    -
    -

    - Hierarchical logging is an ideal fit with component based development. - Each component has its own of logger. When individually tested, the - properties of these loggers may be set as the developer requires. - When combined with other components, the loggers inherit the properties - determined by the integrator of the components. One can selectively elevate - logging priorities on one component without affecting the other components. - This is useful when you need a detailed trace from just a single component - without crowding the trace file with messages from other components. All - this can be done through configuration files; no code changes are required. -

    -
    -

    XML Configuration

    -
    -

    - log4net is configured using an XML configuration file. The configuration - information can be embedded within other XML configuration files - (such as the application's .config file) or in a separate file. The - configuration is easily readable and updateable while retaining the - flexibility to express all configurations. -

    -

    - Alternatively log4net can be configured programmatically. -

    -
    -

    Dynamic Configuration

    -
    -

    - log4net can monitor its configuration file for changes and dynamically - apply changes made by the configurator. The logging levels, appenders, - layouts, and just about everything else can be adjusted at runtime. - In many cases it is possible to diagnose application issues without - terminating the process in question. This can a very valuable tool in - investigating issues with deployed applications. -

    -
    -

    Logging Context

    -
    -

    - log4net can be used to collect logging context data in a way that is transparent - to the developer at the point of logging. The GlobalContext and the - ThreadContext allow the application to store contextual data that is - attached to logging messages. For instance, in a web service, - once the caller is authenticated the username of the caller could be - stored in a ThreadContext property. This property would then be automatically - logged as part of each subsequent logging message made from the same thread. -

    -
    -

    Proven architecture

    -
    -

    - log4net is based on the highly successful log4j logging library, - in development since 1996. This popular and proven architecture has - so far been ported to 12 languages. -

    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/framework-support.html b/doc/release/framework-support.html deleted file mode 100644 index 91d86482..00000000 --- a/doc/release/framework-support.html +++ /dev/null @@ -1,773 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Supported Frameworks - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Supported Frameworks

    -
    -

    Contents

    - -

    Summary of .NET frameworks supported by log4net

    -
    -

    - log4net is built on a number of different frameworks. Each new version of the frameworks add - new features. To take advantage of these new features we must build log4net using the - appropriate framework. We also maintain builds compatible with older versions of the frameworks. -

    -

    - It is important to remember that the .NET frameworks support backward compatibility, that is - a new version of the framework will run binary assemblies that were targeted to previous versions - of the framework. -

    -

    - While the number of different builds available may seem confusing, you only need to select the - nearest build for your platform that is equal to or earlier than your chosen deployment framework. - If you intend to deploy your application on the Microsoft .NET Framework 1.0 don't pick the - log4net build that is built against the Microsoft .NET Framework 1.1 because the .NET framework - does not guarantee forward compatibility only backward compatibility. -

    -

    - The lowest common denominator build is the CLI 1.0 Compatible build. This build is compatible with - the ECMA/ISO CLI 1.0 standard APIs and will run on all frameworks that support the standard. (Note - that the Microsoft .NET Compact Framework does not support this standard). Use this build if you - intend to deploy you application on both the Microsoft .NET Frameworks and the Mono frameworks. -

    -

    - log4net now builds on 6 frameworks: -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FrameworkWebsite
    Microsoft .NET Framework 1.0 (1.0.3705)http://msdn.microsoft.com/net
    Microsoft .NET Framework 1.1 (1.1.4322)http://msdn.microsoft.com/net
    Microsoft .NET Framework 2.0 (2.0.50727)http://msdn.microsoft.com/net
    Microsoft .NET Compact Framework 1.0http://msdn2.microsoft.com/en-us/netframework/aa497273.aspx
    Mono 1.2.3http://www.mono-project.com
    Microsoft Shared Source CLI 1.0http://msdn.microsoft.com/library/en-us/dndotnet/html/mssharsourcecli.asp
    CLI 1.0 Compatiblehttp://msdn.microsoft.com/net/ecma/
    -
    -

    - For each of these frameworks a log4net assembly targeting the framework is supplied. Although it's - perfectly possible to use the .NET Framework 1.0 version of log4net on the .NET Framework 1.1, having - an assembly that really targets a specific framework allows us to use features in that framework that - are not available in other frameworks or remove features from log4net that are not supported in a - specific framework. -

    -
    -

    Appenders

    -
    -

    - The appenders available to each framework depend on the functionality of the - framework and the platform it runs on: -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Appender.NET Framework 1.0.NET Framework 1.1.NET Framework 2.0.NET CF 1.0Mono 1.2Shared Source CLI 1.0CLI 1.0 Compatible
    AdoNetAppenderxxxxx - x
    AnsiColorTerminalAppenderxxxxxxx
    AspNetTraceAppenderxxx - x - x
    BufferingForwardingAppenderxxxxxxx
    ColoredConsoleAppenderxxx - - - -
    ConsoleAppenderxxxxxxx
    DebugAppenderxxxxxxx
    EventLogAppenderxxx - x - x
    FileAppenderxxxxxxx
    ForwardingAppenderxxxxxxx
    LocalSyslogAppenderxxx - x - x
    MemoryAppenderxxxxxxx
    NetSendAppenderxxx - - - -
    OutputDebugStringAppenderxxxx - - -
    RemoteSyslogAppenderxxxxxxx
    RemotingAppenderxxx - xxx
    RollingFileAppenderxxxxxxx
    SmtpAppenderxxx - x - x
    SmtpPickupDirAppenderxxxxxxx
    TelnetAppenderxxxxxxx
    TraceAppenderxxxxxxx
    UdpAppenderxxxxxxx
    -
    -
    -

    Framework Specific Notes

    -
    -

    Microsoft .NET Framework 1.0 (1.0.3705)

    -
    -

    - none -

    -
    -

    Microsoft .NET Framework 1.1 (1.1.4322)

    -
    -

    - none -

    -
    -

    Microsoft .NET Framework 2.0 (2.0.50727)

    -
    -

    - none -

    -
    -

    Microsoft .NET Compact Framework 1.0

    -
    -
      -
    • -

      Assembly attributes

      -

      - The .NET Compact Framework 1.0 does not support retrieving assembly level - attributes, therefore all log4net configuration attributes were removed from - the .NET Compact Framework 1.0 version of log4net. -

      -

      - For Smart-device applications, the log4net system can be configured by passing - the location of the log4net configuration file to the - log4net.Config.XmlConfigurator.Configure(FileInfo) - method in the entry point of the application. -

      -

      For example:

      -

      -

      -namespace TestApp
      -{
      -    using System.IO;
      -
      -    public class EntryPoint
      -    {
      -        /// <summary>
      -        /// Application entry point.
      -        /// </summary>
      -        public static void Main() 
      -        {
      -            // Uncomment the next line to enable log4net internal debugging
      -            // log4net.Util.LogLog.InternalDebugging = true;
      -
      -            // This will instruct log4net to look for a configuration file
      -            // called config.log4net in the root directory of the device
      -            log4net.Config.XmlConfigurator.Configure(new FileInfo(@"\config.log4net"));
      -
      -            ...
      -            
      -            // This will shutdown the log4net system
      -            log4net.LogManager.Shutdown();
      -        }
      -    }
      -}                        
      -                            
      -
    • -
    • -

      Notification events

      -

      - The .NET Compact Framework 1.0 does not support notification events during the - application shutdown, therefore log4net cannot automatically hook the - application shutdown notification. -

      -

      - Applications will need to programmatically shutdown the log4net system during - the application's shutdown using the - log4net.LogManager.Shutdown() - method in order to prevent losing logging events. - See the code above for an example. -

      -
    • -
    • -

      FileSystemWatcher

      -

      - The .NET Compact Framework 1.0 does not support the - System.IO.FileSystemWatcher - class. As a result, the - XmlConfiguratorAttribute.Watch - property and the - XmlConfigurator.ConfigureAndWatch - methods are not available. Watching changes to the log4net configuration - file is not supported on the .NET Compact Framework 1.0. -

      -
    • -
    • -

      UserName

      -

      - The .NET Compact Framework 1.0 does not support the - System.Security.Principal.WindowsIdentity class. - This is used to capture the current thread's user identity. Therefore - the LoggingEvent.UserName property will return the value - "NOT AVAILABLE". -

      -
    • -
    • -

      Identity

      -

      - The .NET Compact Framework 1.0 does not support the - System.Security.Principal.IPrincipal interface. - This is used to capture the current thread's user identity. Therefore - the LoggingEvent.Identity property will return the value - "NOT AVAILABLE". -

      -
    • -
    • -

      Environment variables

      -

      - The .NET Compact Framework 1.0 does not support retrieving environment - variables, therefore it's not possible to substitute environment variables in - parameter values when using the .NET Compact Framework 1.0 version of log4net. -

      -
    • -
    • -

      Serialization

      -

      - The .NET Compact Framework 1.0 does not support serialization, therefore none of - the log4net classes in the .NET Compact Framework 1.0 version are serializable. -

      -
    • -
    • -

      LoggingEvent.Domain

      -

      - The .NET Compact Framework 1.0 does not support AppDomain functionality. The - friendly name for the current AppDomain is stored in the LoggingEvent.Domain - property and is accessed using the %a pattern of the - PatternLayout. On the .NET Compact Framework 1.0 this - value is generated by taking the file name for the application's primary module. -

      -
    • -
    -
    -

    Mono

    -
    -

    - There are 2 separate builds of log4net for mono; Mono 1.0, built using the C# compiler in a mode - which is compatible with the CLI 1.0 language specification, and; Mono 2.0, built using the .NET - 2.0 extensions to the C# language. -

    -

    Mono 1.0

    -
    -

    - none -

    -
    -

    Mono 2.0

    -
    -

    - none -

    -
    -
    -

    Microsoft Shared Source CLI 1.0

    -
    -
      -
    • -

      FileSystemWatcher

      -

      - SSCLI 1.0 does not support the - System.IO.FileSystemWatcher - class. As a result, the - XmlConfiguratorAttribute.Watch - property and the - XmlConfigurator.ConfigureAndWatch - methods are not available. Watching changes to the log4net configuration - file is not supported on SSCLI 1.0. -

      -
    • -
    • -

      UserName

      -

      - SSCLI 1.0 does not support the - System.Security.Principal.WindowsIdentity class. - This is used to capture the current thread's user identity. Therefore - the LoggingEvent.UserName property will return the value - "NOT AVAILABLE". -

      -
    • -
    • -

      Identity

      -

      - SSCLI 1.0 does not support the - System.Security.Principal.IPrincipal interface. - This is used to capture the current thread's user identity. Therefore - the LoggingEvent.Identity property will return the value - "NOT AVAILABLE". -

      -
    • -
    -
    -

    CLI 1.0 Compatible

    -
    -

    - This build of log4net is designed to run on any ECMA CLI 1.0 compatible runtime. - The assembly does not support any platform specific features. The build includes - the common subset of functionality found in the .NET 1.0 and Mono 1.0 builds. - The output assembly is built using the Microsoft .NET 1.0 compiler and library. -

    -

    - The log4net CLI 1.0 assembly is runtime compatible with the following frameworks: -

    -
      -
    • Microsoft .NET Framework 1.0 (and higher)
    • -
    • Mono 1.0 (and higher)
    • -
    -

    - Only a Release build is generated for this configuration because the assembly - debugging information has not been standardized. -

    -
    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/howto/chainsaw.html b/doc/release/howto/chainsaw.html deleted file mode 100644 index a6eef08e..00000000 --- a/doc/release/howto/chainsaw.html +++ /dev/null @@ -1,276 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: How To view logging events using Apache log4j Chainsaw - - - - - - - - - - - - - - - - - -
    - - - - -

    How To view logging events using Apache log4j Chainsaw

    -
    -

    Contents

    - -

    - Apache log4j includes Chainsaw - a graphical log viewer. -

    -

    - Chainsaw can either receive and display log events in realtime over - the network, or it can load a previously created log file. -

    -

    - Before Chainsaw can display data, one or more receivers must be setup. - This is usually done by specifying an xml config file when the program - first starts up.
    - Save one or more of the sample xml config files to your local system and - load them when Chainsaw starts. -

    -

    Logging via UDP

    -
    -

    - log4net can be configured to log messages via UDP in such a way that Chainsaw - can receive and display them. -

    -

    log4net UDP Configuration

    -
    -

    - Configure log4net to use a UdpAppender with the following config snippet: -

    - -
    -<appender name="UdpAppender" type="log4net.Appender.UdpAppender">
    -    <remoteAddress value="127.0.0.1" />
    -    <remotePort value="8080" />
    -    <layout type="log4net.Layout.XmlLayoutSchemaLog4j">
    -        <locationInfo value="true" />
    -    </layout>
    -</appender>
    - -
    -

    Chainsaw UDP receiver Configuration

    -
    -

    - Chainsaw should be configured to start a UDPReceiver using the - following configuration document: -

    - -
    -<?xml version="1.0" encoding="UTF-8" ?>
    -<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> 
    -<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">    
    -    <plugin name="UDPReceiver" class="org.apache.log4j.net.UDPReceiver">
    -        <param name="Port" value="8080" />
    -    </plugin>    
    -</log4j:configuration>
    - -
    -
    -

    Logging to XML file

    -
    -

    - Chainsaw can also load an XML log file if it is formatted according - to the log4j schema. Use the following log4net config to output - to file using the log4j schema: -

    - -
    -<appender name="FileAppender" type="log4net.Appender.FileAppender">
    -    <file value="log-file.txt" />
    -    <appendToFile value="true" />
    -    <layout type="log4net.Layout.XmlLayoutSchemaLog4j">
    -        <locationInfo value="true" />
    -    </layout>
    -</appender>
    - -

    - To load the file into Chainsaw drag the file into the Chainsaw - app and drop it on the tab labeled Drag & Drop log files here. -

    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/howto/index.html b/doc/release/howto/index.html deleted file mode 100644 index 6ac5c06e..00000000 --- a/doc/release/howto/index.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: How Tos - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net How Tos

    -
    -

    - Below are presented, in no particular order, a series of documents - on how to get stuff done. -

    -

    - New documents can be contributed via the issue tracking system. - See the Contributing page for - details. -

    - -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/manual/configuration.html b/doc/release/manual/configuration.html deleted file mode 100644 index 1a82748d..00000000 --- a/doc/release/manual/configuration.html +++ /dev/null @@ -1,1437 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net Manual: Configuration - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Manual - Configuration

    -
    -

    Contents

    - -

    Configuration

    -
    -

    - Inserting log requests into the application code requires a fair amount of - planning and effort. Observation shows that approximately 4 percent of code is - dedicated to logging. Consequently, even moderately sized applications will - have thousands of logging statements embedded within their code. Given their - number, it becomes imperative to manage these log statements without the need - to modify them manually. -

    -

    - The log4net environment is fully configurable programmatically. However, it is - far more flexible to configure log4net using configuration files. Currently, - configuration files are written in XML. -

    -

    - Let us give a taste of how this is done with the help of an imaginary - application - MyApp - that uses log4net. -

    -
    -using Com.Foo;
    -
    -// Import log4net classes.
    -using log4net;
    -using log4net.Config;
    -
    -public class MyApp 
    -{
    -    // Define a static logger variable so that it references the
    -    // Logger instance named "MyApp".
    -    private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
    -
    -    static void Main(string[] args) 
    -    {
    -        // Set up a simple configuration that logs on the console.
    -        BasicConfigurator.Configure();
    -
    -        log.Info("Entering application.");
    -        Bar bar = new Bar();
    -        bar.DoIt();
    -        log.Info("Exiting application.");
    -    }
    -}
    -

    - MyApp - begins by importing log4net related classes. It then defines a static logger - variable with the name - MyApp - which happens to be the fully qualified name of the class. -

    -

    - MyApp - uses the following - Bar - class: -

    -
    -// Import log4net classes.
    -using log4net;
    -
    -namespace Com.Foo
    -{
    -    public class Bar 
    -    {
    -        private static readonly ILog log = LogManager.GetLogger(typeof(Bar));
    -
    -        public void DoIt()
    -        {
    -            log.Debug("Did it again!");
    -        }
    -    }
    -}
    -

    - The invocation of the - BasicConfigurator.Configure() - method creates a rather simple log4net setup. This method is hardwired to add - to the root logger a - ConsoleAppender. The output will be formatted using a - PatternLayout - set to the pattern - "%-4timestamp [%thread] %-5level %logger %ndc - %message%newline". -

    -

    - Note that by default, the root logger is assigned to - Level.DEBUG. -

    -

    - The output of MyApp is: -

    - -
    -0    [main] INFO  MyApp  - Entering application.
    -36   [main] DEBUG Com.Foo.Bar  - Did it again!
    -51   [main] INFO  MyApp  - Exiting application.
    - -

    - As a side note, let me mention that in log4net child loggers link only to their - existing ancestors. In particular, the logger named - Com.Foo.Bar - is linked directly to the - root - logger, thereby circumventing the unused - Com - or - Com.Foo - loggers. This significantly increases performance and reduces log4net's memory - footprint. -

    -

    - The - MyApp - class configures log4net by invoking - BasicConfigurator.Configure() - method. Other classes only need to import the - log4net - namespace, retrieve the loggers they wish to use, and log away. -

    -

    - The previous example always outputs the same log information. Fortunately, it - is easy to modify - MyApp - so that the log output can be controlled at run-time. Here is a slightly - modified version. -

    -
    -using Com.Foo;
    -
    -// Import log4net classes.
    -using log4net;
    -using log4net.Config;
    -
    -public class MyApp 
    -{
    -    private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
    -
    -    static void Main(string[] args) 
    -    {
    -        // BasicConfigurator replaced with XmlConfigurator.
    -        XmlConfigurator.Configure(new System.IO.FileInfo(args[0]));
    -
    -        log.Info("Entering application.");
    -        Bar bar = new Bar();
    -        bar.DoIt();
    -        log.Info("Exiting application.");
    -    }
    -}
    -

    - This version of - MyApp - instructs the - XmlConfigurator - to parse a configuration file and set up logging accordingly. The path to the - configuration file is specified on the command line. -

    -

    - Here is a sample configuration file that results in exactly same output as the - previous - BasicConfigurator - based example. -

    - -
    -<log4net>
    -    <!-- A1 is set to be a ConsoleAppender -->
    -    <appender name="A1" type="log4net.Appender.ConsoleAppender">
    -
    -        <!-- A1 uses PatternLayout -->
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline" />
    -        </layout>
    -    </appender>
    -    
    -    <!-- Set root logger level to DEBUG and its only appender to A1 -->
    -    <root>
    -        <level value="DEBUG" />
    -        <appender-ref ref="A1" />
    -    </root>
    -</log4net>
    - -

    - Suppose we are no longer interested in seeing the output of any component - belonging to the - Com.Foo - package. The following configuration file shows one possible way of achieving - this. -

    - -
    -<log4net>
    -    <!-- A1 is set to be a ConsoleAppender -->
    -    <appender name="A1" type="log4net.Appender.ConsoleAppender">
    -
    -        <!-- A1 uses PatternLayout -->
    -        <layout type="log4net.Layout.PatternLayout">
    -            <!-- Print the date in ISO 8601 format -->
    -            <conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
    -        </layout>
    -    </appender>
    -    
    -    <!-- Set root logger level to DEBUG and its only appender to A1 -->
    -    <root>
    -        <level value="DEBUG" />
    -        <appender-ref ref="A1" />
    -    </root>
    -    
    -    <!-- Print only messages of level WARN or above in the package Com.Foo -->
    -    <logger name="Com.Foo">
    -        <level value="WARN" />
    -    </logger>
    -</log4net>
    - -

    - The output of - MyApp - configured with this file is shown below. -

    - -
    -2000-09-07 14:07:41,508 [main] INFO  MyApp - Entering application.
    -2000-09-07 14:07:41,529 [main] INFO  MyApp - Exiting application.
    - -

    - As the logger - Com.Foo.Bar - does not have an assigned level, it inherits its level from - Com.Foo, which was set to WARN in the configuration - file. The log statement from the - Bar.DoIt - method has the level DEBUG, lower than the logger level WARN. Consequently, - DoIt() - method's log request is suppressed. -

    -

    - Here is another configuration file that uses multiple appenders. -

    - -
    -<log4net>
    -    <appender name="Console" type="log4net.Appender.ConsoleAppender">
    -        <layout type="log4net.Layout.PatternLayout">
    -            <!-- Pattern to output the caller's file name and line number -->
    -            <conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
    -        </layout>
    -    </appender>
    -    
    -    <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
    -        <file value="example.log" />
    -        <appendToFile value="true" />
    -        <maximumFileSize value="100KB" />
    -        <maxSizeRollBackups value="2" />
    -
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%level %thread %logger - %message%newline" />
    -        </layout>
    -    </appender>
    -    
    -    <root>
    -        <level value="DEBUG" />
    -        <appender-ref ref="Console" />
    -        <appender-ref ref="RollingFile" />
    -    </root>
    -</log4net>
    - -

    - Calling the enhanced MyApp with the this configuration file will output the - following on the console. -

    - -
    - INFO [main] (MyApp.cs:16) - Entering application.
    -DEBUG [main] (Bar.cs:12) - Doing it again!
    - INFO [main] (MyApp.cs:19) - Exiting application.
    - -

    - In addition, as the root logger has been allocated a second appender, output - will also be directed to the - example.log - file. This file will be rolled over when it reaches 100KB. When roll-over - occurs, the old version of - example.log - is automatically moved to - example.log.1. -

    -

    - Note that to obtain these different logging behaviors we did not need to - recompile code. We could just as easily have logged to an email address, - redirected all - Com.Foo - output to an NT Event logger, or forwarded logging events to a remote log4net - server, which would log according to local server policy. -

    -

    - For more examples of configuring appenders using the XmlConfigurator - see the Example Appender Configuration - document. -

    -

    Configuration Attributes

    -
    -

    - The log4net configuration can be configured using assembly-level attributes rather than - specified programmatically. -

    -
      -
    • - XmlConfiguratorAttribute -

      - The log4net.Config.XmlConfiguratorAttribute Allows the - XmlConfigurator to be configured using the following properties: -

      -
        -
      • - ConfigFile -

        - If specified, this is the filename of the configuration file to use with the - XmlConfigurator. This file path is relative to the - application base directory (AppDomain.CurrentDomain.BaseDirectory). -

        -

        - This property cannot be used in conjunction with the - ConfigFileExtension property. -

        -
      • -
      • - ConfigFileExtension -

        - If specified, this is the extension for the configuration file. The assembly - file name is used as the base name with the this extension appended. For example - if the assembly is loaded from the a file TestApp.exe - and the ConfigFileExtension property is set to - log4net then the configuration file name is - TestApp.exe.log4net. This is equivalent to setting the - ConfigFile property to TestApp.exe.log4net. -

        -

        - The path to the configuration file is build by using the application base - directory (AppDomain.CurrentDomain.BaseDirectory), - the assembly file name and the configuration file extension. -

        -

        - This property cannot be used in conjunction with the - ConfigFile property. -

        -
      • -
      • - Watch -

        - If this flag is specified and set to true - then the framework will watch the configuration file and will reload the config - each time the file is modified. -

        -
      • -
      -

      - If neither of the ConfigFile or ConfigFileExtension - properties are specified, the application configuration file (e.g. TestApp.exe.config) - will be used as the log4net configuration file. -

      -

      - Example usage: -

      -
      -// Configure log4net using the .config file
      -[assembly: log4net.Config.XmlConfigurator(Watch=true)]
      -// This will cause log4net to look for a configuration file
      -// called TestApp.exe.config in the application base
      -// directory (i.e. the directory containing TestApp.exe)
      -// The config file will be watched for changes.
      -                            
      -
      -// Configure log4net using the .log4net file
      -[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net",Watch=true)]
      -// This will cause log4net to look for a configuration file
      -// called TestApp.exe.log4net in the application base
      -// directory (i.e. the directory containing TestApp.exe)
      -// The config file will be watched for changes.
      -                            
      -

      - This attribute may only be used once per assembly. -

      -
    • -
    -

    - Using attributes can be a clearer method for defining where the application's - configuration will be loaded from. However it is worth noting that attributes - are purely passive. They are information only. Therefore if you use configuration - attributes you must invoke log4net to allow it to read the attributes. A simple - call to LogManager.GetLogger will cause the attributes - on the calling assembly to be read and processed. Therefore it is imperative - to make a logging call as early as possible during the application start-up, and - certainly before any external assemblies have been loaded and invoked. -

    -
    -

    Configuration Files

    -
    -

    - Typically the log4net configuration is specified using a file. This file can - be read in one of two ways: -

    -
      -
    • Using the .NET System.Configuration API
    • -
    • Reading the file contents directly
    • -
    -

    .config Files

    -
    -

    - The System.Configuration API is only available if the - configuration data is in the application's config file; the file named - MyApp.exe.config or Web.config. Because the System.Configuration - API does not support reloading of the config file the configuration settings - cannot be watched using the log4net.Config.XmlConfigurator.ConfigureAndWatch - methods. The main advantage of using the System.Configuration - APIs to read the configuration data is that it requires less permissions than accessing - the configuration file directly. -

    -

    - The only way to configure an application using the System.Configuration - APIs is to call the log4net.Config.XmlConfigurator.Configure() method or - the log4net.Config.XmlConfigurator.Configure(ILoggerRepository) method. -

    -

    - In order to embed the configuration data in the .config file the section name must be - identified to the .NET config file parser using a configSections element. - The section must specify the log4net.Config.Log4NetConfigurationSectionHandler - that will be used to parse the config section. This type must be fully assembly qualified - because it is being loaded by the .NET config file parser not by log4net. The correct - assembly name for the log4net assembly must be specified. - The following is a simple example configuration file that specifies the correct - section handler to use for the log4net section. -

    - -
    -<?xml version="1.0" encoding="utf-8" ?>
    -<configuration>
    -    <configSections>
    -        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    -    </configSections>
    -    <log4net>
    -        <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
    -            <layout type="log4net.Layout.PatternLayout">
    -                <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
    -            </layout>
    -        </appender>
    -        <root>
    -            <level value="INFO" />
    -            <appender-ref ref="ConsoleAppender" />
    -        </root>
    -    </log4net>
    -</configuration>
    - -

    - In the above example the log4net assembly is specified. - This assembly must be located where the .NET runtime can find it. For example it could - be located in the same directory as the application. If the log4net assembly is stored in - the GAC then the fully qualified assembly name must be specified including the culture, - version and public key. -

    -

    - When using the .config file to specify the configuration the section name and - XML element name must be log4net. -

    -
    -

    Reading Files Directly

    -
    -

    - The XmlConfigurator can directly read any XML file and use it to configure log4net. - This includes the application's .config file; the file named MyApp.exe.config - or Web.config. The only reason not to read the configuration file directly is if the - application does not have sufficient permissions to read the file, then the configuration - must be loaded using the .NET configuration APIs (see above). -

    -

    - The file to read the configuration from can be specified using any of - the log4net.Config.XmlConfigurator methods that - accept a System.IO.FileInfo object. Because the - file system can be monitored for file change notifications the - ConfigureAndWatch methods can be used to monitor - the configuration file for modifications and automatically reconfigure log4net. -

    -

    - Additionally the log4net.Config.XmlConfiguratorAttribute - can be used to specify the file to read the configuration from. -

    -

    - The configuration is read from the log4net element - in the file. Only one log4net element can be specified - in the file but it may be located anywhere in the XML hierarchy. For example it - may be the root element: -

    - -
    -<?xml version="1.0" encoding="utf-8" ?>
    -<log4net>
    -    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
    -        </layout>
    -    </appender>
    -    <root>
    -        <level value="INFO" />
    -        <appender-ref ref="ConsoleAppender" />
    -    </root>
    -</log4net>
    - -

    - Or it may be nested within other elements: -

    - -
    -<?xml version="1.0" encoding="utf-8" ?>
    -<configuration>
    -    <configSections>
    -        <section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
    -    </configSections>
    -    <log4net>
    -        <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
    -            <layout type="log4net.Layout.PatternLayout">
    -                <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
    -            </layout>
    -        </appender>
    -        <root>
    -            <level value="INFO" />
    -            <appender-ref ref="ConsoleAppender" />
    -        </root>
    -    </log4net>
    -</configuration>
    - -

    - The above example shows how the configuration data can be embedded - inside a .config file even though the file is being read directly - by log4net. An important note is that the .NET config file parser - will throw an exception if it finds an element that has not been - registered using the configSections element. - Therefore in the above example the log4net - section name is registered, but the type specified to handle the - section is System.Configuration.IgnoreSectionHandler. - This is a built-in class that indicates that another method for reading - the config section will be employed. -

    -
    -
    -

    Configuration Syntax

    -
    -

    - log4net includes a configuration reader that parses an XML DOM, the - log4net.Config.XmlConfigurator. This section defines the - syntax accepted by the configurator. -

    -

    - This is an example of a valid XML configuration. The root element - must be <log4net>. Note that this does not mean - that this element cannot be embedded in another XML document. See the section above - on Configuration Files for more information - on how to embed the XmlConfigurator XML in a configuration file. -

    - -
    -<log4net>
    -    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
    -        <layout type="log4net.Layout.PatternLayout">
    -            <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
    -        </layout>
    -    </appender>
    -    <root>
    -        <level value="INFO" />
    -        <appender-ref ref="ConsoleAppender" />
    -    </root>
    -</log4net>
    - -

    - The <log4net> element supports the following attributes: -

    -
    - - - - - - - - - - - - - - - - - - - - - -
    AttributeDescription
    debug - Optional attribute. Value must be either true or false. - The default value is false. Set this attribute to true - to enable internal log4net debugging for this configuration. -
    update - Optional attribute. Value must be either Merge or Overwrite. - The default value is Merge. Set this attribute to Overwrite - to reset the configuration of the repository being configured before applying this configuration. -
    threshold - Optional attribute. Value must be the name of a level registered on the repository. - The default value is ALL. Set this attribute to limit the messages - that are logged across the whole repository, regardless of the logger that the message is logged to. -
    -
    -

    - The <log4net> element supports the following child elements: -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ElementDescription
    appender - Zero or more elements allowed. Defines an appender. -
    logger - Zero or more elements allowed. Defines the configuration of a logger. -
    renderer - Zero or more elements allowed. Defines an object renderer. -
    root - Optional element, maximum of one allowed. Defines the configuration of the root logger. -
    param - Zero or more elements allowed. Repository specific parameters -
    -
    -

    Appenders

    -
    -

    - Appenders may only be defined as child elements of the <log4net> - element. Each appender must be uniquely named. The implementing type for the appender must be specified. -

    -

    - This example shows an appender of type log4net.Appender.ConsoleAppender being - defined. The appender will be known as ConsoleAppender. -

    - -
    -<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
    -    <layout type="log4net.Layout.PatternLayout">
    -        <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
    -    </layout>
    -</appender>
    - -

    - The <appender> element supports the following attributes: -

    -
    - - - - - - - - - - - - - - - - - -
    AttributeDescription
    name - Required attribute. Value must be a string name for this appender. The name must be unique - among all the appenders defined in this configuration file. This name is used by the - <appender-ref> element of a Logger to reference an appender. -
    type - Required attribute. Value must be the type name for this appender. If the appender is - not defined in the log4net assembly this type name must be fully assembly qualified. -
    -
    -

    - The <appender> element supports the following child elements: -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ElementDescription
    appender-ref - Zero or more elements allowed. Allows the appender to reference other appenders. - Not supported by all appenders. -
    filter - Zero or more elements allowed. Defines the filters used by this appender. -
    layout - Optional element, maximum of one allowed. Defines the layout used by this appender. -
    param - Zero or more elements allowed. Appender specific parameters. -
    -
    -

    - For examples of configuring appenders see the - Example Appender Configuration - document. -

    -
    Filters
    -
    -

    - Filters elements may only be defined as children of <appender> elements. -

    -

    - The <filter> element supports the following attributes: -

    -
    - - - - - - - - - - - - - -
    AttributeDescription
    type - Required attribute. Value must be the type name for this filter. If the filter is - not defined in the log4net assembly this type name must be fully assembly qualified. -
    -
    -

    - The <filter> element supports the following child elements: -

    -
    - - - - - - - - - - - - - -
    ElementDescription
    param - Zero or more elements allowed. Filter specific parameters. -
    -
    -

    - Filters form a chain that the event has to pass through. Any filter along the way can accept the event - and stop processing, deny the event and stop processing, or allow the event on to the next filter. - If the event gets to the end of the filter chain without being denied it is implicitly accepted and will be logged. -

    - -
    -<filter type="log4net.Filter.LevelRangeFilter">
    -    <levelMin value="INFO" />
    -    <levelMax value="FATAL" />
    -</filter>
    - -

    - This filter will deny events that have a level that is lower than INFO - or higher than FATAL. - All events between INFO and FATAL will be logged. -

    -

    - If we want to only allow messages through that have a specific substring (e.g. 'database') - then we need to specify the following filters: -

    - -
    -<filter type="log4net.Filter.StringMatchFilter">
    -    <stringToMatch value="database" />
    -</filter>
    -<filter type="log4net.Filter.DenyAllFilter" />
    - -

    - The first filter will look for the substring 'database' in the message text of the event. - If the text is found the filter will accept the message and filter processing will stop, - the message will be logged. If the substring is not found the event will be passed to - the next filter to process. If there is no next filter the event would be implicitly - accepted and would be logged. But because we don't want the non matching events to be - logged we need to use a log4net.Filter.DenyAllFilter - that will just deny all events that reach it. This filter is only useful at the end of the filter chain. -

    -

    - If we want to allow events that have either 'database' or 'ldap' in the message text we can use the following filters: -

    - -
    -<filter type="log4net.Filter.StringMatchFilter">
    -    <stringToMatch value="database"/>
    -</filter>
    -<filter type="log4net.Filter.StringMatchFilter">
    -    <stringToMatch value="ldap"/>
    -</filter>
    -<filter type="log4net.Filter.DenyAllFilter" />
    - -
    -
    Layouts
    -
    -

    - Layout elements may only be defined as children of <appender> elements. -

    -

    - The <layout> element supports the following attributes: -

    -
    - - - - - - - - - - - - - -
    AttributeDescription
    type - Required attribute. Value must be the type name for this layout. If the layout is - not defined in the log4net assembly this type name must be fully assembly qualified. -
    -
    -

    - The <layout> element supports the following child elements: -

    -
    - - - - - - - - - - - - - -
    ElementDescription
    param - Zero or more elements allowed. Layout specific parameters. -
    -
    -

    - This example shows how to configure a layout that uses the log4net.Layout.PatternLayout. -

    - -
    -<layout type="log4net.Layout.PatternLayout">
    -    <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
    -</layout>
    - -
    -
    -

    Root Logger

    -
    -

    - Only one root logger element may only be defined and it must be a child of <log4net> element. - The root logger is the root of the logger hierarchy. All loggers ultimately inherit from this logger. -

    -

    - An example root logger: -

    - -
    -<root>
    -    <level value="INFO" />
    -    <appender-ref ref="ConsoleAppender" />
    -</root>
    - -

    - The <root> element supports no attributes. -

    -

    - The <root> element supports the following child elements: -

    -
    - - - - - - - - - - - - - - - - - - - - - -
    ElementDescription
    appender-ref - Zero or more elements allowed. Allows the logger to reference appenders by name. -
    level - Optional element, maximum of one allowed. Defines the logging level for this logger. - This logger will only accept event that are at this level or above. -
    param - Zero or more elements allowed. Logger specific parameters. -
    -
    -
    -

    Loggers

    -
    -

    - Logger elements may only be defined as children of the <log4net> element. -

    -

    - An example logger: -

    - -
    -<logger name="LoggerName">
    -    <level value="DEBUG" />
    -    <appender-ref ref="ConsoleAppender" />
    -</logger>
    - -

    - The <logger> element supports the following attributes. -

    -
    - - - - - - - - - - - - - - - - - -
    AttributeDescription
    name - Required attribute. Value must be the name of the logger. -
    additivity - Optional attribute. Value may be either true or false. - The default value is true. Set this attribute to false - to prevent this logger from inheriting the appenders defined on parent loggers. -
    -
    -

    - The <logger> element supports the following child elements: -

    -
    - - - - - - - - - - - - - - - - - - - - - -
    ElementDescription
    appender-ref - Zero or more elements allowed. Allows the logger to reference appenders by name. -
    level - Optional element, maximum of one allowed. Defines the logging level for this logger. - This logger will only accept event that are at this level or above. -
    param - Zero or more elements allowed. Logger specific parameters. -
    -
    -
    -

    Renderers

    -
    -

    - Renderer elements may only be defined as children of the <log4net> element. -

    -

    - An example renderer: -

    - -
    -<renderer renderingClass="MyClass.MyRenderer" renderedClass="MyClass.MyFunkyObject" />
    - -

    - The <renderer> element supports the following attributes. -

    -
    - - - - - - - - - - - - - - - - - -
    AttributeDescription
    renderingClass - Required attribute. Value must be the type name for this renderer. If the type is - not defined in the log4net assembly this type name must be fully assembly qualified. - This is the type of the object that will take responsibility for rendering the - renderedClass. -
    renderedClass - Required attribute. Value must be the type name for the target type for this renderer. If the type is - not defined in the log4net assembly this type name must be fully assembly qualified. - This is the name of the type that this renderer will render. -
    -
    -

    - The <renderer> element supports no child elements. -

    -
    -

    Parameters

    -
    -

    - Parameter elements may be children of many elements. See the specific elements above for details. -

    -

    - An example param: -

    - -
    -<param name="ConversionPattern" value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
    - -

    - The <param> element supports the following attributes. -

    -
    - - - - - - - - - - - - - - - - - - - - - -
    AttributeDescription
    name - Required attribute. Value must be the name of the parameter to set on the parent object. -
    value - Optional attribute. One of value or type attributes must be specified. - The value of this attribute is a string that can be converted to the value of the - parameter. -
    type - Optional attribute. One of value or type attributes must be specified. - The value of this attribute is a type name to create and set as the value of the - parameter. If the type is not defined in the log4net assembly this type name must - be fully assembly qualified. -
    -
    -

    - The <param> element supports the following child elements: -

    -
    - - - - - - - - - - - - - -
    ElementDescription
    param - Zero or more elements allowed. Parameter specific parameters. -
    -
    -

    - An example param that uses nested param elements: -

    - -
    -<param name="evaluator" type="log4net.spi.LevelEvaluator">
    -    <param name="Threshold" value="WARN"/>
    -<param>
    - -
    Extension Parameters
    -
    -

    - Configuration parameters map directly to writable properties on an object. - The properties available depend on the actual type of the object being - configured. The log4net SDK documentation contains the API reference for - all the components included in the log4net assembly. -

    -

    - For 3rd party components please see their relevant API reference for - details of the properties available. -

    -
    -
    Compact Parameter Syntax
    -
    -

    - All parameters may alternately be specified using the parameter name as the element name - rather than using the param element and name attribute. -

    -

    - For example a param: -

    - -
    -<param name="evaluator" type="log4net.spi.LevelEvaluator">
    -    <param name="Threshold" value="WARN"/>
    -<param>
    - -

    - may be written as: -

    - -
    -<evaluator type="log4net.spi.LevelEvaluator">
    -    <threshold value="WARN"/>
    -<evaluator>
    - -
    -
    -
    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/manual/contexts.html b/doc/release/manual/contexts.html deleted file mode 100644 index afacb06c..00000000 --- a/doc/release/manual/contexts.html +++ /dev/null @@ -1,420 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net Manual: Contexts - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Manual - Contexts

    -
    -

    Contents

    - -

    - Most real-world systems have to deal with multiple clients simultaneously. In a - typical multithreaded implementation of such a system, different threads will - handle different clients. Logging is especially well suited to trace and debug - complex distributed applications. An approach to differentiate the - logging output of one client from another is to instantiate a new separate - logger for each client. However this promotes the proliferation of loggers and - increases the management overhead of logging. -

    -

    - A lighter technique is to uniquely stamp each log request initiated from the - same client interaction. -

    -

    - Log4net supports different types of contextual logging and contexts with different scopes. -

    -

    Scopes

    -
    -

    - Contextual data can be set in different scopes. These contexts have progressively narrower visibility. - In the logging event itself the values from all of the contexts are combined together such that - values specified in a lower scoped context hide values from a higher context. -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScopeTypeDescription
    Globallog4net.GlobalContext - The global context is shared by all threads in the current AppDomain. - This context is thread safe for use by multiple threads concurrently. -
    Threadlog4net.ThreadContext - The thread context is visible only to the current managed thread. -
    Logical Threadlog4net.ThreadLogicalContext - The logical thread context is visible to a logical thread. Logical - threads can jump from one managed thread to another. For more details - see the .NET API System.Runtime.Remoting.Messaging.CallContext. -
    Eventlog4net.Core.LoggingEvent - Each event captures the current contextual state at the time the event - is generated. Contextual data can be set on the event itself. This context - is only visible to the code generating the event itself. -
    -
    -
    -

    Context Properties

    -
    -

    - The log4net contexts store properties, i.e. name value pairs. The name is a string - the value is any object. A property can be set as follows: -

    - -
    -log4net.GlobalContext.Properties["name"] = value;
    -
    - -

    - If properties with the same name are set in more than one context scope then - the value in the narrowest scope (lower down in the list above) will hide the - other values. -

    -

    - The property values are stored as objects within the LoggingEvent. - The PatternLayout supports rendering the value of a named - property using the %property{name} syntax. The value is - converted to a string by passing it to the log4net.ObjectRenderer.RendererMap - which will locate any custom renderer for the value type. The default behavior for - custom types is to call the object's ToString() method. -

    -

    Active Property Values

    -
    -

    - An active property value is one who's value changes over time. -

    -

    - For example, imagine a custom type that implemented the - ToString() method to return the - number of bytes allocated by the runtime garbage collector. -

    - -
    -public class GCAllocatedBytesHelper
    -{
    -    public override string ToString()
    -    {
    -        return GC.GetTotalMemory(true).ToString();
    -    }
    -}
    - -

    - An instance of this type can be added to the log4net.GlobalContext - during application startup: -

    - -
    -log4net.GlobalContext.Properties["GCAllocatedBytes"] = new GCAllocatedBytesHelper();
    -
    - -

    - Once this property is set in the context all subsequent logging events will have a property - called GCAllocatedBytes. The value of the property will be an instance of the - GCAllocatedBytesHelper type. When this value is rendered to a - string by calling the ToString method the current number of bytes - allocated by the garbage collector will be returned and included in the output. -

    -
    -
    -

    Context Stacks

    -
    -

    - Sometimes simple key value pairs are not the most convenient way of capturing contextual - information. A stack of information is a very convenient way of storing data especially - as our applications tend to be stack based. -

    -

    - The ThreadContext and LogicalThreadContext - also support storing contextual data in a stack. The stack is stored in context property, - therefore stacks have names and more than one stack can exist in the same context. A property - value set in a narrower context would override a stack with the same property name set in a - wider scoped context. -

    -

    - The stack supports Push and Pop methods. - As more contextual data is pushed onto the stack the stack grows. When the stack is rendered - all the data pushed onto the stack is output with the most recent data to the right hand - end of the string. -

    -

    - As the stack is just an object stored in the context properties it is also rendered - using the same PatternLayout syntax: %property{name}. - Where name is the name of the stack. -

    -

    - Calls the the stack's Push and Pop - methods must be matched up so that each push has a corresponding pop. The - Push method also returns an IDisposable - object that will perform the required pop operation when it is disposed. This allows - the C# using syntax to be used to automate the stack management. -

    - -
    -using(log4net.ThreadContext.Stacks["NDC"].Push("context"))
    -{
    -    log.Info("Message");
    -}
    -
    - -

    - The INFO level log has a stack stored in its NDC property. The top item in the - stack is the string context. - The using syntax ensures that the value context is popped off the stack - at the end of the block. -

    -

    - The using - syntax is recommended because it removes some work load from the developer and - reduces errors in matching up the Push and Pop calls, especially when exceptions - can occur. -

    -
    -

    Nested Diagnostic Contexts

    -
    -

    - The NDC (Nested Diagnostic Context) exists for compatibility - with older versions of log4net. This helper class implements a stack which is stored - in the thread context property named NDC. -

    -
    -

    Mapped Diagnostic Contexts

    -
    -

    - The MDC (MappedDiagnostic Context) exists for compatibility - with older versions of log4net. This helper class implements a properties map which is - mapped directly through to the thread context properties. -

    -
    -

    - To illustrate this point, let us take the example of a web service delivering - content to numerous clients. The web service can build the NDC at the very - beginning of the request before executing other code. The contextual - information can be the client's host name and other information inherent to the - request, typically information contained in cookies. Hence, even if the web - service is serving multiple clients simultaneously, the logs initiated by the - same code, i.e. belonging to the same logger, can still be distinguished - because each client request will have a different NDC stack. Contrast this with - the complexity of passing a freshly instantiated logger to all code exercised - during the client's request. -

    -

    - Nevertheless, some sophisticated applications, such as virtual hosting web - servers, must log differently depending on the virtual host context and also - depending on the software component issuing the request. Log4net supports - multiple logger repositories. This would allow each virtual host to possess its own copy - of the logger hierarchy. Configuring multiple logger hierarchies is beyond the - scope of this document. -

    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/manual/internals.html b/doc/release/manual/internals.html deleted file mode 100644 index 11d56cbd..00000000 --- a/doc/release/manual/internals.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net Manual: Internals - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Manual - Internals

    -
    -

    Contents

    - -

    Performance

    -
    -

    - One of the often-cited arguments against logging is its computational cost. - This is a legitimate concern as even moderately sized applications can generate - thousands of log requests. Much effort was spent measuring and tweaking logging - performance. Log4net claims to be fast and flexible: speed first, flexibility - second. -

    -

    - The user should be aware of the following performance issues. -

    -
      -
    1. - Logging performance when logging is turned off. -

      - When logging is turned off entirely or just for a set of levels, the cost of a - log request consists of a method invocation plus an integer comparison. -

      -

      - However, The method invocation involves the "hidden" cost of parameter - construction. -

      -

      - For example, for some logger - log, writing, -

      -
      -log.Debug("Entry number: " + i + " is " + entry[i].ToString());
      -

      - incurs the cost of constructing the message parameter, i.e. converting both - integer - i - and - entry[i] - to strings, and concatenating intermediate strings, regardless of whether the - message will be logged or not. This cost of parameter construction can be quite - high and it depends on the number and type of the parameters involved. -

      -

      - To avoid the parameter construction cost write: -

      -
      -if(log.IsDebugEnabled)
      -{
      -    log.Debug("Entry number: " + i + " is " + entry[i].ToString());
      -}
      -

      - This will not incur the cost of parameter construction if debugging is - disabled. On the other hand, if the logger is debug-enabled, it will incur - twice the cost of evaluating whether the logger is enabled or not: once in - IsDebugEnabled - and once in - Debug. This is an insignificant overhead because - evaluating a logger takes about 1% of the time it takes to actually log. -

      -

      - Certain users resort to pre-processing or compile-time techniques to compile - out all log statements. This leads to perfect performance efficiency with - respect to logging. However, since the resulting application binary does not - contain any log statements, logging cannot be turned on for that binary. In - many people's opinion this is a disproportionate price to pay in exchange for a - small performance gain. -

      -
    2. -
    3. - The performance of deciding whether to log or not to log when logging is - turned on. -

      - This is essentially the performance of walking the logger hierarchy. When - logging is turned on, log4net still needs to compare the level of the log - request with the level of the request logger. However, loggers may not have an - assigned level; they can inherit them from the logger hierarchy. Thus, before - inheriting a level, the logger may need to search its ancestors. -

      -

      - There has been a serious effort to make this hierarchy walk to be as fast as - possible. For example, child loggers link only to their existing ancestors. In - the - BasicConfigurator - example shown earlier, the logger named - Com.Foo.Bar - is linked directly to the root logger, thereby circumventing the nonexistent - Com - or - Com.Foo - loggers. This significantly improves the speed of the walk, especially in - "sparse" hierarchies. -

      -

      - The typical cost of walking the hierarchy is typically 3 times slower than when - logging is turned off entirely. -

      -
    4. -
    5. - Actually outputting log messages -

      - This is the cost of formatting the log output and sending it to its target - destination. Here again, a serious effort was made to make layouts (formatters) - perform as quickly as possible. The same is true for appenders. -

      -
    6. -
    -

    - Although log4net has many features, its first design goal was speed. Some - log4net components have been rewritten many times to improve performance. - Nevertheless, contributors frequently come up with new optimizations. You - should be pleased to know that when configured with the - SimpleLayout - performance tests have shown log4net to log within an order of magnitude of - System.Console.WriteLine. -

    -
    -

    Logging Event Flow

    -
    -

    - The following is the series of steps and checks that a messages goes through while being logged. - For the purposes of this example we will document an INFO level - message being logged on logger ConsoleApp.LoggingExample. This logger is configured - to use the log4net.Appender.ConsoleAppender. The repository used - in this example is a log4net.Repository.Hierarchy object. -

    -
      -
    1. -

      - The user logs a message using the ILog.Info method on the logger - obtained using a call to log4net.LogManager.GetLogger("ConsoleApp.LoggingExample"). - For example: log4net.LogManager.GetLogger("ConsoleApp.LoggingExample").Info("Application Start"); - The ILog interface is actually an extension to log4net that provides level - specific logging methods (i.e. Debug, Info, Warn, Error, and Fatal). -

      -
    2. -
    3. -

      - The message is then logged through to the ILogger.Log method on the - appropriate log4net.Repository.Hierarchy.Logger object. The - ILogger.Log method takes the Level to - log at as a parameter and therefore works for all levels. -

      -
    4. -
    5. -

      - The repository threshold level is compared to the message level to determine if the message - can be logged. If the message level is below the threshold level the message is not logged. - In this case the repository is a log4net.Repository.Hierarchy object. -

      -
    6. -
    7. -

      - The Logger level is compared to the message level to determine if the - message can be logged. Note that the Logger level is inherited from a - parent Logger if not specified explicitly for this Logger. - If the message level is below the Logger level the message is not logged. -

      -
    8. -
    9. -

      - A LoggingEvent instance is created to encapsulate the message being logged. -

      -
    10. -
    11. -

      - The list of appenders for the Logger is built. This includes appenders - attached to parent Loggers except where excluded by the - Logger.Additivity property. -

      -
    12. -
    13. -

      - The LoggingEvent object is passed to the - IAppender.DoAppend method for each appender. -

      -
    14. -
    -

    - For Each Appender that the LoggingEvent is delivered to the following - actions take place: -

    -
      -
    1. -

      - The appender threshold level is compared to the message level to determine if the message - can be logged. If the message level is below the threshold level the message is not logged. -

      -
    2. -
    3. -

      - If the appender has a filter chain the LoggingEvent is passed down the - filter chain which can decide if the message can be logged or not. -

      -
    4. -
    5. -

      - Next an appender specific check is performed. Usually this check will verify that all the - required properties are set for the appender (e.g. a Layout is set if required). -

      -
    6. -
    7. -

      - The LoggingEvent is passed to the appender specific - Append method. What happens now is specific to the appender. -

      -
    8. -
    -

    - The following actions take place in the ConsoleAppender.Append method: -

    -
      -
    1. -

      - The ConsoleAppender uses a Layout to - format the message as a string for display. -

      -
    2. -
    3. -

      - The Layout uses the LoggingEvent.RenderedMessage - property to get the string for the message object. This uses the registered - IObjectRenderer for the type of the message object. -

      -
    4. -
    5. -

      - The message text is displayed on the console using the Console.WriteLine method. -

      -
    6. -
    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/manual/introduction.html b/doc/release/manual/introduction.html deleted file mode 100644 index 0adc0e3e..00000000 --- a/doc/release/manual/introduction.html +++ /dev/null @@ -1,1210 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net Manual: Introduction - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Manual - Introduction

    -
    -

    Contents

    - -

    Overview

    -
    -

    - This document is based on Short introduction to log4j by Ceki Glc. -

    -

    - The log4net framework is based on log4j, see - http://logging.apache.org/log4j for more information on log4j. - The log4net framework, source code, binaries, documentation, examples and related - materials are published under the terms of the - Apache License, Version 2.0, - a copy of which has been included with this distribution in the LICENSE.txt file. -

    -

    - This document is an introduction to the log4net API, its unique features and - design rationale. Log4net is an open source project based on the work of many - authors. It allows the developer to control which log statements are output - with arbitrary granularity. It is fully configurable at runtime using external - configuration files. -

    -

    - Almost every large application includes its own logging or tracing API. - Inserting log statements into code is a low-tech method for debugging it. It - may also be the only way because debuggers are not always available or - applicable. This is usually the case for multithreaded applications and - distributed applications at large. -

    -

    - Once an application has been deployed it may not be possible to utilize - development and debugging tools. An administrator can use effective logging - systems to diagnose and fix many configuration issues. -

    -

    - Experience indicates that logging is an important component of the development - cycle. It offers several advantages. It provides precise context about the - execution of the application. Once inserted into the code, the generation of - logging output requires no human intervention. Moreover, log output can be - saved in persistent medium to be studied at a later time. In addition to its - use in the development cycle, a sufficiently rich logging package can also be - viewed as an auditing tool. -

    -

    - Logging does have its drawbacks. It can slow down an application. If too - verbose, it can cause scrolling blindness. To alleviate these concerns, log4net - is designed to be reliable, fast and extensible. Since logging is rarely the - main focus of an application, the log4net API strives to be simple to - understand and to use. -

    -
    -

    Frameworks

    -
    -

    - Log4net is available for several frameworks. For each supported framework an - assembly targeting that framework is built: -

    -
      -
    • Microsoft .NET Framework 1.0 (1.0.3705)
    • -
    • Microsoft .NET Framework 1.1 (1.1.4322)
    • -
    • Microsoft .NET Compact Framework 1.0
    • -
    • Microsoft .NET Compact Framework 2.0
    • -
    • Mono 1.0
    • -
    • Mono 2.0
    • -
    • Microsoft Shared Source CLI 1.0
    • -
    • CLI 1.0 Compatible
    • -
    -

    - Not all frameworks are created equal and some features have been excluded from - some of the builds. See the Framework Support - document for more information. -

    -
    -

    Loggers and Appenders

    -
    -

    - Log4net has three main components: loggers, appenders and layouts. - These three types of components work together to enable developers to log - messages according to message type and level, and to control at runtime how - these messages are formatted and where they are reported. These components are - helped by filters that control the actions of the appender and - object renderers that turn objects into strings. -

    -

    Logger hierarchy

    -
    -

    - The first and foremost advantage of any logging API over plain - System.Console.WriteLine - resides in its ability to disable certain log statements while allowing others - to print unhindered. This capability assumes that the logging space, that is, - the space of all possible logging statements, is categorized according to some - developer-chosen criteria. -

    -

    - Loggers are named entities. Logger names are case-sensitive and they follow the - following hierarchical naming rule: -

    -
    -
    Named Hierarchy
    -
    -

    - A logger is said to be an ancestor of another logger if its name - followed by a dot is a prefix of the descendant logger name. A logger is - said to be a parent of a child logger if there are no ancestors - between itself and the descendant logger. -

    -

    - The hierarchy works very much in the same way as the namespace and class - hierarchy in .NET. This is very convenient as we shall soon see. -

    -
    -
    -

    - For example, the logger named - "Foo.Bar" - is a parent of the logger named - "Foo.Bar.Baz". Similarly, - "System" - is a parent of - "System.Text" - and an ancestor of - "System.Text.StringBuilder". This naming scheme - should be familiar to most developers. -

    -

    - The root logger resides at the top of the logger hierarchy. It is exceptional - in three ways: -

    -
      -
    1. - It always exists
    2. -
    3. - It cannot be retrieved by name
    4. -
    5. - It always has an assigned level
    6. -
    -

    - Loggers are retrieved using the static method from the - log4net.LogManager - class. The - GetLogger - methods take the name of the desired logger as a parameter. They are listed - below: -

    - -
    -namespace log4net
    -{
    -    public class LogManager
    -    {
    -        public static ILog GetLogger(string name);
    -        public static ILog GetLogger(Type type);
    -    }
    -}
    - -

    - The - GetLogger - methods that takes a - Type - parameter uses the fully qualified type name as the name of the logger to - retrieve. -

    -

    - These - GetLogger - methods return an - ILog - interface. That is the representation of the Logger passed back to the - developer. The - ILog - interface is defined below: -

    - -
    -namespace log4net
    -{
    -    public interface ILog
    -    {
    -        /* Test if a level is enabled for logging */
    -        bool IsDebugEnabled { get; }
    -        bool IsInfoEnabled { get; }
    -        bool IsWarnEnabled { get; }
    -        bool IsErrorEnabled { get; }
    -        bool IsFatalEnabled { get; }
    -        
    -        /* Log a message object */
    -        void Debug(object message);
    -        void Info(object message);
    -        void Warn(object message);
    -        void Error(object message);
    -        void Fatal(object message);
    -        
    -        /* Log a message object and exception */
    -        void Debug(object message, Exception t);
    -        void Info(object message, Exception t);
    -        void Warn(object message, Exception t);
    -        void Error(object message, Exception t);
    -        void Fatal(object message, Exception t);
    -        
    -        /* Log a message string using the System.String.Format syntax */
    -        void DebugFormat(string format, params object[] args);
    -        void InfoFormat(string format, params object[] args);
    -        void WarnFormat(string format, params object[] args);
    -        void ErrorFormat(string format, params object[] args);
    -        void FatalFormat(string format, params object[] args);
    -        
    -        /* Log a message string using the System.String.Format syntax */
    -        void DebugFormat(IFormatProvider provider, string format, params object[] args);
    -        void InfoFormat(IFormatProvider provider, string format, params object[] args);
    -        void WarnFormat(IFormatProvider provider, string format, params object[] args);
    -        void ErrorFormat(IFormatProvider provider, string format, params object[] args);
    -        void FatalFormat(IFormatProvider provider, string format, params object[] args);
    -    }
    -}
    - -

    - Loggers may be assigned levels. Levels are instances of the - log4net.Core.Level - class. The following levels are defined in order of increasing priority: -

    -
      -
    • - ALL -
    • -
    • - DEBUG -
    • -
    • - INFO -
    • -
    • - WARN -
    • -
    • - ERROR -
    • -
    • - FATAL -
    • -
    • - OFF -
    • -
    -

    - If a given logger is not assigned a level, then it inherits one from its - closest ancestor with an assigned level. More formally: -

    -
    -
    Level Inheritance
    -
    -

    - The inherited level for a given logger X, is equal to the first - non-null level in the logger hierarchy, starting at X and proceeding - upwards in the hierarchy towards the root logger. -

    -
    -
    -

    - To ensure that all loggers can eventually inherit a level, the root logger - always has an assigned level. The default value for the root logger is - DEBUG. -

    -

    - Below are four tables with various assigned level values and the resulting - inherited levels according to the above rule. -

    -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Logger name - Assigned level - Inherited level
    rootProotProot
    XnoneProot
    X.YnoneProot
    X.Y.ZnoneProot
    -
    -

    - In Example 1 above, only the root logger is assigned a level. This level - value, - Proot, is inherited by the other loggers - X, - X.Y - and - X.Y.Z. -

    -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Logger name - Assigned level - Inherited level
    rootProotProot
    XPxPx
    X.YPxyPxy
    X.Y.ZPxyzPxyz
    -
    -

    - In Example 2 above, all loggers have an assigned level value. There is - no need for level inheritance. -

    -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Logger name - Assigned level - Inherited level
    rootProotProot
    XPxPx
    X.YnonePx
    X.Y.ZPxyzPxyz
    -
    -

    - In Example 3 above, the loggers - root, - X - and - X.Y.Z - are assigned the levels - Proot, - Px - and - Pxyz - respectively. The logger - X.Y - inherits its level value from its parent - X. -

    -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Logger name - Assigned level - Inherited level
    rootProotProot
    XPxPx
    X.YnonePx
    X.Y.ZnonePx
    -
    -

    - In Example 4 above, the loggers root and - X - and are assigned the levels - Proot - and - Px - respectively. The loggers - X.Y - and - X.Y.Z - inherits their level value from their nearest parent - X - having an assigned level. -

    -

    - Logging requests are made by invoking one of the printing methods of a logger - instance (through the log4net.ILog). These printing methods are - Debug, - Info, - Warn, - Error, and - Fatal. -

    -

    - By definition, the printing method determines the level of a logging request. - For example, if - log - is a logger instance, then the statement - log.Info("..") - is a logging request of level INFO. -

    -

    - A logging request is said to be enabled if its level is higher than or - equal to the level of its logger. Otherwise, the request is said to be disabled. - A logger without an assigned level will inherit one from the hierarchy. This - rule is summarized below. -

    -
    -
    Basic Selection Rule
    -
    -

    - A log request of level L in a logger with (either assigned or inherited, - whichever is appropriate) level K, is enabled if L >= K. -

    -
    -
    -

    - This rule is at the heart of log4net. It assumes that levels are ordered. For - the standard levels, we have - DEBUG < INFO < WARN < ERROR < FATAL. -

    -

    - Calling the - log4net.LogManager.GetLogger - method with the same name will always return a reference to the exact same - logger object. -

    -

    - For example, in: -

    - -
    -ILog x = LogManager.GetLogger("wombat");
    -ILog y = LogManager.GetLogger("wombat");
    - -

    - x - and - y - refer to exactly the same logger object. -

    -

    - Thus, it is possible to configure a logger and then to retrieve the same - instance somewhere else in the code without passing around references. In - fundamental contradiction to biological parenthood, where parents always - precede their children, log4net loggers can be created and configured in any - order. In particular, a "parent" logger will find and link to its descendants - even if it is instantiated after them. -

    -

    - Configuration of the log4net environment is typically done at application - initialization. The preferred way is by reading a configuration file. This - approach will be discussed shortly. -

    -

    - Log4net makes it easy to name loggers by software component. This can be - accomplished by statically instantiating a logger in each class, with the - logger name equal to the fully qualified name of the class. This is a useful - and straightforward method of defining loggers. As the log output bears the - name of the generating logger, this naming strategy makes it easy to identify - the origin of a log message. However, this is only one possible, albeit common, - strategy for naming loggers. Log4net does not restrict the possible set of - loggers. The developer is free to name the loggers as desired. -

    -

    - Nevertheless, naming loggers after the class where they are located seems to be - the best strategy known so far. It is simple an obvious to the developers where - each log message came from. Most importantly it leverages the design of the - application to produce the design of the logger hierarchy. Hopefully some - thought has gone into the design of the application. -

    -
    -

    Appenders

    -
    -

    - The ability to selectively enable or disable logging requests based on their - logger is only part of the picture. Log4net allows logging requests to print to - multiple destinations. In log4net speak, an output destination is called an appender. - Appenders must implement the log4net.Appenders.IAppender - interface. -

    -

    - The following appenders are defined in the log4net package: -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Type - Description
    log4net.Appender.AdoNetAppender - Writes logging events to a database using either prepared statements or stored - procedures. -
    log4net.Appender.AnsiColorTerminalAppender - Writes color highlighted logging events to a an ANSI terminal window. -
    log4net.Appender.AspNetTraceAppender - Writes logging events to the ASP trace context. These can then be rendered at - the end of the ASP page or on the ASP trace page. -
    log4net.Appender.BufferingForwardingAppender - Buffers logging events before forwarding them to child appenders. -
    log4net.Appender.ColoredConsoleAppender - Writes logging events to the application's Console. The events may go to either - the standard our stream or the standard error stream. The events may have configurable - text and background colors defined for each level. -
    log4net.Appender.ConsoleAppender - Writes logging events to the application's Console. The events may go to either - the standard our stream or the standard error stream. -
    log4net.Appender.EventLogAppender - Writes logging events to the Windows Event Log. -
    log4net.Appender.FileAppender - Writes logging events to a file in the file system. -
    log4net.Appender.ForwardingAppender - Forwards logging events to child appenders. -
    log4net.LocalSyslogAppender - Writes logging events to the local syslog service (UNIX only). -
    log4net.Appender.MemoryAppender - Stores logging events in an in memory buffer. -
    log4net.Appender.NetSendAppender - Writes logging events to the Windows Messenger service. These messages are - displayed in a dialog on a users terminal. -
    log4net.Appender.OutputDebugStringAppender - Writes logging events to the debugger. If the application has no - debugger, the system debugger displays the string. If the application has no - debugger and the system debugger is not active, the message is ignored. -
    log4net.Appender.RemoteSyslogAppender - Writes logging events to a remote syslog service using UDP networking. -
    log4net.Appender.RemotingAppender - Writes logging events to a remoting sink using .NET remoting. -
    log4net.Appender.RollingFileAppender - Writes logging events to a file in the file system. The RollingFileAppender can - be configured to log to multiple files based upon date or file size - constraints. -
    log4net.Appender.SmtpAppender - Sends logging events to an email address. -
    log4net.Appender.SmtpPickupDirAppender - Writes SMTP messages as files into a pickup directory. - These files can then be read and sent by an SMTP agent - such as the IIS SMTP agent. -
    log4net.Appender.TelnetAppender - Clients connect via Telnet to receive logging events. -
    log4net.Appender.TraceAppender - Writes logging events to the .NET trace system. -
    log4net.Appender.UdpAppender - Sends logging events as connectionless UDP datagrams to a remote host or a - multicast group using a UdpClient. -
    -
    -

    - More than one appender can be attached to a logger. -

    -

    - - Each enabled logging request for a given logger will be forwarded to all - the appenders in that logger as well as the appenders higher in the hierarchy. - - In other words, appenders are inherited additively from the logger hierarchy. - For example, if a console appender is added to the root logger, then all - enabled logging requests will at least print on the console. If in addition a - file appender is added to a logger, say X, then enabled logging requests - for X and X's children will print on a file and on the - console. It is possible to override this default behavior so that appender - accumulation is no longer additive by setting the additivity flag on the logger - to - false. -

    -

    - The rules governing appender additivity are summarized below. -

    -
    -
    Appender Additivity
    -
    -

    - The output of a log statement of logger X will go to all the appenders - in X and its ancestors. This is the meaning of the term "appender - additivity". -

    -

    - However, if an ancestor of logger X, say Y, has the additivity - flag set to - false, then X's output will be directed to all - the appenders in X and it's ancestors up to and including Y but - not the appenders in any of the ancestors of Y. -

    -

    - Loggers have their additivity flag set to - true - by default. -

    -
    -
    -

    - The table below shows an example: -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Logger Name - Added Appenders - Additivity Flag - Output Targets - Comment
    rootA1not applicableA1There is no default appender attached to root.
    xA-x1, A-x2trueA1, A-x1, A-x2Appenders of "x" and root.
    x.ynonetrueA1, A-x1, A-x2Appenders of "x" and root.
    x.y.zA-xyz1trueA1, A-x1, A-x2, A-xyz1Appenders in "x.y.z", "x" and root.
    securityA-secfalseA-secNo appender accumulation since the additivity flag is set to - false.
    security.accessnonetrueA-secOnly appenders of "security" because the additivity flag in "security" is set - to - false.
    -
    -
    -

    Filters

    -
    -

    - Appenders can filter the events that are delivered to them. The filters can be - specified in the configuration to allow fine control of the events that are - logged through different appenders. -

    -

    - The simplest form of control is to specify a - Threshold - on the appender. This works by logging only the events that have a level that - is greater than or equal to the threshold. -

    -

    - More complex and custom event filtering can be done using the filter chain - defined on each appender. Filters must implement the - log4net.Filter.IFilter interface. -

    -

    - The following filters are defined in the log4net package: -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Type - Description
    log4net.Filter.DenyAllFilter - Drops all logging events. -
    log4net.Filter.LevelMatchFilter - An exact match to the event's level. -
    log4net.Filter.LevelRangeFilter - Matches against a range of levels. -
    log4net.Filter.LoggerMatchFilter - Matches against a the start of the logger name. -
    log4net.Filter.PropertyFilter - Matches a substring from a specific property value. -
    log4net.Filter.StringMatchFilter - Matches a substring from the event's message. -
    -
    -

    - The filters can be configured to either accept or reject the event based upon - the match. -

    -
    -

    Layouts

    -
    -

    - More often than not, users wish to customize not only the output destination - but also the output format. This is accomplished by associating a layout - with an appender. The layout is responsible for formatting the logging request - according to the user's wishes, whereas an appender takes care of sending the - formatted output to its destination. The - PatternLayout, part of the standard log4net - distribution, lets the user specify the output format according to conversion - patterns similar to the C language - printf - function. -

    -

    - For example, the PatternLayout with the conversion pattern - "%timestamp [%thread] %-5level %logger - %message%newline" - will output something akin to: -

    - -
    -176 [main] INFO  Com.Foo.Bar - Located nearest gas station.
    - -

    - The first field is the number of milliseconds elapsed since the start of the - program. The second field is the thread making the log request. The third field - is the level of the log statement. The fourth field is the name of the logger - associated with the log request. The text after the '-' is the message of the - statement. -

    -

    - The following layouts are included in the log4net package: -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Type - Description
    log4net.Layout.ExceptionLayout - Renders the exception text from the logging - event. -
    log4net.Layout.PatternLayout - Formats the logging event according to a flexible - set of formatting flags. -
    log4net.Layout.RawTimeStampLayout - Extracts the timestamp from the logging event. -
    log4net.Layout.RawUtcTimeStampLayout - Extracts the timestamp from the logging event in Universal Time. -
    log4net.Layout.SimpleLayout - Formats the logging event very simply: - [level] - [message] -
    log4net.Layout.XmlLayout - Formats the logging event as an XML element. -
    log4net.Layout.XmlLayoutSchemaLog4j - Formats the logging event as an XML element that - complies with the log4j event dtd. -
    -
    -
    -

    Object Renderers

    -
    -

    - Just as importantly, log4net will render the content of the log message - according to user specified criteria. For example, if you frequently need to - log - Oranges, an object type used in your current project, - then you can register an - OrangeRenderer - that will be invoked whenever an orange needs to be logged. -

    -

    - Object rendering follows the class hierarchy. For example, assuming oranges are - fruits, if you register an - FruitRenderer, all fruits including oranges will be - rendered by the - FruitRenderer, unless of course you registered an - orange specific - OrangeRenderer. -

    -

    - Object renderers have to implement the - log4net.ObjectRenderer.IObjectRenderer - interface. -

    -
    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/manual/plugins.html b/doc/release/manual/plugins.html deleted file mode 100644 index 88bd5621..00000000 --- a/doc/release/manual/plugins.html +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net Manual: Plugins - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Manual - Plugins

    -
    -

    Contents

    -
    - Plugins
    - -
    -

    Plugins

    -
    -

    - Plugins are additional modular components that are attached to a logger repository. -

    -

    - Plugins are stored in the PluginMap of an - ILoggerRepository. - Plugins are attached to the repository by using the PluginMap.Add - method. -

    -

    - The following plugins are included in the log4net package: -

    -
    - - - - - - - - - -
    - Type - Description
    log4net.Plugin.RemoteLoggingServerPlugin - Creates a remote logging sink that can receive logging events from a - RemotingAppender. -
    -
    -
      -
    • -

      RemoteLoggingServerPlugin

      -

      - Creates a remote logging sink that can receive logging events from a - RemotingAppender. -

      -

      - Creates a remoting logging sink. A single - parameter must be passed to the constructor that specifies the sink URI. This is a - name used to identify the logging sink object published via remoting and must be - agreed with the client before communication can take place. -

      -

      - Example usage: -

      - -
    • -
    -

    Plugin Attributes

    -
    -

    - Plugins can be configured using the following assembly-level attributes: -

    -
      -
    • -

      PluginAttribute

      -

      - Specifies a plugin type to create and attach to the default repository. This attribute - does not allow plugins to be parameterized. The plugin class must have a public default constructor. -

      -

      - This attribute may be used as many times as necessary to attach plugins to the repository. -

      -
    • -
    -
    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/manual/repositories.html b/doc/release/manual/repositories.html deleted file mode 100644 index aa1c4347..00000000 --- a/doc/release/manual/repositories.html +++ /dev/null @@ -1,271 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net Manual: Repositories - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Manual - Repositories

    -
    -

    Contents

    - -

    Logging Repositories

    -
    -

    - Logging repositories are considered advanced functionality. The default behavior - should be sufficient for most users. -

    -

    - Log4net supports logging repositories. A repository is uniquely named. - Each repository is a (ILoggerRepository). - Multiple assemblies can link to the same repository. -

    -

    - By default there is a single logging repository per process (more precisely per AppDomain). This extends - across all assemblies loaded into the process and allows them to all share a - single configuration. The configuration of the repository only needs to be done once, - typically in the entry point to the application, either programmatically or using - a configuration attribute. -

    -

    - Named logging repositories can be created using the LogManager.CreateRepository - method. The repository for can be retrieved using the - LogManager.GetRepository method. - A repository created in this way will need to be configured programmatically. -

    -

    Attributes

    -
    -

    - An assembly may choose to utilize a named logging repository rather than the default repository. - This completely separates the logging for the assembly from the rest of the application. - This can be very useful to component developers that wish to use log4net for their - components but do not want to require that all the applications that use their - component are aware of log4net. It also means that their debugging configuration is - separated from the applications configuration. The assembly should specify the - RepositoryAttribute to set its logging repository. -

    -

    - The log4net logging repositories can be configured using the following assembly-level - attributes: -

    -
      -
    • - AliasRepositoryAttribute -

      - Specifies a named repository to use as this assembly's repository. -

      -

      - An assembly's logger repository is defined by its - RepositoryAttribute, however this can be overridden by an - assembly loaded before the target assembly. -

      -

      - An assembly can alias another assembly's repository by specifying - this attribute with the name of the target repository. -

      -

      - This attribute may be used as many times as necessary to alias all the required - repositories. -

      -
    • -
    • - RepositoryAttribute -

      - Specifies the logging repository for the assembly. -

      -

      - Assemblies are mapped to logging repositories. This attribute controls the configuration of the repository. The - Name property specifies the name of the repository - for this assembly. The RepositoryType - property specifies the type of the repository object to create for the assembly. - If this attribute is not specified and a Name - is not specified then the assembly will be part of the default shared logging - repository. -

      -

      - This attribute may only be used once per assembly. -

      -
    • -
    -
    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/release/release-notes.html b/doc/release/release-notes.html deleted file mode 100644 index 06e42ff3..00000000 --- a/doc/release/release-notes.html +++ /dev/null @@ -1,1282 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Release Notes - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Release Notes

    -
    -

    Contents

    - -

    1.2.10

    -
    -

    Bug Fixes

    -
    -
      -
    • [LOG4NET-21] - RemotingAppender fails once NDC becomes empty
    • -
    • [LOG4NET-22] - XmlLayout allows output of invalid control characters
    • -
    • [LOG4NET-23] - example-apps.html links are off by one folder level
    • -
    • [LOG4NET-25] - RollingFileAppender can fail if RollOverIfDateBoundaryCrossing required
    • -
    • [LOG4NET-28] - AdoNetAppender does not support inserting NULL into columns
    • -
    • [LOG4NET-29] - LevelMatchFilter should return Neutral when no match is found
    • -
    • [LOG4NET-32] - AdoNetAppender losing first entry
    • -
    • [LOG4NET-35] - Exception rendering ThreadContextStack if null value pushed into stack
    • -
    • [LOG4NET-36] - System.Diagnostics.Trace may throw exception if AppDomain does not have config file
    • -
    • [LOG4NET-40] - RollingFileAppender does not limit files to MaxSizeRollBackups when CountDirection is 1
    • -
    • [LOG4NET-41] - RollingFileAppender roll over date fail
    • -
    • [LOG4NET-42] - Serialised LoggingEvent does not preserve the Fix flags
    • -
    • [LOG4NET-43] - Specifying an empty string as a property in the config file results in an error
    • -
    • [LOG4NET-44] - XmlLayout emits all properties under a node named global-properties, rather than just properties.
    • -
    • [LOG4NET-49] - CountingQuietTextWriter does not count strings written with WriteLine
    • -
    • [LOG4NET-50] - Process.StartTime hangs on some systems
    • -
    • [LOG4NET-60] - Bug in RollingFileAppender.cs causing failure to timely roll files on monthly interval
    • -
    • [LOG4NET-63] - 1.2.9.0 Documentation typos
    • -
    • [LOG4NET-65] - Unhandled SecurityException exception for FileIOPermission while loading configuration file
    • -
    • [LOG4NET-67] - CVE-2006-0743 Security vulnerability in LocalSyslogAppender
    • -
    • [LOG4NET-69] - Exception thrown when *Format methods are given a malformed format string
    • -
    • [LOG4NET-70] - CoreDll.dll referenced with different capitalisation
    • -
    • [LOG4NET-73] - ADONetAppender.ActivateOptions() leaks database connection when called multiple times
    • -
    -
    -

    New Features

    -
    -
      -
    • [LOG4NET-11] - Add Flush command to API
    • -
    • [LOG4NET-24] - Programmatic flush of BufferingAppenderSkeleton buffer
    • -
    • [LOG4NET-37] - Allow the RepositorySelector type to be specified using the AppSettings config
    • -
    • [LOG4NET-46] - Support appenders that can output multiple events efficiently
    • -
    • [LOG4NET-51] - WmiAppender
    • -
    -
    -

    Improvements

    -
    -
      -
    • [LOG4NET-3] - Support per event patterns in FileAppender File name
    • -
    • [LOG4NET-13] - Allow SMTPAppender to have replaceable parameters in Subject
    • -
    • [LOG4NET-15] - Email high "importance" priority setting with SmtpAppender
    • -
    • [LOG4NET-17] - Line-wrapping Appender Layouts
    • -
    • [LOG4NET-33] - Ability to use global property to point to log4net configuration file
    • -
    • [LOG4NET-34] - Allow xml config values to be set via XmlNodeType.CDATA or XmlNodeType.Text rather than just value="foo"
    • -
    • [LOG4NET-45] - PluginAttribute does not allow plugin type to be specified as a Type, only as a string
    • -
    • [LOG4NET-52] - Allow XML configurator to set properties of type Object
    • -
    • [LOG4NET-53] - Allow repository properties to be set in the config file
    • -
    • [LOG4NET-56] - Support rendering IEnumerator objects as well as ICollections
    • -
    • [LOG4NET-58] - Support clean build on .NET 2.0
    • -
    • [LOG4NET-72] - Performance of ILog.xxxFormat methods
    • -
    • [LOG4NET-74] - Change MemoryAppender member variables to protected
    • -
    -
    -
    -

    1.2.9 Beta

    -
    -

    Breaking Changes

    -
    -
      -
    • -

      Renamed namespaces

      -

      - Renamed namespace log4net.spi to log4net.Core. - Renamed namespace log4net.helpers to log4net.Util. -

      -
    • -
    • -

      Renamed config classes and attributes

      -

      - In the log4net.Config namespace the DOMConfigurator, - DOMConfiguratorAttribute, DomainAttribute, - and AliasDomainAttribute have been marked as obsolete. These types are - still available and functional in this release. -

      -

      - The XmlConfigurator and XmlConfiguratorAttribute - types replace DOMConfigurator and - DOMConfiguratorAttribute. The RepositoryAttribute - and AliasRepositoryAttribute types replace - DomainAttribute and AliasDomainAttribute. -

      -
    • -
    • -

      Fixed pascal casing of type names

      -

      - Renamed AdoNetAppender, AspNetTraceAppender, - SmtpAppender, Iso8601DateFormatter, - MdcFilter, and NdcFilter. - Note that the config file type resolver is case insensitive so this is only a breaking change - for code that programmatically creates a type that has been renamed. -

      -
    • -
    • -

      Layouts changed to stream their output to a TextWriter

      -

      - Layouts have been changed to format their output to a TextWriter - rather than return a string. This increases performance and reduces temporary object creation. -

      -
    • -
    • -

      C style string escapes no longer supported by config parser

      -

      - The XML config parser no longer supports decoding C style escape sequences in strings. - Previously sequences like \n and \\ - where decoded. Instead use the appropriate XML encodings as required. -

      -
    • -
    -
    -

    New Features

    -
    -
      -
    • -

      New CLI build

      -

      - A new log4net assembly is built that targets all CLI 1.0 compatible runtimes. - This build is essentially a common subset of the Mono 1.0 and .NET 1.0 builds. - It is built using the MS .NET 1.0 compiler and libraries but does not use any - platform specific APIs. -

      -

      - This build is only available in release configuration and can be found at - bin\cli\1.0\release. -

      -
    • -
    • -

      Logging contexts

      -

      - Logging contexts can be used to record contextual data that is relevant to the current - process. Logging contexts are both an extension of the concepts embodied in the - MDC and NDC and a replacement for - them. The MDC and NDC have been - reimplemented to use the ThreadContext as storage. -

      -

      - The logging contexts provide a single unified view that cuts across different - scopes within an application. - The contexts are layered in the following order of narrowing scope: - GlobalContext, ThreadContext, - LogicalThreadContext, and LoggingEvent. - Context values specified in a narrower scope hide the matching value in a wider scope. -

      -
    • -
    • -

      PatternLayout customization and long pattern names

      -

      - The PatternLayout now supports long pattern names. - These pattern names are significantly more readable than the single character patterns. -

      -

      - The PatternLayout now supports custom patterns. New patterns - can be defined in the config file: -

      -
      -<layout type="log4net.Layout.PatternLayout">
      -
      -  <converter>
      -    <name value="myConverter" />
      -    <type value="TestApp.MyPatternConverter, TestApp" />
      -  </converter>
      -
      -  <conversionPattern value="%-5level %logger - %myConverter - %message%newline" />
      -</layout>
      -

      - The above config defines a custom pattern called myConverter - which is bound to the TestApp.MyPatternConverter, TestApp - type. This type must extend the log4net.Util.PatternConverter - base class. The custom pattern can then be used in the pattern string. -

      -

      - For full details see the SDK Reference entry: log4net.Layout.PatternLayout. -

      -
    • -
    • -

      PatternString for pattern based configuration

      -

      - A new pattern based type, PatternString, can be used in - the config file to set string properties using a pattern syntax. For example the - File property of the FileAppender could be set as follows: -

      -
      -<file type="log4net.Util.PatternString">
      -
      -  <converter>
      -    <name value="folder" />
      -    <type value="TestApp.SpecialFolderPatternConverter,TestApp" />
      -  </converter>
      -
      -  <conversionPattern value="%folder{LocalApplicationData}\log-file.txt" />
      -</file>
      -

      - The code for the SpecialFolderPatternConverter - is as follows: -

      -
      -public class SpecialFolderPatternConverter : log4net.Util.PatternConverter 
      -{
      -  override protected void Convert(System.IO.TextWriter writer, object state) 
      -  {
      -    Environment.SpecialFolder specialFolder = 
      -      (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), base.Option, true);
      -      
      -    writer.Write(Environment.GetFolderPath(specialFolder));
      -  }
      -}
      -

      - For full details see the SDK Reference entry: log4net.Util.PatternString. -

      -
    • -
    • -

      Loading configuration from a URI

      -

      - The XmlConfigurator methods now support loading the - configuration data from a URI. Config can be loaded from any URI supported by the - System.Net.WebRequest class. -

      -
    • -
    • -

      Support for No-Touch deployment

      -

      - Log4net supports configuring No-Touch deployment applications using the - XmlConfiguratorAttribute. If a relative config file - or extension is specified then this is resolved relative to the deployment - URI. -

      -
    • -
    • -

      Config file parser enhancements

      -

      - The config file parser has been enhanced to support specifying the property subtype, or intermediate type, - directly on the property element, for example: -

      -
      -<layout type="log4net.Layout.PatternLayout" value="%message%newline" />
      -

      - Implicit conversion will be attempted between the value string and the type specified, - and then again between the type and the target property type. -

      -
    • -
    • -

      .NET string formatting syntax

      -

      - Added .NET String.Format style formatting syntax methods to - the ILog interface. The new methods are: - DebugFormat, InfoFormat, - WarnFormat, ErrorFormat - and FatalFormat. -

      -
    • -
    • -

      Customizable levels

      -

      - Levels are defined by the repository LevelMap. The defined - levels, the relative ordering of levels and level display names can be configured on - a per-repository basis. -

      -
    • -
    • -

      Per-appender security contexts

      -

      - Appenders that interact with controlled platform resources, e.g. files, can be - configured to use a separate security context when accessing these resources. - The calling thread may not have appropriate privileges to access the resource a - custom SecurityContext can be used to elevate the - privileges of the appender. The WindowsSecurityContext - is used to specify alternative credentials on the Windows platform. -

      -
    • -
    • -

      Added new appenders

      -
      -
      AnsiColorTerminalAppender
      -
      -

      - The AnsiColorTerminalAppender writes events to - the application's ANSI terminal window. It can be configured to specify - the text and background colors for different level events. Note that Console - applications running on Windows do not have an ANSI terminal window and - should use the ColoredConsoleAppender instead. -

      -
      -
      LocalSyslogAppender
      -
      -

      - Logs events to a local syslog service. This appender uses the POSIX libc syslog - library functions. If these functions are not available on the local system then - this appender will not work! -

      -
      -
      RemoteSyslogAppender
      -
      -

      - The RemoteSyslogAppender uses the BSD syslog protocol to - log to a syslog daemon. The syslogd listens for for messages on UDP port 514. -

      -
      -
      TelnetAppender
      -
      -

      - The TelnetAppender accepts socket connections and streams - logging messages back to the client. The output is provided in a telnet-friendly way - so that a log can be monitored over a TCP/IP socket. - This allows simple remote monitoring of application logging. -

      -
      -
      -
    • -
    • -

      Added new LoggerMatchFilter filter

      -

      - Added LoggerMatchFilter which matches a string against - the event's logger name. -

      -
    • -
    • -

      Pluggable file locking models for the FileAppender

      -

      - The FileAppender (and by extension the - RollingFileAppender) now support pluggable file - locking models. The default model, ExclusiveLock, - maintains the current exclusive file locking behavior. An alternative - model, MinimalLock, can be used to support writing to - a single output file from multiple processes. -

      -

      - For full details see the SDK Reference entry: log4net.Appender.FileAppender.LockingModel. -

      -
    • -
    • -

      RollingFileAppender roll once

      -

      - The RollingFileAppender now supports a new - rolling style, Once. In this mode the appender - will roll the file once per run. -

      -
    • -
    • -

      SmtpAppender authentication

      -

      - On the .NET 1.1 platform only, the SmtpAppender supports authenticating - against the mail server using either username and password or integrated NTLM authentication. -

      -
    • -
    • -

      AdoNetAppender ReconnectOnError

      -

      - Added new configuration property to AdoNetAppender. - Setting ReconnectOnError to true - will force the appender to attempt to reconnect to the database if the connection - is lost. -

      -
    • -
    • -

      UdpAppender hostname support

      -

      - The UdpAppender config property RemoteAddress - can now be specified as a DNS hostname string. The hostname is resolved to an IP address. -

      -
    • -
    -
    -

    Other Changes

    -
    -
      -
    • -

      FxCop compliance

      -

      - Updates to bring the internal code in line with the current FxCop rules. -

      -
    • -
    • -

      Separate NUnit tests

      -

      - Moved the NUnit tests into a separate project, log4net.Tests. -

      -
    • -
    • -

      Bug Fixes

      -
      -
      RemotingAppender
      -
      -

      - Sends events from a ThreadPool thread - rather than the calling thread to prevent transfer, - and potential loss, of the CallContext. -

      -
      -
      RollingFileAppender
      -
      -

      - Fixed date rolling period detection for non UTC timezones. -

      -
      -
      ColoredConsoleAppender
      -
      -

      - Updated to support writing more than 30,000 chars in a single message. - Fixed background color overspill if the console window needs to - scroll the contents. -

      -
      -
      -
    • -
    -
    -
    -

    1.2.0 Beta 8

    -
    -
      -
    • -

      Changed assembly name to log4net

      -

      - The build output is now log4net.dll - for all frameworks. This is a breaking change. -

      -

      - To resolve cross platform and cross version issues we have - changed the log4net assembly to use a common name for all - frameworks. The assembly friendly name is now log4net. - The builds for each framework can now be differentiated - by the assembly title. This includes the name of the framework - that the assembly was built on. -

      -
    • -
    • -

      Combined Release and ReleaseStrong builds

      -

      - The Release and ReleaseStrong builds have been consolidated into - a single build called Release. This Release build is strongly named. -

      -
    • -
    • -

      New Appender: ColoredConsoleAppender

      -

      - The ColoredConsoleAppender writes events to the - application's console. It can be configured to specify the text and background - colors for different level events. -

      -
    • -
    • -

      New Appender: SmtpPickupDirAppender

      -

      - The SmtpPickupDirAppender generates SMTP compliant - messages and writes them to a local directory. These files can then be read - by an SMTP agent (e.g. the IIS SMTP Agent) and delivered. -

      -
    • -
    • -

      New Layout: XmlLayoutSchemaLog4j

      -

      - This new layout formats the logging events as XML which complies with - the log4j event dtd. This can be used to transfer log event from log4net - to log4j. Currently the only appender that can communicate directly with - log4j is the UdpAppender. -

      -
    • -
    • -

      New PatternLayout conversion characters

      -

      - Added support for capturing the current thread principal name and the - app domain friendly name for each logging event. -

      -
      -
      %a
      -
      - Used to output the friendly name of the AppDomain where the - logging event was generated. -
      -
      %u
      -
      - Used to output the user name for the currently active user - (Principal.Identity.Name). -
      -
      -
    • -
    • -

      Types specified in the config file are now loaded ignoring case

      -

      - All types specified in the configuration files are now loaded - using a case insensitive method. -

      -
    • -
    • -

      Fine grained fixing for buffered events

      -

      - The LoggingEvent now supports fine grained - fixing of data that needs to be accessed outside the append context, - e.g. when an event is buffered. The new Fix - property takes a combination of the FixFlags - enumeration values. -

      -
    • -
    • -

      Code updated inline with FxCop 1.21

      -

      - In line with the FxCop 1.21 guidelines: - Sealed utility classes. Added serialization security demand to GetObjectData. - Renamed parameters. -

      -
    • -
    • -

      EventLogAppender 32K Limit

      -

      - There is a limit of 32K characters in an EventLog message. Added a - check that only logs the first 32000 characters from the rendered - message. -

      -
    • -
    -
    -

    1.2.0 Beta 7

    -
    -
      -
    • -

      Updated to support the Microsoft .NET Framework 1.1 Final

      -

      - Updated to support the Microsoft .NET Framework 1.1 Final Beta (1.1.4322). -

      -
    • -
    • -

      Features document

      -

      - Added a new document that covers the main features of log4net. - See the features - document for more information. -

      -
    • -
    • -

      Hierarchy disabled until it is configured

      -

      - The Hierarchy is now disabled until it has been configured. - All messages logged to the Hierarchy before it has been - configured will be ignored without an error message being - written to the console. -

      -

      - If you are configuring log4net programmatically (i.e. not using - one of the built-in configurators) you must set the - ILoggerRepository.Configured property - to true once you have configured - the repository. -

      -

      - The no appenders defined for a logger message will no longer be - displayed on the console by default. This message will only be - displayed if internal debugging is enabled. -

      -
    • -
    • -

      New examples in VisualBasic.NET, JScript and Managed C++

      -

      - New examples in VisualBasic.NET, JScript and Managed C++. - TODO Link to document about examples. -

      -
    • -
    • -

      Code and Documentation Updates

      -

      - Code fixes. Documentation and manual updates. - See the ChangeLog for more information. -

      -
    • -
    • -

      Added document with example appender configurations

      -

      - See the Example Appender Configuration - document for more information. -

      -
    • -
    -
    -

    1.2.0 Beta 6

    -
    -
      -
    • -

      Added support for multiple frameworks

      -

      - log4net 1.2.0 beta 6 adds support for the the following frameworks: -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - -
      - Framework - Website
      Microsoft .NET Framework 1.1 Final Beta (1.1.4322)http://msdn.microsoft.com/net
      Microsoft .NET Compact Framework 1.0 (1.0.5000)http://msdn.microsoft.com/vstudio/device/compactfx.asp
      Mono 0.23http://www.go-mono.org
      Microsoft Shared Source CLI 1.0http://msdn.microsoft.com/library/en-us/dndotnet/html/mssharsourcecli.asp
      -
      -
      -

      - Not all frameworks are created equal and some features have been excluded from - some of the builds. See the Framework Support document for more information. -

      -
    • -
    • -

      New build system using NAnt

      -

      - The new build system allows log4net to be built for all supported frameworks and - in all build configurations in one go. -

      -
    • -
    • -

      New source code & distribution layout

      -

      - The source code & distribution layout has been updated to support the new - build environment and multiple target frameworks. -

      -
    • -
    • -

      Removed DomainAttribute.UseDefaultDomain property

      -

      - Updated default behavior of DefaultRepositorySelector. Assemblies - are now by default placed into the default domain. To specify another domain, - the DomainAttribute must be used. This is the opposite behavior - to what was previously available. If you were previously specifying the DomainAttribute.UseDefaultDomain - property then you should remove it, and if the default behavior is now - sufficient, you do not need to specify the DomainAttribute at all. -

      -
    • -
    • -

      Updated configuration file parser

      -

      - Updated config file parser to use the element name as the property to set. Also - removed <object> tag, the type attribute can now be - specified on the property element directly. -

      -

      - For example: -

      -
      -<appender>
      -  <param name="Evaluator">
      -    <object type="log4net.spi.LevelEvaluator">
      -      <constructor>
      -        <param type="log4net.spi.Level" value="DEBUG"/>
      -      </constructor>
      -    </object>
      -  </param>
      -</appender>
      -

      - becomes: -

      -
      -<appender>
      -  <evaluator type="log4net.spi.LevelEvaluator">
      -    <threshold value="DEBUG"/>
      -  </evaluator>
      -</appender>
      -
    • -
    • -

      Support for event ID

      -

      - The EventLogAppender now supports setting the event ID in the - event log, this is taken from the EventID property from the per - event Properties map on the LoggingEvent. -

      -
    • -
    • -

      Updated ADONetAppender

      -

      -

        -
      • - Added support for prepared statements and stored procedures
      • -
      • - Added RawTimeStampLayoutto correctly convert the timestamps into - database date time format
      • -
      • - Added ExceptionLayout to render the exception data
      • -
      -

      -

    • -
    • -

      Support for front-end extension

      -

      - This allows the logging API to be wrapped or adapted for specific purposes. Two - extension samples are included in the distribution: -

      -
      - - - - - - - - - - - - - - - - - -
      - Extension - Description
      log4net.Ext.TraceAdds trace logging methods
      log4net.Ext.EventIDAdds additional eventId parameter to all methods
      -
      -

      -

    • -
    • -

      Added ForwardingAppender

      -

      Forwards events to multiple sub appenders after applying filter rules.

      -
    • -
    • -

      Added BufferingForwardingAppender

      -

      Forward events to sub appenders after buffering them.

      -
    • -
    • -

      Added ASPNetTraceAppender

      -

      Logs events to the ASP.NET trace system.

      -
    • -
    • -

      Added NetSendAppender

      -

      Delivers logging events using the Windows Messenger service.

      -
    • -
    • -

      Added UdpAppender

      -

      Sends logging events as connectionless UDP datagrams to a remote host or a - multicast group.

      -
    • -
    • -

      Removed obsolete methods

      -
    • -
    • -

      Lots of updates to improve our compliance with FxCop

      -
    • -
    • -

      Improved SDK documentation

      -
    • -
    -
    -

    1.2.0 Beta 5

    -
    -
      -
    • -

      Fixed Exception thrown when DOM Configurator called with a null XML - Element.

      -

      This occurred if the configuration file did not have a log4net section defined.

      -
    • -
    • -

      Made level lookup case insensitive

      -
    • -
    • -

      Prevented the Hierarchy's Threshold level from being set to a null reference

      -
    • -
    -
    -

    1.2.0 Beta 4

    -
    -
      -
    • -

      Added event specific properties to the logging event object

      -

      - Appenders can add additional information to the events they are logging. The RemotingAppender - and the SMTPAppender both add a 'hostname' property to the events. - These properties can be accessed using the PatternLayout with the - %P{name} syntax. -

      -
    • -
    • -

      Added a plugin framework

      -

      An IPlugin interface can be attached to any repository.

      -
    • -
    • -

      A new RemoteLoggingServerPlugin plugin acts as the server for the - RemotingAppender

      -
    • -
    • -

      Updated the core log4net framework to work in an environment with no - permissions

      -

      Specific appenders still require additional permissions to log correctly

      -
    • -
    • -

      Added support for domain aliasing using the AliasDomainAttribute

      -

      This allows a parent assembly to take control of the logging domain for child - assemblies.

      -
    • -
    • -

      Added events for repository creation, configuration change, configuration reset - and repository shutdown

      -
    • -
    • -

      Added LevelMap to the ILoggerRepository interface

      -

      The mapping from level name to level object is now repository specific, - therefore each repository can have independent mappings.

      -
    • -
    • -

      Moved hierarchy specific config file parser to new DOMHierarchyConfigurator class

      -

      This is controlled by the Hierarchy object and allows for better - encapsulation.

      -
    • -
    • -

      Added OnlyFixPartialEventData property to the buffered appenders

      -

      This setting causes slow settings to be ignored. This significantly improves the - performance of the buffered appenders.

      -
    • -
    • -

      XML entity references are supported in the XML config file.

      -
    • -
    • -

      Added support for expanding environment variables in <param> values

      -

      - The environment variables must be specified as ${FOO} where FOO - is the name of the variable to expand. -

      -
    • -
    • -

      Upgraded to use NUnit 2.0

      -
    • -
    • -

      File appenders can specify the encoding to use for the file

      -
    • -
    • -

      Added strong named configuration

      -
    • -
    -
    -

    1.2.0 Beta 3

    -
    -
      -
    • -

      Added log4net.Ext.Trace extension

      -

      This is a separate assembly that adds a trace level to log4net.

      -
    • -
    • -

      The default log file output directory is now the application base directory not - the current directory

      -
    • -
    • -

      Added MemoryAppender

      -

      Stores all the logging events in an in-memory buffer.

      -
    • -
    • -

      Moved the Hierarchy implementation into a separate namespace

      -

      - The log4net.Repository.Hierarchy namespace now contains all the - code that is specific to the Hierarchy implementation. -

      -
    • -
    • -

      Refactored the DOMConfigurator and BasicConfigurator

      -

      - The Hierarchy specific data schema and implementation could be has - now been moved to the log4net.Repository.Hierarchy namespace. The - bootstrap code for these configurators remains in the log4net.Config - namespace. -

      -
    • -
    • -

      Replaced the DOMConfiguratorAttribute UseExecutableDomain - property with UseDefaultDomain

      -

      - This change to the implementation of the DOMConfiguratorAttribute should - allow the configuration of multiple assemblies to be accomplished more easily, - especially when developing web applications (ASP.NET). -

      -
    • -
    • -

      A few good bug fixes!

      -
    • -
    -
    -

    1.2.0 Beta 2

    -
    -
      -
    • -

      Added ADONetAppender

      -

      Thanks to TechnologyOneCorp.com.

      -
    • -
    • -

      Added TraceLogAssembly extensibility example

      -
    • -
    • -

      Lots of bug fixes

      -
    • -
    -
    -

    1.2.0 Beta 1

    -
    -
      -
    • -

      Added 6 new examples

      -
    • -
    • -

      Split Category class into Logger and LogManager classes

      -

      - The instance methods from Category have moved to the Logger - class. The static methods from Category have moved to the LogManager - class. The Category class still exists but for backward - compatibility only. Changed interface ICategoryFactory to ILoggerFactory - and the implementation class DefaultCategoryFactory to DefaultLoggerFactory. -

      -
    • -
    • -

      Replaced Priority class with Level class

      -

      - The Priority class has been replaced by the Level class. - The Priority class still exists for backward compatibility only. - The Level class implements a static pool of Level objects. - The Level class is sealed and serializable. -

      -
    • -
    • -

      Added ILoggerRepository interface implemented by Hierarchy

      -

      - The Hierarchy class implements the ILoggerRepository interface. - This interface is used by the LogManager class and therefore - allows different implementations of ILoggerRepository to be used. -

      -
    • -
    • -

      Enhanced NUnit tests

      -

      - All the NUnit tests can be run using a single TestSuite: NUnitGUI - log4net.LogManager+AllTests,log4net.dll. -

      -
    • -
    • -

      Added support for serializing LoggingEvents

      -

      - The LoggingEvent class is serializable. All local state is - captured before serialization occurs. This now allows LoggingEvent - objects to be serialized between applications or machines. -

      -
    • -
    • -

      Added RemotingAppender

      -

      - Delivers LoggingEvents to a remote interface. This can be used to - collect distributed logging into a single log file. There is an example - remoting sink that receives the logging events, see examples\net\remoting\RemotingServer - for details. -

      -
    • -
    • -

      Added support for rendering composite objects

      -

      - The IObjectRenderer interface method DoRender now - takes a RendererMap argument. This allows the renderer to use the - appropriate renderer from the RendererMap to render any nested - objects. -

      -
    • -
    • -

      Added support for rendering exceptions

      -

      - The DefaultRenderer now has support for rendering exceptions to a - string. This includes nested exceptions. The RendererMap is now - used to render exceptions in the LoggingEvent. This allows the - rendering of specific exceptions to be enhanced by specific renderers. -

      -
    • -
    • -

      Added ITriggeringEventEvaluator interface

      -

      - This interface is used by SMTPAppender and RemotingAppender - to determine if a LoggingEvent meets a set of user defined - criteria. These appenders use the interface to determine whether or not to - deliver the current buffer of events to their listener. The interface is - implemented by the LevelEvaluator class, which triggers above a - set level. -

      -
    • -
    • -

      Added regex matching to the MDCFilter, NDCFilter and StringMatchFilter

      -

      - The MDCFilter, NDCFilter and StringMatchFilter - can now be configured to use regex matches in addition to substring matches. - Set the RegexToMatch property to use this feature. -

      -
    • -
    • -

      Added XMLLayout

      -

      - emits an XML element for each LoggingEvent. This allows logging - events to be stored and manipulated as XML. The DTD for the XML emitted is in - the log4net-events.dtd -

      -
    • -
    • -

      Added support for <logger> and <level> elements in the - DOMConfigurator

      -

      - As the Category and Priority classes have been - replaced by the Logger and Level classes. The DOMConfigurator - has been updated to allow the <logger> and <level> - elements to be used in place of the <category> and <priority> - elements. The old elements are still accepted for backward compatibility. -

      -
    • -
    • -

      Added Threshold property to Hierarchy

      -

      - Changed DisableXXX() methods on Hierarchy to a Threshold - property. -

      -
    • -
    • -

      Added support for logging domains

      -

      - The LogManager supports multiple logging domains. The LogManager - uses an instance of the IRepositorySelector class to map from - domains to ILoggerRepository instances. The default implementation - is to have a separate ILoggerRepository for each domain. When a - call is made to the static methods on LogManager the domain can be - specified (as a string) or the domain can be inferred automatically from the - calling assembly. The default behavior is for each assembly loaded into the - process to have its own domain and ILoggerRepository. These can - each be configured separately. This allows standalone assemblies to use log4net - without conflicting with other modules in the process. The domain for the - assembly is configured using metadata attributes defined on the assembly. -

      -
    • -
    • -

      DOMConfigurator can set params to arbitrary objects

      -

      - Using a new <object> element, params can now be set to any - creatable object. -

      -
    • -
    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/roadmap.html b/doc/roadmap.html deleted file mode 100644 index f891f97f..00000000 --- a/doc/roadmap.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Development Roadmap - - - - - - - - - - - - - - - - - -
    - - - - -

    Apache log4net Development Roadmap

    -
    -

    - The log4net development roadmap is managed by our JIRA issue tracking system. -

    -

    - For a list of upcoming fixes and in-progress tasks see: -

    - -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/support.html b/doc/support.html deleted file mode 100644 index 34f3acda..00000000 --- a/doc/support.html +++ /dev/null @@ -1,369 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apache log4net: Support - - - - - - - - - - - - - - - - - -
    - - - - -

    log4net Support

    -
    -

    - log4net user support is provided via a mailing list. Discussion on log4net is held on the - log4net-user mailing list. Please search the archives before posting because it - is likely that your question has been answered before. -

    -

    Mailing List Archives

    -
    -

    - You can browse the mailing list archives at the following locations: -

    - -
    -

    Subscribe

    -
    -

    - Subscribe to either the list or to the digest list: -

    - -
    -

    Unsubscribe

    -
    -

    - To unsubscribe send an email to the relevant email address: -

    - -
    -

    Posting

    -
    -

    - Before posting please read the following guidelines: -

    -
      -
    • -

      - Ask smart questions
      - Every volunteer project obtains its strength from the people involved - in it. You are welcome to join any of our mailing lists. You can - choose to lurk, or actively participate; it's up to you. The level of - community responsiveness to specific questions is generally directly - proportional to the amount of effort you spend formulating your - question. Eric Raymond and Rick Moen have even written an essay entitled - "Asking Smart Questions" - precisely on this topic. -

      -
    • - -
    • -

      - Keep your email short and to the point
      - If your email is more than about a page of text, chances are that it - won't get read by very many people. It is much better to try to pack a - lot of informative information (see above about asking smart questions) - into as small of an email as possible. If you are replying to a previous - email, it is a good idea to only quote the parts that you are replying - to and to remove the unnecessary bits. This makes it easier for people - to follow a thread as well as making the email archives easier to search - and read. -

      -
    • - -
    • -

      - Do your best to ensure that you are not sending HTML or "Stylelized" email to the list
      - If you are using Outlook or Outlook Express or Eudora, chances are that - you are sending HTML email by default. There is usually a setting that - will allow you to send "Plain Text" email. If you are using Microsoft - products to send email, there are several bugs in the software that - prevent you from turning off the sending of HTML email. Please read this - page as well. -

      -
    • - -
    • -

      - Watch where you are sending email
      - Our mailing lists have set the Reply-To to go back to the - list. That means that when you Reply to a message, it will go to the list - and not to the original author directly. The reason is because it helps - facilitate discussion on the list for everyone to benefit from. Be careful - of this as sometimes you may intend to reply to a message directly to someone - instead of the entire list. -

      -

      - The appropriate contents of the Reply-To header is an age-old debate that - should not be brought up on the mailing lists. You can examine opposing points of view - condemning - our convention and condoning - it. Bringing this topic up for debate again on a mailing list will add nothing new - and is considered off-topic. -

      -
    • - -
    • -

      - Do not cross post messages
      - In other words, pick a mailing list and send your messages to that mailing - list only. Do not send your messages to multiple mailing lists. The reason is - that people may be subscribed to one list and not to the other. Therefore, - some people will only see part of the conversation. -

      -
    • -
    -

    - Where relevant please try to include the following information in your postings. -

    -
      -
    • -

      - Specify the version of log4net you are using. -

      -
    • - -
    • -

      - Specify what your assembly type is, i.e. exe or dll, and how your code is launched, - e.g. console application, windows application, ASP.NET project, COM+ hosted object, etc... -

      -
    • - -
    • -

      - Specify which runtime platform (e.g. MS .NET, Mono, SSCLI) you are using and which version. -

      -
    • - -
    • -

      - If you are having configuration issues then include logging configuration files if any, plus source code. -

      -
    • - -
    • -

      - If possible please reproduce your issue with the - internal log4net debugging - enabled. Include this debug output in your post, it is usually the first thing we ask for in diagnosing issues. -

      -
    • - -
    • -

      - If you think you have found a bug then a short example reproducing the problem is very much appreciated. -

      -
    • -
    -

    - To prevent spam, we require you to be subscribed to the list before posting to it. -

    -

    - Ask questions and report bugs via email to the - log4net-user@logging.apache.org - mailing list. -

    -
    -
    - - - - - -

     

    - -
    - Copyright © - 2004-2007, - Apache Software Foundation -
    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/xdocs/build.xml b/xdocs/build.xml deleted file mode 100644 index 1b8acea3..00000000 --- a/xdocs/build.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - AnakiaTask is not present! Please check to make sure that velocity.jar is in your classpath. - - - - - - - - - - - - - diff --git a/xdocs/lib/ant-1.4.1.jar b/xdocs/lib/ant-1.4.1.jar deleted file mode 100644 index 8ad84e348091fa8e10ef2e58a236cc0e807a1c00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 417110 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

    )Gp{tUgyc|7_JjE!TH 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

    q=! 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 z

    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�+PtLWQQvGje11VgZN({k`)8=1Pk^2&x|mC0G9J`x(07m}>0}0sP0*;Gt8uSxLLIA|t=V8c$CV~7t~NDFV=-F>49S-k)_KL@ zU$zgRSkl*v?*U>7Wpu0ak$Wo718wddV_ny#!mhO>cBJ2t+Gwk0X0d&2r{dE?H6T>t z)5H0NBIz#(PfcjrTDv9xAI9D(NV4eL*X=Ib%(89Uwr$(CZQJOwZQHhOS9MkOseSf| z`*QEu{~NI$GGaZgSebL?81oz7?{)dI9MlWgks7?YUz|9cG$Dj*T05xDzjmEnS**BZ zS$~pu9q&#IPPCH(qa8)2mQg+KQNujn(?v_F8dvkGk_2X1O)n0Ot1LjkxBuZQgv=Pd zh60O5O$D5YNlTN+3NxB~&99!NBWZ4ON+ugpQ=Gj@EVXzdAB8$C>md7&C{K+jY`~+p zmF82bK7_|u;~qgMS9Q-0orgF&Y_fqnb{FiA;0dKU2G{fNoHngmyz!LUXkb};3vZYCc zI&p+)2*sZGBOHdVIJl`GM)GU2bt0Km$Gf;&X-d*5{`(9v3jfoX_tU$IuMbP42zB!^ z>)*@hM?C~Vw(_X6=g`;#^#`IOy^t^ye9VGZx-&w=N|IS&qfksc#secFVN^eQp4C_1L1#{HSnm+3v4?V4sx9|rl_T81fC%-EpHY4>#7 za>kdCm-siz>+|_>eN3*Vb<-i@u<$rU-bt8zkhr)K%4m1VyS4PSVryJ$^L+2f0Hohx z0FD8J8B8AoA;e{jI@RS5L(fGa zU%f|5J&2Snq1}Y$vvZjaT#LI=Wi~8_m|AI}1kX=|3Ql_kqVmx)2jJY$4%9prDO_~XNV#%Y7~sz9>TM`D<9%q*~h>N(C-eka=rxtc1Qk&P>`tLEp7q;VT~E((}|p{-gffGJ?baXJnD?f#aPvqW1>PNb+-H_$U(7D_o)0 zWkO;Cs5ES3apgW|8%SM{^`zGOv!haPeSF87)lNB`1rZwA8bi9+yk2Urz|>7CqNT%&1A@0APt_)XPEeqsj$ zA|!q!^o{6Yt%w*7p6pyUUR*Q8T%$kM&$seM)>P(9UDV^`Zp8NR`{cS8dYt*2V*OCR z!TWIJreIUpP^MD%)b6ebiRByfU$*o;G@)J9@>|-`*7*q;L+O3(+bUd-*x~Not0(p< zXLlY9YY+DWYkASd02r4{kIIqPZ_Ll0V=e{M9a%eIz`t0#t*KZJN!m72W3*~@MXHF41{05kj9Tj(FxC*S#~DJU@f!@`7%dPW zg3RjLNP2Zt;_$@rcu0^a;P*~>l0bs>ZVD0=ray+RNoB-<=wL2b0!6jh#6n3ufa}N&95$5&gaUa{BhsPS}w2@7@QL_t~tsW zM^eieM`6e447QR=pezvC6#T+P$nCZ_u))a6PZRF$87PX-X11P>nzj$;UW!r3bsvl1 zR^pCmouT)&Ak=$W84~!^b`ePf0AcDx6tzelKdlDfM z=sYI_V+TpZCI*xL7Q*~lw}fF_!VNMpWVvF_)(KJ=ejV5ZlR~{|Wnxf3;S`D^4-Z5k zPDz93T%3fITfxj03MVI4h*=cEh?Nh_hasddz64oLp1(Y zpt68kkioBPDlTqX!6T2kO=%?NM+c4MVRSz$zu-;I9dicHngknFN+umy&;^370M=aD zTEn%Sbcu4%iG%KxrP~K}Izmo$ppcXtm3Z&^E7nqcIXPF%WrB`7M-u5!s~4#zc{H(8 z1rDIVj0{Y0>R6Z#l)q!I@<{j*dZ|PN7A^lW&}=$c6E0ZA(X*3 z>`#Axy|jfk?&b)On&@alS`5(WT9_E5*JF`~59;WP9Vf^miz#B#9TX3Peg^aF78oAm zwD>(0_z)VDi?=Y?f1+|?_haBj<8{ECF@Fd-{dtEJ!N(cYY`R2d01blUcQ;>~Y_@~` zHr6y}BRD2t^WP1LxoA{|@`)pDEGRE`*AzV^1<>G*Z5SkMJ8UPTiVcBU`lyO?MQV@7 z42g|GPxNU??xO|5+9Gg&kg!6T)}IeIy{GqSpX#%5UphG*lUMeZRmJG&{@lWl!X7eE z-V+Pl>RK_RHxYM>o-Bg`V|byJ42){zy1?tsCe;zkFc*rxzin28oxOq|Y_l7)s50)u zZf82CwCf}BOlo5Dzlt-+V4h~Jn5QO}+q+3?G0u&`OstX5Is%p8w}xlgr&=77`V;!C z`2j(ej1n}p8bDxv(=X>b6irxc?b3%9e=6&LK}YE51wn{&LrX|kikw zVn3j<_ZCFy8J)~wnQ7UqMeDwUI-RKZ7$2jm4~`R{XUPphTAUBWIWTuk(b>#e9@1Xv zcBtA4iitX4@EJXtHK|gPX5BZPIN$zg`UU%!kC1rk2_6_c1IaHe^b>eBGxu298MBRH zNuuw;3++~-awPlT4&R&jjSaN=+{bj$V5)^9?hDCwzvnI)6~rVwlAZY;#3x^8>?a03 zfqtkv3%$yuxU95pTpR*JcaOuWlNS2i)>g0kiolp0zh*fm9}7)mKCUP+_IKp4jBnJ( zdZOZ1*1s3Tw<#&9D;WmH{Tw66aEb-t%uEObDmeN60%k>AgsPQ7hvG@thT5+z(Wt7~ zu#M5IzTpYI)2FNx0S=x~7v4{+&@ga3^1iLPvLwuZDv>Py;XGoU|Ckfh@Uoth(7m|C zs47D0({L>;R4Gd{!e`|`1w;vP#1*@_Ko8e@?31KblR7#W(iawP$%YJLJvPRPt>E&@ zYYc^;z*9?;lvdH83KVExTF)Lor_CK3Mlz&^@3kMGQ;j{W zz3%a5<9@<^^^@=6*UjE^{x0doOD1=ZETSjx*D1~3joIoB-Rcflb6V3z_JS3(Xt~hE z=t49_zx5{w=Qak0vWlk^RFqKOG$8kd6_J4*48phpAcg>GEA9azWKf_SbQBCvdG$wM zY^-+!u-(x=`n}{K@bck!MQGuoCgp7>;^VZff35x|eh13FBRT3{6)&1d92o&#ctf-B z4rA^SJL6WhSs)h$V0+0d$V2}hBB}I>2MVVOreO{9WO`_C z3aMqO$hr3P{2Pn}J#)Ss&`<_PPJ}0Bjv~67Q+R(bZU=PK2o+3gB$nP3nxS1%05yV- zWuyd}0Y;e>8xLsN63#FvbQcF&UJ9_%9vG-sDw5BooRjA6(TE>}3kg`*ijAgnCYjl+ z!|R0|Sw(3lb?zJTI3slTMP1(1N5Wk>f*P)l4|g|JDzvvRz+%gcgoayxJI#uS0Sk&8 zY%l*ih@Ye)K$`{rHP<29@Gc)&=h%L%aCP=o+>5uM@L}<1fll!J{8wDWqo&;hX9aTY zmyB*1QEkc))dPnRBgdltLy$6Q8e!68{5VnkIKbGE1IAQL@b`cuiPvZYDw?#ZI)eu_ zqePU?Kc=L{4*dqWj4Clw7vqNC8P>w2S@GkZ#t-b;8dl@RrKm~MW5&>e7YDA)+rpUm zgTi^~1UQ-W#e~pQmLjd(xZ2bpUm7507l-{u<(M$^du^s}ec8%zss+GRqT#j?468s! zG=|y!@nBNXgVgl0g3(Ec3+53DCIJqVhS{O+$YBW>sSy#Idx%GI=}T0Y){e^9@rzfQFuP^UZCn*oXhbQX3CLb$;uxUgw&Pc(RE5Mf{GFI7I>4YE?bA}@OYx16h zA)7mF|9~Buq{H60u|R4`ZG9kO{7DjA#eo1m*?GG66QQVbq|fGf$2n6KvzQg{%$&H8 zprgR3{7$;@tmRH^NA&d5RiflliF9M2=nacUra9)F5WInxzkx?|OnipZ_;blOg2O8? zHlE6bZBsvJ);4$w!9h|J0TOzdUI@p|ih3wD^ae#xHo`EH^=EvJ-g9st|C z*ttf}Iv=5nmy9+aG~2wG&C|W9^=+G7J{PYp5&NI3L*$dD=SxQYul%!9^pJKeL9v4_ z1E);Vq+U!kb{HFz^zTi5lbBZE%vLNG#i%oX{t!j!V|fvjz$LuIuBvpw42~!gbF09# z`FsL8+oKZrhXwQo55BQu;Cwzjh{1P!j6v{0V_p=~I|KT-IR7G!ZL*n&$E-WNazM zx8vh*23!Jkb;Dqqm-KK9XV~{n644!3U8Ifoq1jhuD5lZOj^KgZT z_$V3%RW1D~;b;wr_9K3l>r7iKO2%Xl;Zm$f-t<*3VO@@xz3#YXMRO7e6R1$qkS z9FwSlb@oNGFmLF@u>00xE@l~#{cQ4Vt6zUftGQ|)J9@@1KS-*%dLKJ{e?E~_cjiBK ze2-ruyuFI~tDzQb&_xf3h^AyJxYKD z$7|m^k%hJu#EhAzasSFy?n1RSxr5kJjX}S4RW95zK(6O!2N8C@V!e%bGY_;Dg*e!r z(Lc=lSBm5r=8PS8i5HRM7-QopwjT?7*Tv9*%(jKLc_+MamsbyaTL_D2{|crax6Si} zbVm$R*1o3lsJp~mFo(EhX1+a^{JPqPx(bYgP+iwP@6W~BXFooTmV^Z?0Y{-?n{sPw zba0yuPe>DJClu(~^v_i(-Ooid4w4(k>+}?;M+EEGOd)1s<5VOkhX*u;b0sEd({--{jeq(AWUf+!az8zGK}KJNO3a{ z1P6shjk=OvVuPi9eO%JPklpxXC7f4vIfCY68hj z6Z$PsFFa03P1rm5Q3jk_d`b`Lla3e#%-V;21;z_05@HS^S3oXtbK$vhHy7~GB?G?= zHk;4#RW=e#G@pZWcf}n(o{;U}|j&@wY3bj*G3|-xWiFMs5$Zc0Y&C zw$|PnsB^QvTaacaKu~zUWcrCQqgSZ3Sy}cGIe?h;vEjZAiD^o3l?o-VwZD=jqy=t` zM=n-Aa=Y!(ihTW&Wmp}xXa2X{h%RZ-U8T#HXkmv6rq+&$buJ z74tkc4~|X$FMH~5Ieme9l(zT9xi~)H!M8^Fsl3q*S9IxPx<12iB>;;7 z%uklK_+GfyJGOniPnxqmyFuA++^dt@!Ol;jw_rb*-3PgS_-_v6PiRp;ob4>XVeU^W z)q!4v!}r#z+<$$7pJJ|r{~~e*{Y=yD^wyt0*<7)9Cs`kN*SiNsS|GSKX|b;?3L3Tv zbGpfxTf~g(^n^*x2&2p*uy@4T-sBS|qlD>rWuH#M!h_xl2By&uwh|0~)uIBwOYZMi z4$1pwVvNip556B4`s)#iK5Pmz^eVZ(`xFM-A(ni~Fl73Xj@;P|tAAHwkfA8hIt~jf zP{N@h4=F29gho&@=usm<3s{W0DO_ zfFLSRiexd$RVk)MEKfkytKJiF6U(Z~qLh(e4*!_|Jzzd2te0)q%&xH>xaTqKZV<^X z;ijEY$wfY;=o}iJuyu%dh;37T7uGgyjH0ss8W!E8cWAEW*EYf;s%e%%TwON}zqENA zifJi2fcOgo@cF%{Cih+Mm~Jc*iZZArXF+I2=~@CKss@KO;11T zi&JbQpW|88#CZ%arU8m0^CZ`q*a9d)lI-S!&P(#-0w>a#As+s5c|C= z>?cVuLCH*{D)*(wCA2kvuLqvu$l1x<335EiE9r{b zy;aevhVo*Q>_X?5yT1Z~AjiaxYh0D#Y6>?w>0rj^eVCV)o6-NkxMji4?TGBYQBXcG z_D%Og3>UD+2|Db&M0&T1q6UhdgV%~=SMU4c2J5WV9$p@(h5OK>UcdUBQStik9|)17 z;R$5CVUR}38Ibzo(ej274X5oP>jmg}!wS@c6CPl(OL&8y?!BTOc(n<9LSzlk+NZsN z;-d8S8yV7Fq4@Ph8RB&jeh0tazVtAL`;@{McqJED z=P^c`k&|$%Q5=I#kn?I%93rR8cPU~{Rwg_4h+_`KDSX`LGiKB(l|Doz3%#XCl8`^y z@ge-BS#C>L_yA}cV{>St6W6%7dMc|1mQQD`O(Xmz86e2ZgdPJ(7fqU^dqcM{=r)E# zz?BMT&`ew@w=;@SHZO}`qq$Z}Tq``THb6UONWQ|Rs;VSU&Yj_PfHB$!qfQE`1qoSz zi%6e`t#)XaHV5&fnJBw$@GZ7g9W_uFdDGIfvRzlu5h5@E z%tcv09}2cEnWJ_J)P(keS?I!9Jp-}1yI3`C`64p5vaPhG2+CY~ur2fw=ssj%A@K=> zQ;F&&(}tslr5<-oE7z=c7A4S|ARU(5f)5il{G(D8jo`jcoI1zFXPA^Is57{piBaVu^6pA1&jngnQe*1j&8$o{lAX6r} zu;MN1-x9n6222xDvMEgKGB znZM5*uY`*8&#`4dbwPBiQz`}5gKJ?qdPQ2gFU^wuA}fNK8*GH~+`cl??F!HA=H}t{ zh@k9(a`JpV79Pl^G5?Anw1hwDGM&K^Wj8Si32mc7gk4|uDc(^Ip;PpWKhyefBmVH! zn+5WrpFHN8kY^Bio3wT0hOwP{2}`p7DTjZ4Mz83!K_@@V7SxY|<^N6;{%8Hle=%GC z2iQ`BbXQ(R{f5stk_i>_#}@}NQAZX;L)=Qt59LYc2LZrrT*P}22Q?095VmPmZ#T8L zh|tieMxkwK=9DYfV>M}NU7OlmF07O^Z^(37X#LH5-H|38Bp!Onvb*Vg-Ex}Y+2lFh zBKv+EGa?tPrhX*|#{uKL9VEXZ7eVjIAC$$hUEGi2+`2im4-25fTs!`mki0vP{n{xR zOmkV&k>vIAzT3B@yHO~8r5ye1+_oE4dp4ui?cNs!j@qOZ*5r7-x-P`a9WB9T1<|x?jN{9W3|lAjMk2Aavwi;f(IW zdad(|6>u-ZT?0JTePm)!Mc*pSr)tVqj-W2vofoj(+gvQ0k9rUv##<5mC5jX5_t9Y9 zJ$lMJ4bINXK`qpG7M$PeKHkK;3*L8x8%$Rv<);*ST=}nmtao_8w~*XA3Hs{ti-0J% zRd7#W9UfI5Ml@)$3*dQUA4jd)lyW_!C}E&^eRh;)RnQNhnBooWs63+hn7~4Pa$0h$ z?SY&R`6^!za%;pQ@>EGENsbz+k!pTndWNV4TzC;3dIm8&xZnY+!pVbs49pbfkivo^ z31fMd)*x`22vC~-HPzg1PSkbd;Z<u5;C`iM1-X|$Pd*9$K5ggNH&r^*9~j^! z0s8jaEy8x(D^|lvn=qIn`)6A}anGm;kMF#*~l%lp;-8e8f6s zp~mDSmOsX|BSo5ZG<7V7B8K-ifee&NVp?ISa`fJ9+eMn1m{<2R3$ar$RphyZhF^7p zC%foBJk~NMXxH#r74@D7c%o$Jz%!1j8Y5b(MzU*2HUHLqm7NYX>TLrvb6Y{#62;E| zg(v7T5&BGU$TVrkyb)nA4e3C5diVun2rrnAfNGRdfjzy~ZMjYlRFqN{=1Lc=XDFX7 ziPC*Js`Xu#A~7ybqznb(AWChrqWS$iChLVJRRRHMJ`@t$CRL_X)F-iYxr@*1CgXvJ#V_9w zx(ewLB~_E0yoB=KGN9yr>X>E+qSkCCUCCIC{mFw%gelP&y`gPSXMmL6cDw3$BMPLW$DqS&^bC#7DMHtH}|HHHllq=?Zf=lP#f%8g}W7 zkUpd>``$uuWq<0I{yLIO!w^|`n7B(zjMFfqR;YNAWpWfyX? z%%_A^3u(#xFJL$(k}aO#X%!FIzVW)GwGIE;`NSQovqn{vLTYw1<0(ndU$XNMTarL1 zdiSEXFcT49NZ%hyDwR^TqE6UECB^K(3xyG`= zm}x2=k}8w*ojb-;0T6JNoEUNp0}MN`T-9<^+Q*tY!J?g-c-q~eWDAO_D6uY9GTiBH z!?w;H;4GXZ+qO!|rFXxft)Q7(`88ZHoQ1WOR|XMV*@|99 zBFIKYQ9f>L@Fm8&4w%WGVetfcrb77Z%gE6jv)I>{Sw-W`8*y?tvTk5Z+db(fJHGJI zlf~Tuqm~iPEXm@eSKvf>O+`WxB^iLjw*{Lc$9zCqP=mleSTB)Mv}2}6umejE1QJe+j;9?t zZh`DW1$y?HK=5jeC|2yy<#K+m{W1g6{Q<|_N#y5XUc(s0D+QTli)2?;8!@M6;5*yV z=0#(Uv+v_ixL{O#zGPcZ6k_V&iD zt%`9=OA#y84kF5Ie^I;%N<*-qDp&lUFLuW`CLYQdi`>oqO4?U1l>OhySF6j;UMU8w zM3dI0fX0WnXCv47+?Gsc%2)ZyzjqLRPTE@3BkZv}cMJcL&OG?Oc=K}YipkKFUK`Jo z=xH2yZ5%LL4vf45w1c3>kCC{8rN+-61XztmFGt3#H)MI#CI6{ROBvnx1AD)WsBk}7 z3ceLPNKitq)&VLNALS&GR<_besOwv6kKKQpkbBG8d~>ipW@|yTL!fu|Hz&_5;q+e4 zMCV;-^LdPw^2QW_v!^Ht=#z2mjMR1GEZUFaH^0w0c(8SL#Z5&8ymNHLjhl64Nx#J3 z^Q1?5fiv_(N8|9Iw?&gFr_tFH1>}VoyIuY2WaN_ecs|Q^d}rN`GsMO}It&@&vgPkOgpPPc8TQIN;1N0_3q`tp^S;kL zejC4X0M>Pr_7v<1rklH@LmFt^Mj$3TN$L_zRD*nXHXw3;yx+}7+#x<G*>Y2HS zzwsr+%K?f>*GX%dn`@P3`;+ZS zR(dlKxa`SbmD4fbQrquDCP~Tt7Z8bK;PWA2^sFvg4-evtM~Be5I{ZFeq3?t+PaWE-MN1}^OLnv zsqz9`z81xzT+-dxk^bkC`FwO^xpQw;p=P>YeN|&I?)k;Hn&<(%NgKQG&C+bWKYuHP z6tuM7fNO-kanVjxMOMMZf6C9~I7gObJb6Xa%*u$y#z)i!V1_G}wJiN~WpPLD6GCP* z$vufyX%h9ylDu>kHqQCfuS0H2f3r}&8PWM}Rq_(|P_|3<4xBsq=pJD;+Ea;v7mv&! z3D{2{jZPIwr=2cO8D^JAHE6Hm&#D^2TnJ3B8gOX#)#A}w`7mWU>xy|(U6C!Xc5ZB&!td^Ur zYCLFSK`?aH~X*KzcYA-&4;L`E*A{)n?f`T&o+y7$jBB$`rAX%4)i+U=$#e0}038W*ZwZj;V!Z1etbl z<6zGxZKZqK5J?q9>$tm?;+^qp*ReOtyYh^smvWqrpz629c;^yB||f9 zvPOyBM%lnFZ~?h3t%)2P2`SB3o~yMTiKe}@gCiovnsUGz#7yd4nLZ#9dYr4WvK(X1 z*E}Ry>5f?&POqzSpSdQp?}BQ#7d)3^Sg!lDAeMd;U)>4RX!++hP;o5}?I1eRB3sb` zZ4~{BCL%I`rIMZOp&fL4ev>z24^ypGI`mnjb0Kj#<_M{h<+{aY{TVXLind^-lRKy0 zdOEj4PC=M3noT7e9Z`8VR^NW9g;W?=r7NWM2fIucx=!LwaN((grldWKp!-dI>ro*=D!nAA-XnrYaEaL2w1~5`*rmk=vwg34RlK<}N5Kf2>Ai5>0HUIrbn-1Ou&Q~aJdY1q z=_t_Kr!1%Dqot-_Q&vJD{K*=wsW>slS>$~Ar|WMh&LlqElLf8CfJm1!YC#$}ISGsu zN}F<{jSZ!NN$Cv``IDQP7@|tpueEzSCfk5K6o}OY@H18{==Nkzl=kx%Gm0#iR{;&q zlM7s9fyYRwc|l`~#q$$7y`xD(i9h*Awqp&Wf3S@OYt>ngHDxze2KLy@y%j?|2y|<= z1NkLv??Mg@s)}k4(foU|eHq{^PSKI)wJgXNGzB|x)*wU6&YCv4fT;#N>gMCMetAH-<{$s z138j?W7o&LNxs{HYt^MQgOKusG`QiLEj8edoyx;!4LxvEIFyg&a|R>1Ej>@6gmkvhzrlI}+WZiGVf)#R z>r&AKan5?8J20Duft;19rSw4s!8`tQ=VjLEdkM7l_p(L70l(Ep*vK%48ibt>sfhrx$!BPk<9@bD2gGVRH z^ZF~&2|p=UjZ9?N5Q@p!;B_cEC7X5Q=NAbAIX%*UFv#ys;&VUA$Q@h}GH2|54Cd%0?4T%SpG;{%KG`uig3dR{q_>Qw-aTU5 z17_b*%+Cl5(nD&kP^Y7NZja7B*8{>$sh~~}IWO*wpzfxF|Lt}!%Ld5V{dA)${zoD3 z{||}gf34#G-P-+;3OboM{`ZO=qHObHML_Xog|u$4hK8j(E@^IQ0-%{oR*ILXhJ*rz zqI*>4SKBtQoePeYc4AFN$9@A<+v#1Dq{3rsR)#fesm0+CeC78Bld8MoNfxl zoNDl3ispEEG;nUz+q)j7PhHb9+G|Dm@mq{+GVUZe=m?H2=deKPNKDR*JO}3XP#n~l z9A~%Xx*b9{aZnQwT5mRtI(n)GHW3!=XmK^A$0PJqZ+bB0m6+t9pMJXVTuW<&#v_O; z%t7sn`!LjNkrln`9tf5}1 z;ZNn@+v&`Yh8=CWNH2l86A?W6kfja4E4rYYF5zLzsx<39u^=S%3230JO%JirSk4@y z%Qk9)^d}1T+Lin{ZN?`uuMNS-^<~cXAyfdUj_dFT%%!_E0h;|SQ#!Yu<;PH4EG`xq zUFQDoZOD)apTeyt`6({a^v0i;fX7>Q+UU@Mcz*c1QiHFTnshtlNcp6?FbBx=d&xClQgAl4k{IZ6g+{*8Pc$3$M_V!PkKQHTT1$)q`a#y&3E?l`g7@4wj zBS+{VrR-xb!Hy4P5aW(g0Z|EIOfpD0J-)JWyov)NomBkSyAngR6s0X8$>7m&Metis z=G_<;;o(qT8|8D`MoY$0g}74OEFTVWJ;8#AT5>I?Y~(RUS^Gj*#ss!PQ^f~ubCzXE zp@Bnnv5VGPQHM}w(~xIwa?);%P0gcKm&%fpY|NR-%V1Tl^$Bb}LlTER^&2d*TaX?y zr28I5(#79oxhLvv6Uq7ld+e=+kXo+3D;#!{%NkUh1n~GJfTgW7y-vSHXyBt8-hB`iuaB+ zMVM^%D@LNg!o5xycMdc0W>4XzJizd<>4 zHbbjGTMa;WQ1FVDQl8y@)(a)ugDiZHWYl zwyLo~rhgVtY9~kf!;25X&xgm&1;)AQko3jPgMY?ypVHb8uB#2~TQJ7Vmmlw+0tYD*1i=&7Uww2pjVi{CZ0U zc!gp3gciMJpPWG-+>^LmQ+b~5>VxbaP~H$ov`4-9!e16ZT`KuvU0B`dq~3rp?T_-L zJh|MnU_Mb5X`)NrBOu0cSSW3F=Rq8sWghF0mR0DC*oE6T}6vY|8@ z@0SS{EOD%BB~|qrswJMYdm8gC>;DWQtlewy8*+HymUjt8=+R>`i935z>ppz|=#s_# z`)Q?vLs(jGx|#myU3~sW8!+{M{5$%S53S^4==6VlLLq8@-IUc(zimxP-59lXfdjyz zx&u&>GKiJR2}w~<#cejY{fmQtz?=+@B*Xe1DViin z&5e%aj*ADkG{5M#Yp=%{XAY}l?w9Ww-oM^nc|Nwh@3+%h5Cx!k!*zIMmUFQJ7P6ua zk{_ea+_*w6`5uIkWT31lA*jQ3u}!hkFqip;>QUA(L>S8niwtOkq=+L9n#}JQBLvAw=QNrgmHM2uejoN;zc~Md*t~qWm38`cZJbeX64S1 z#3WU~ic5@!oW>t*f@gi&+6|Uqrio|fU~QEp1o$S8NnD9%57`-9f&qJF2D_5wwgw(G zAsc@Rk9O}1f=Qg`DuZ45=kM&CN4Pm@&Cu#`nQe%Ovo<@3Z* zg(@S)>PX!h{Z3BWsHBNYrv(5jEA6Y|)wwe6i_WvbfsM_frQ2yiTshMd3%BjDHLMmu z&Iiiz#vHIgwN~LiS1O4z{Ne36tO0A)?xtt4_N)miacrRCti17{Jkn?2jN$$Z9L5{- zNKy*p4XUTYKq;gf278F0LsidiCX3mrCPRaM)spvuGO5#Zf+6XoK=6KQKilZUdQ}On z`S}^lH&z$PUYKJ&kV)1~W>00fjUM7KiSDu;xREc4OV(T1?mz!JG<4=2S2%_7VrjIbJk|L2k^Dn zV=<_K|Kj{Pn4o$Byfusa2E}^3m=`v>5tKPgW4Q}8xkPP&AzspDtGeEt>*uk-exj+t ze8Q<=#DT+n;`-6wi8*NS?Ko7`Hnxfh8M|HjRKF_mO%+c(lpV@}?F_hR+Kpwxnw`d< zN@u|2F^!H)f#KL;y*1wTS}>TQeP)>%OOS$2*{3;y?exO}n@nN2qx&(~BR7KW4E|;8 zE-9$kuQKPOzbk0#uH1_*t}0ByRiUVrAM2!;d{N9j&YdZ*%F3L@<zn8TSsC3)WhH+SQKTptunC%$!hu^ zc-uhO#>j+Oq-ThJv?uS?-`~LsB*R%nlz(=8XCJO#tCp{d=88ueec~HweSOTYriWmp zx?O=)7J`xP?_hhPX|AJw4hAfYc0d5Re zYL-wgz_iX4uxVW>Y7R*?Cqpj?UT*M{~&(Z zNAd89-XJUYNK}N5Gr|xOe`KNt#?p{>bjB@mk42+XeC2*<8-mY6FV7J~RNIf|i^vd# zV{u$#`4Rmd)kXTa5RQjaJK{Z-ARD_TCjMj?%t?NF9OM-ggLkLgC8WGT59t*jjRAcl zk#PR)IkLef@zAQ>+t)}Bl1RickiY0Gs}CExAvZFMBiB5DCA5W>f^lsU39QjHR6_q# zNqe~Sd%#U*`+fD`1kx5hu@Q`}5H8JuEoi|%tq!X;{zffhMonVg1niiFbVuPOz{#St zt}Q2Xa;3)j)9GGxoeTuacphaO-c-zahJ1+Ej#?Sk|e+j z3|_h0_cRlO`cR6uDY~T<4T3uy*4l32pN8T)F5l&D*%8`5^f!NwzXTDV5H@dAw`aQ; z>%E8UwoGRK`eC|<<^IXtQGd4+<5i}wDzd~fUB3VQ-^D`*I#IQCF9W$deQ{=+#wzYfe9r=F)M-^ zdaG|VXY1P0xp@uv9Wl`{CkXF;6-76qz{W#g4NhH6dGAhL&D`?w`4;-KFxx0&(<|e& zr85|=gonZ58qBCavZ7g2b7F{1i*An~37v}|fPRn&Z9l3koD!mK3yn7`8cc{3dx#b5 zv1wM1fP-B&Ur2;X@P!|3THE6%#j-<;8q`lD z%adN}4YBptrD{njRp)+YI||yEan3wJToy);ic)vB#evi2>JN`7q0deY4?+zl?;i&o zR9{aY);)^oioSl`w3Z+aTf{Mh5L=++~p075Oje-hYM9uxhA35|B&!YbsC;8w;sde$_2oYQ?0m zB7qFe>o!R_2A3GHHR8d!mZEppF~Nh;7=`OeEWZskDgx9LKZ_Z?R3qqzjDud z?a&SQ)&6@&mq@ytPbUi*K|(-KVGP7NVg>ueeU1mo7Tkv>H9; zmV&b15!)#y!5L7CkB&$)S`NkwO#R-qP0S(D5ZG^(`oBnf$L~7BtzWo}+1TcaZQHhO z+YKArwrw=l%8G3@wvz@;nw)GrW1RQH+4~ve{dE5U*PQd7_`&{V1q1tKdw6?$FbeE< znJN}s7;PH;QOK0~E<<)Tq7UVtA4x@K2J1P1H^`Mr*qMzPC8q7f={4xoVgh;Xw4Z>r z<6i(}rk$6v38;#^Yc}nZtec6Zy<5LRLs{~2nrse@Vh|RziXIFHjzybi@L%|80vHSn zLU9=o)-EWv9d5(+@stAKWV_c!0Z2$zCVM1UsN?*>OG}}hGoXffz2}CRJfAb5ji`RA zoj{nSjjgShVgYt-rkwDmdgq3u3P;I{G_xjvMP>D;$Y8rFvdodYEeuGPMt&>Sm1XnF z5sl;|JJnWsxD@+{S?L%NaM%c)fQwdpq9!c9peA#7ufHl^buK&eECaqTadV zF(8&JLCD=*bdl>?HXNGTG4fM!i9 zcYW)W3rOOsxfYp==9M~O<(29!kR9-CAwz&wv$`e?^+qVfh2kQD=2G+yt~dqmF)YS0 z5p-fPj}jyVS86#0frVzw8Jg@+K>0>!L?E4b6D>4a@%U5JV*R!!*O~2PkI&fhe9${7 zmTq$@(Y@zq7o1IY)MQ2Bh^qPK&NSJkplh{agq+%7yCK#3JjlWFBhHG-?u>^`i_dYk zx*a$ZaTlvXKK+i^iVC^P%d%4VoDmVvILK@z_eRBnKTgFA^3DS?g&Zl9ODHNfQ}vTH zOP9%(Nm>XUp|P}&`bFWq4SR{3q|Bdo7i=pUsl$xx%6l z`nv_zstV004KWo97!9!sqZhc?6^(XGlo8V()01h2)OizLj2lQlsFzwKqoM??Tv^Q&rF3tmU$-Tp}c(y$NTEH~e4hSy)F)Cac|VVc2J~xn6^e>kH_6Sdx1p!Yaw8 zti5?*)q%W)=qZtRGLn$HxL7Dy-9oi4pJw*{u@mZ?Dkz4|OJJJtBF=_%V*(Dw*kqUz z%ofIa(Ufvp9nmE4Pj2q6cANlF4r(#c8;q(Q=%^gNC;~|dWs*lPl7az0!q;g3hP?$X z(s^(q9QxnsD~M-FPt3QBbtw^;_f5!a6v2_zqRNUeKqIdpGE^B|m+(E8jW0T}+n0bX zNwbfD;D>76*QY>^;aJpA%nO`M6L0N5-eFgwO`h+EG6r#3mDDoqd_<6hJs+ZlnAmZi zZ-{_`!eBAW3f>wBcdf*3I%?T07L|DerD2>uuee{BN*)}N(kOE^QV*z`vQEw1(md^h zzterqmexqgDJEA$V^a@)7sG)BC+ZX+`AyKOD>Y+2F-rAI49I!8DRe}z-WmWuvPntP zd<0dMgcsd{h`%QGo1?{ofD!fbq<_r);p)dCAf1?Mlvk!X^kideB z%8@e~q|#t3r9|Zu=pp2%G*FemR18@d#}dZ6osSTaqoTkxtk37yMS@itfi1YoIvLn1 z{W|G3w$(+gI@XsKx}DZo=PUK0dG{7$gAi7|j89v>SK9BcSKO9Y-)|@9_8SUe0z3J_~CMn&gwZC1RdQrj~;HwHnjgNOsa;RqXGGsp=^ z4a80oSmZ?@B$pP!anP&|KTI*G6{?P4Lgp(sEQMw}HOJ_(MEGXI|Ljm7v1gbxG23Vy z3eD}vP0u%P@$7H{c#J*c>;C0a?cEvF@5q+lEZ#9l1E?CB@fz;!3WT*rxA#pBX`)|f zG)M|#IeIj6+i`jhB`Eu1jSJ4G%zC;$W#S=Adxod*g^OfnO)VrF0-kzE7fB`rLw1fP z5l!Hc1%C>gp`+N)6zpk?jcKt!y13e6frdCEp{g@-{DhYXki<{csHv2x08%&le5yfk zwUcgrz6gyi)6Du*`PLr)Xcvb1sU=}M0>l=9FPa|(n5*BT`eTkz@%$~Wk}D34B~Rs6 zpHKc4r&1sIbQ2S0d5fP}=lB#ZVnR!=xF~p3jYm?;z z{URF-K~7k!f|RR*zY=}1-`b&IWTMj9#DPH?^#T{0@&aWpt#$bm?POuZazaobcOxFbugdW-5m+~7~g#7W<`hBHqVv%NUWZ?pbn?FrAyIRe9l+tG(g(CEUhE8SZJ)_{XZE zm#Ygas65i-IWO-fHfM%>wc-%TMQ{4$H0mD>QtzJV^at&!LIJafIwkf50x}x#b`|D# z4<_&C%$mYyidb7u70W=^x6na2$4^4-H~Aw(>Wjs~K$;qjTfkeU=pQVM0CRj*%_TKG zO-HXdIUR;sbP4{W7UNU*F$Sz8izt$FFIw=>_dYe^YG6(Xd}i@s zo7$|wOQB#lM)87V@29t9C$1J9V{C#(VY;PZ9X{M96 zgRIU8rG@l%c2Pvl(FN+~i4n^(@DxUDfVV7zRE{ilSSS(g%n>VfTs(8E**1A0!6p+Q7q|3b3%^A&>wnf!dza0ne*y6;xx6lNNvG%La zLMs~yf}JAQLI{ZOb9L^6BQ`83nn7tSc$%wBFDv@6d^ueU9%=v@{Q?NkVF#MZ6Xj^T zAjkyci%O)?_Tr<3$TVY*j4(0u=4vmI<4WdMma zoD7P7Ys_+2D7y9(k6-ngMmECZQ+T{IhFL9TMstzJ|4<={50$`gerr!YQav$@GPa5A zftHmyEIDXNOwwMkc1pI*>&Q|u|MJszQ;Zan^$*j%SX&QXc{rpo`T}@{I9;=>wu=lF z3q3~q2ooTzI~e=Ul!{8-C*d${ONNvyv;_!XFZ8swFswFwLoW;_=*a}*Ac+9n${5&5 zQW6*$C8)f4+HFD`^2>etc-6rUcPR^oN%u77{eA?xxuw}i<)^Y_t5l^>V=rkg!3%xR zp5;G~5=7xl4>aE=3v~@AM;)Ib%CsSLMUR8o4`e z35=V=Q4x*Q{`s$b$%MG6&kn$R~OaGcmGu&t;Pia}QHF&b|n< zJ+gI`fn#=MSfLTkGos76d^J|z>@UMD!xaWmfpiYgVJwn=p36;oe~w;$*uWa|Djn`N zkPYdzgolr63GF+OU-|Ic3^s}gy?VIsWop-H+%{et=<>7<_0g^K=&r)#VtRP(NI|}S zA8RWYJ(YFJLIYs@CHP!n%v?dYZeVKlGH1bCKIYB-|+A~)Qu0}bs#toZn zI@Axp*JSazx2#HJx;qz7Jp{rlFIqRo-05A}RS?Z@JO^5bRp&$34B#(Y3ax1OTi?bY z7DciQRrd-yn^L)&2ztm8`XmY7zmGmc*S<&6`3XgSFiwtyQw;|&A$?a0-PU2WB@ zT+EHl{&h)@RoVE|h(_i|D_>jh;GCaNX=@Rpij-yQ4if5C3nUeXsYJQnFw6c_h}LoJ z@Iy%FOh8tlMM?150soYUu7TyO6mLAp-CAR{oW{9qzc%b06b45`Vp!If+t1PGxM({4 z6c&cjYYDIFPZP@BsX8WLXHw2WPSc4$RK*!#ISsw+RmdOf(b^(KkDbgz*3hlI3Uwjo z{f?2v7Tc^uNojXa5yA)W!^F3$nk6JJGWJkh;}fgI+dIA2Wg`erBtyTi1(e&n>Xni+ z%&Zvt-Cj)2;tBHvptO3IH2#Z%wbBN( z=#4SRzP#>mCX1csYFT8C!`y$kO`y;M;v$KmWUkBq1U9f|BHP{hx_m`fZlLtiY$&@Q z?d8sEOa9{Al0OuH6YXcPw}mKy!OZ}bFFf!F6I#F=j8+q?#J9({D>rS#%=mML_Q-GQ zx8t(~PAc<+yalzB9*n@?%a6)-C*3qTeC996bTw>cSyPbR`;)$Dzk`}-xp>R8kF9Q1 z<;cDTcrqT2iC#5ib?J!47K7HT^#;v%{z~@1rnX)Z!OoxXMykqxGYhU@RYe1GNtdOH68df)eJ zGmwbBfz8TFd9G?8JdNorF=0{QXG`TO;}eLKD-fjKVykrf!z^#{20h8;RB5iVNLCb4 zM}(_l*P0J)gakjWX^SS#Dxy%*fN04H0YtGuyM~s;Q%PD{6fca&l5;P*(8ffG?Nx6L z*Trke73YLaTIQt3OhOS+EkA{g6(cqcM`CSnX zO^-nmrZMJFYYgo;94{wV{AP+MB|evcO5@d52e?l91$Gz~;gyO_er{%3xpb2C44Uv& zK>^X$Tew=THQB-Q9D}d~sz}wT-y>!0waccM7LXKyg9ZN48r?TK?$i3eJIsNDI_U_Y zW$PZ_qKlKQ0?F!f#PXRY@fjMcC=@!*sIql33RTWpB?<`w_NdoC-*8*&d8~GNi%G@;=1T5pQ z6It7vK9Z!==4RL5#kG7OOWJ>eeK}*g`vt%UWuSVl z__B*`;L--CLn8dtkdE0Eg5<)3SYVS&F3mgQo4H#VHY;Jh*I#Xc#@ zTWmIpvjSpdZV1}*eDTsn_g=8~4Y#=X-CwaBivnpo0-u~vG?~MZP9M?q21yM@j=dl! zyf6fJSo{ahpHmO~0kMKNnD2ud&(N9`y4%LW-4jJ-g?idVdt$E*SV+E0<$a{=zrO7V z{sYlb>_dlG|B2|3`;Ul@|GqR-GIley`d1Z9)v$F%`!wm{=rO}f69N}6gxk$4OAjoF zfJ{l#C2tX$D6MUmcgeELz6jfr*S!IY;6!F5a#M4|2RV<-a3xKz;@l<^y(!1dtjX7x zKngza|HG;N+I#xG_qgQa?G=qTgS}8-hFKn5&7?nlAK27*8|1r8?5oolrYZDL1PrcFBEeO_VvC zA%{|=aglJ!b_tEmYA%a{{}|9tsM)IMUD9GL3=%Fbu)N?(cKlTrc=woU1pYAVkXQth zAn|`Z$-H$LGd^2w_)$~Ln8`}7D|dvb$we+*B6A&Ri$@VDE2DSvtR|77H^f2^@S?Yd zT$g{}oq^mo)KHLtn%P9#j@vNqA@Qsd%J)q_DKG4}K~WS770!b{lLq(Es6OnQ8P3FCI;o&;9hhsj z7lvj-Bc)9O702U#EJ6ujPxHRfCIK5iLU-D(Q zzAFLiMH77KO}3rM+oo)to6(&I40LDr=5UQ{M@bi(HHSpZIcQg4-%Bv<$yz(fFX+BH zL@f1>rPy7U1cSq~6HIO_m+-yq`-Te2Iltcp395g6A$P${sITO_%RN|y5Ep1_d3|wD zkP0=G^~06vzWNGwi?fI*U;O?R_sUgx;JyWAap7@3&nP%qYvyM#mQz8N1>OQQ7stp3 zQGv4n!-4lq!PoB(-CW_GnbLJRHuc0_NL`i%-=+#8U&BbNX=YCh2w+`R2C|;7wRmHX z!twEFBE*)}8+v&FH53YEK`#WHg^3=>!g>YB=|A_8eVF8?$;9x7W!0g4t7Ect`|jIr zR2+@YUet_jz)woDMs&I4Wi^Z6Z|Qh;*Q zP07TqYK_oBwNkd~MpE)L#G_ZN4~ms>wQw)6GMe?@AzBa2XfaW}@e#4@|1(7C}V zddBU#L97S0UyNNl;|j9u0VLiK!29TCnftdBHOsNCy|!v@K0rL(h=>2Iyk2f^Yh<5G z=4!bAG|c>WpT5t^YbEOF;9>6KMlNscB<|qm;{ESJtR}0vpoISJke!4|YEnuiz(hJf z4>o{Rv;z-eURFT%+#l+*u|02;?Utn50*`f8Z*)3dJ59yKQp}rsE6JU=!LnC8ZG?H8 z=f@p?&F9ej{o@(d7{Pd12;qC}YRJCK18w4LVvI?@5Ck>2H3F^~SIv*w;fOdiD7gn} zXBCq26b~H`4uL6x&cM?+LgOTy;h{%l*TiG+1A(V^4hcDb7^b#ca4$-j+sJ*oy}|C! zqK4ArRIu!>`7}PS9IVj(-Z69MaaYYy#<6zy!lUt`1cf*eIj%Y~MivCX2iZtJfeGi~ zA>`0i%zo614L9wZcpg1U5wytkVkRg#KvlC2rAdqY9mSwB#RlQ;)J2xMJ)M`jAix4Y zwR|5-VrYC-jB`5kWKaOjcg~tLP9e-xej=-er}XV%A*VtL-khC{#UuTo%K8ix`bVaR>klr~wbT zo81v*jmFwxvB$%}oU`e?@_OWDu5)M+;ZS{4a}F0!H5?)Yv6yn%!r4Si3cwkZUb+t= zI4ZN?+m;J)N=6 z!E_Ps!#3aP9C#q?gGW}4oSR#T*r4`@UxfOR(3qm7{Rb<4mE^3{wg_!rF##jhJN+LQ zY<^v3pZ21b3YcAc!Q!~>V#5hk63MI$+kkaJ@>j_pT5768@2u(=h4rKeXnP855Q|Lbdu&EeLTp#l(-#Yfkomyyh_eSMbdLm1O_UEzR$4=t~%% zqn@Xw2WwEn*E6t05{M)_uxP3R_(DV!whke3^cbVl23~1Q4%YK4I`W5wG#!jqt3HHf z4LfH0QhH)Ly2`*>k-sPDkE)lR@c|F`ioOcIJ__;t>%Nv2SW+C=AFHoNJ)YO!pWd%P zzORED$NcmR|3QX*gX`g`O_$JYCFfRl{OZeV_ z117wOju;Z0Un#frg1xbT4E)4f0-Rr|xBNJg=J?4@dV|SecRchx>kTa6U@~3CCz)+2 zX;Wv~UlnzleISp9C*>5yWNmK^_)Rh`Xz=C`XiX4He%qCVXr;k>vHEzjkT89?bmRSY z;4j8=&V?|Oop?A|4pRs+vMX=XjV@s;2FzQVCrKb(YVy45CP@r#inc}QLcWzL=S-Z& zWG=H}YF{ee@BTfIP}ZE5DI?APoVF~a(ue)s&RQ;I$yujCQ6-5j8gMC`Yz~x)8yhbXw=C2ixD1*Oh5b)ovSlPy}{c8#TW ziV#ali)*xVtifa)T(pEWA~&v0E-4QSm#s+v5MmM0qQPll8p`xVWX+v|b>+1s)(JsD0xbNcPp4tx+)Cr?NzB`|rAe@ZRjTbSZae5hcIWbC zsBR{BRnn1izjSq4TN~;ZcH0f za%>k$v(Y8}7oKC(umJQNvAh|4jRqWD2+Y2x8k5^{bU&hU@))Y;uX$xoSI%eB1J*f( zETcGM{^R$sUl?Z1e!f&b9yX>H|vGZ5wUUNt|$cWScc&$}R`%8(5M<(|My(gD?K zPSYB@(z52+b)4oH9_B2TPVJ`9PNM-u$AEIHzqQ`L-2ET^o zwLbh;Xi#fk;8frOhZLdk=0vIQ?@sbvT=G!aYRUX=eV5!N zQvkYh@1`k;Tfxx#=HfQZMNrT`PeKz77MevJwQWaD@VEpIy?U zbel|(u?y_Z$RKs5ZqIps$*Jn8$=phSJ z<`$@9g)_Eimo;$B>2sG6Wp<8W^;H!d8;IyENU{#8o5K~cX&pDX&Rw`RnBo#?zxVhy zjrB}V$p$`e>DaYyIWpofFutVidFJ$_vyn|>NTmDdOjx6hyl0n|7Oz-0qdLkYx zRitq-4AuxAEefpnH}6zXCLAUy=DQ;4^IXn1x9jg#pL zc_FpzD$F7E3|0xKM+f>n9!-etr(~GZkrGlQo8zhjDBARLpwI&VXnfrXlJYgDIC5nb z%n;o^wfN%uog5^mjOS^aZVs$bI%};}xE1AF!;X zMw<=fZuLaWESeObd(F6l-f9}=n6L`a*vLplyI-XvjI7AEbuUnv8b2uvB~FIKT0@>t zUfDX!5jmCQsBW~_TXqyJ$!qf%ZNZP^`c(9qkBBrIOYG;!S>*^O6j_Vn#U!Sl*f1tB zrXitb<3cycHkvWe(TH+xg=(~(ObjW?`x!0k)>7;i%Z4PNwC$GD=BuL;@`pm<2Xv49 zM`X`4*40SgE%AGZ{B7;)6;hfF%92=`DT5;$N-XV(3uPdaHS;%dicE{c<4DT#*y~<8zE|VIPgv%Cmv=%5^}~A zt~VTH&R4ke>ZLNGD)M`Q#h-W|XTVKt1j(F_cApzkaPXeRAmO$sxY$d2vzIQ7==By2 z2ZY|T?}eDtcNXAHbfSC%XOMcE6|-XgrZxhL12BJ+%iui(;rVx;f^<<2BHcztPqjrw zh<&8;mxplp)8Rn&w7IhGvK6f{CDyUB36II#re!Q6Es49%Vj`{DEfg&sCf2Oo$t)Zc zi2Sl+61wdwP&1w8fce3|7X4sGG|oGi#Z%Alyz$qw-Og7oZQ;jfUIX6vJCacVte>|#W4$s#rWiS>J%J9!fb)pk8h>YW-u>qNI@ zD)fgG6n0f==Q@iFT4LY4SeSi!H-;mb3##>(A_8~SJ$Rm#scw(c=sOZ)eJ3CvH*%-y&l{DCm{3oPL}|^Go?ejB`Ita?|gD9 z##r2?&Amf*w7LUtpQbn10K;>)nf+T=?J4Jr2BeoIvTzI~c#{c@i#IZp);?Ryt0 zia`LuD|yY;?WibOG1+YwS&09e2$0t+UAgARieXL$6CK9T;4;oz(tO_d7C3mKm!FlV z8qhc5#aRQ$-7u-H==n=Z%}Stt?>oMdvoLYq*ZZaUjcSw`C-TNX+4GA4r6HIdf%CT&!1UD3WvJkuSdd zt#8_iaSrcK;EBpFC$Z=&Y{EDM)PWv075h{z-QLnesOs zj$GO({~8*rJuM@O18iYrsUZ8ID&|f&34`)|%H#*%H(`<2C<1C7tIZ6mAL(jn&DvqT zrWXl`2S4WPw&oQkv{AFtiVyt{x;vVe-GmbKIS=_d=$@&A!1mC;om{ z+y|sho6SQ47&r7AA!J1c|Jd%+%gwzZu5`Nv=nb#9d@<;^eHlt_0uWT=Bg#~V=Qm&yi(zKZBeGo|2J}Zht;7Rr21lE4n2gN8!VbzH=|8mZFEhQ@we`r07#b zqNO1Jp%ncpE;YMZr3J#UBcINSR(hH$eCNZpn8VhZGRKr}hRKmQzB^~v+f+=i6m6I+ zTHDgutZj|4V%>-06BbjPk1ub)RV0hCjJSY#+||Y(c9pt~1dter@E*Q!;@{apFV7P) z*JlF}*=YG-=s!8WTU1}#e$LuJ%87CC>^1j1a*IPjDN*Suldsszdm4J5`i!Ul)`UlWRKamuNaIw z7F^%UP@$%P4TUjhH?%{HG`3z;8b}E+I+OJ)e9)omOmc9tQS2Y+HSg^obwm=bZb4PNxA&*`aZ5s z(1*Xt*kcfpKs7{$&!P%;HAJ0n&=q^mMtI_kv3A7vRc&!i;M@=z=K)sX>B_aum?VF_ zu+WINj62&A5Y!2Tv6BY$s@n1VQ4|dt|DsnE8sC6Pl-x=5^s*EtmDIv+!qzq%--sl3nJ+ks9x14)->J=_{Z&O{q~r<{}Zf!{Ov!r2R#4l_JCa2 z)Xmz_LDb68+Vp?aZeo@7Wx+mWZ};o!vdY#xt&znllwRj`QGTF9%!x`M^T(c-=$^++ zPQv}I7Kk9OAexPjx(fSE%+H4Ov_JXNa@t%#!0^|u5xlLpSH=`c2shHbHl11HiSe3f zDhcbJG9ALu#nKoek+a}l({X$4H*?4Ix+f8w_3u#S+Z{$ux>dB;GJrz#^4kKk2kvXJ z9|t~z1~I8e=dpsVO}@fx8WZj6HQ>(Zl+8d^6sj!@A6^_9;`mCircve;fI9a4h>QJL zWTVYV;YdTV+sv^j;X|lnYE;Zj>2G?@c7132H=^6vkp3{4wm&oosOiASUMITJ+1d!a zTSf(+s~E)IZJnrzrm~;O?TboK7gY^;n&VrBQ5DqSJc8Rk20--I*CkW1x~|$ z!rn;ns7%M3#630{QyX_VccR43d?SHmuNTc0Sgf(il3zP|JQ(fYPc`N*0VR}%#4xNW zsuf15E_t&EX`^;m@c(#H9wnT1+fQ7D(&x_Y|4mjC`QJaOhPjK0qpP)>x170$x!wQw zX;t)XKgkLF&C(oe?zXlze=BNRbxJVS`DC$#F(Hj_2S!D1tdlm&=G@BUC~5y{Y7jvb zhW7p`9?mxZZCts-w^`5qw8=^&81T2_N67b!hdEF#p-;#8zCqyY*JW@%m=1}ZITpOTh2>XDVxCS-fJt(e)6=V(-ENZNKnEwu8GL5dlI2QyYShMFLOb zP8%0krzWY>pPwY{K4oU0V6FP>Mar~T7I9EH8Asiuqv=kb8e3B%c<81k8Blg5XVFv2 zkGGIgHP^_{yvF>lOw_F$HCd75zEuXjqR7o#%Hva-g~l?k@;=}6-qKiebNVqh$RVgl z6xi?Mi-*sRe}CAZe`J^3V|2~``psDYysqJLItt6qkt9cy^GNB5md6k?K@+CoPx=G5 zUW+YnM_@8nAs)ct1Q?0sv0sAs$9XSY_zf`^7?ggp!}0oUS&LhXI{=PvnC!tH{2#Gk z5yy<0^BD_?|1lQ+JI3aJy8nMIUQ0DkUD4H%KNqi@&6#psn89MmX`-ukVAWp6FgB=Q z5}dF}5HRD+Yu~$YRwwCLo4@kiY6u~BGa`$F{}ET_P%o2tlfW=fl}uIF(XiHjCraB& z)=ug-DfB3UmV-z&kLwyTQKUeJz8+mJX$NtvDbP`MfmEvi+!M`Bki zhSA2nR%aA0qlZ)|_`?jQ64?yK8Zr|ZO6`Yn#cHHJToa8&A?FX_BT6(`@o!z~EDqIL zU&13Ndhci)1`~q$>6p!UKNL@8jq!wTP};w{}-(XKu0hbC)KD`s7}t;--Ru7$u#O?WR^n{rdB)nk8EoM={eG`8dzBBf?(l?7kv!*sgV3o(4`pFD z&S+v4TxGl@)Ie9lKlSi2UKXp5Np9Cj8qsnA^OQhK%Z)te=I18fX9ztXc3+6?>TIT^ zSWxf_A^No^?G&?doBU0zy`dsXEK(Mh!?5`_seF%H`M@A^vMVKSy^WLF6(6EdEj7`> zxxN1pH8ahlXS>Z~yriq@3YTo(bWQRkJS$0?D4=y?d_(%@vQbNQbkqd*7esoiB_{wb zdyPnP*pl4U;1-<0qSF^>4E*^U)Ni(2gS3pr(nfzU4hJo+%99e??3F!&_&en#F_

    z!~+q$wGyw5WFC)M!J=i#=94&^DrFOt+1+#!O<*N+a^!HWMax!~cpxR&@rP)^ni;|y zDe@Iq2VGB%^nKz_5>0>-^JxUPHO@`-HeRv!zWPIWUaCVrd1$eTqu1EDZ+Xv+)+Ao*|Mpfz!7A`#8)sl&e%3dcXfo}82N1!iwZ6s(_N$|<#M zuCoHiMQC7bvV{RjC4bW`skmX<9vZ`pbC#W;^3mz#9h8D7R?^ai?4^N(D(F^!1pksc zod=wn2OXBSUrtB^wk?jJOKZDWmM&DpAAD=Ei>@{*Ebkw_fqc78y|ERp9Wbpj`dVdLrqMlbTCC}7o&8MpKk)i*gb(*xM!UOI&JyU?Z;l(5G zFyZ`)c98dy*nMm*1J=9D)181QtxS|DvF1&bPOXJ zox)6Qi5iibD|+LqgI)rq7Y|pI3sV4{x*9|MFu)GJ!IW(VX4^Q;`7=Q-4W&L}Df#E^ z-zoq>iIRNMX0(T4A8;jK(@;oUi<Gko-X$gT#;pUC~YWycq>BGU1Qi3fLZ$$(hB(FM#H z+ZK0F)law|ZF3$u?+iXT&&XKRD~qw>24VqkaDiW#s!R^d1@Z;TfSmXnas)JWq-ciX z%C!o9*~}oBmNb?VYaFT&sNrk95t_bnu#iJ34EH>UN@2Q??2%%ep}+@yxA!InWs;AG zw!i|t`HzH?zL!VPw^Z~93@82p9>7R_jY|Kf7=I50d`FOXL7?~k?o^1#1J@i{MqF~l zg7}iy(8pY7DPX@VMZuK{HfBvF`|NMcazii49N;Dt`lHX@8-d{VK*3Bn~EWru8pc z^q1iDFC^$Q!SWw+c#8wwLgx+Sqp5tGi$wReO!R~kTB33w9d&#MyZ_WexmmY?u5|O2 zUk%ylS*Itnq;dTk?|H#It`Cl|R4#xKXCWwWqZ@DaJ zAiu}i(`lo?ItQg8M~J{ilk&&xG;6E?^YH%y6o2U!l&Qp>M;m)Ea; zk1jt~^(G{W2)^Y_IwUGzJ!gd}2%e6CCS#E)Fe=JW>toy`3dm+^iLI)xtm-U1;0WiB zH5w+YThQk}q0=r0;$-Bm%RwGpV~K%C5%SQhriUDE5_%8b=bj_yPF2tcOvX4aj0tVs z9@u%-QiPN(xr`+tnYZ+}gp|g6ugMk;*~rz+Ro%vY2qB&6Y*+n6hKy^^>OTy#^CT0o zYK?8X5R1DGZPC8z64qs@7BUp|SIOhsBhD>*V z3!()}URw7n=3rf_QIB;l_EyCeo-`HH@Y-+^8S+wo);0U}ETeHX+FF#@ORD9k`6eU`#`!%ulRL5`pdnoHu~J z_7YRr#qEL1I%kp!P&e8$CA)N8GQFk^A`1~^AQ*z{m_Jhv zXI(*^@+14HOA!|9XI=!iXlw^l9p{nWXLzukk-tVlR*-~GP$iVD_21_GV!oS5m`(@f zk-iQ{M%S*K&?7eGNP&($_R?Yc^$ANE@DR*cG1|~N+i=`$(9P5~WK3zk5SaJ?yZ;CNf zoCTsUJ3|Hx4d^F*?2ue34nbkv{m5(oNAeasQ|Fj}BEGdg6Zroc@{6xc`=_`y%A4#h z5_GT<pzK+QtGuq`mred(vi|RX9>FoM z3ik`*CfpaDfFtUXF6K_PTKbHWhbr^gH> z_F^taLE;+s1v~7DMmS0Q3^w^YA!{`3)V^r11n7FNoQed<$|nJ9Rui=FV8KXtyF64s zM~U8M`HT%IGD^12#-pjRR{=}is(h&t4doUf5n|zKZij2+x+up2TC~CO0ZQs!lo5aA*iCgGR%d2_iin;qIxQ@%7Vw*sVpF+BT1a~EZytxrV> zKFEz8Pf-npIh>b%k~oZUEB}FfP=8ZBd+8}ak|WI!S!Dt@qziD$_T111oSAu2yj zi(dC@+y}<}IdsJpzN^B|dz}u>Bhyi z!n1JWv)#e|RK2Pao2fj^iqi&n^)di;7r{dr^he{?;c*316EIT$X^ImEuQ!q=aG+|< zhH^009*P3XnQN%pWe?*xb$|;e>F6-F*WOJzBp;-mZ_XWNgKe)-(_lKmnVEu7Ji=Z# zpMQj=#16yMXGCdZ(O{zvaZaM-$n`J;Sk!juY+Dsh<+*d8s!N`wyw>JW zCe9X%1BxB%!=jrn2W~7}?5l>urrm&WP=0CdcI&%Q^PcTexWoD`P634x7Ax@rs)TZ& zjS;vpeCT;THUpc>7gP$8x_^GG#Ee=2c;p<2Amn!gH$I-IWQ0@JcX3_(~=^u(=!@PX(M4$;=?v5w!E%r1= z#=dytwyg=vKsa+0hlx@L>Tfdw*+?N3aJwe_Gsb}TCk0x%JGhOYG zj>tKCncmKo${3YKI`esirFN*Z5q~^W%`p`jf5zu9%;$MF^)Z3`TNdgR$|`mVlm93J z5LpJf_6Z;RO6*|rFvA1at1p=i7311QDk>>EN^)|%TU)%AUzVH{& z8$mv-_S{ro{<1&LN)$Q8l9@&aX*!Vj3(gkrATC0OuXl%T-N{>E+CLLBT<(p&A_ny5 z2rEf$Z0*bq^cZP?`Z!bV)YE9PS3S>T>ty+eiGGoK@IWiOi#z|V5U4@hQbPJ*t;WO=aa$4* zBs$@9VBiS4stWx~j$#1VeW@()y1aq25j(jj7qx~_^nL!f^3C#dV`bjAGhpVsf&2fy zS6w@OiJT6XW=q^1+M>#z!-0hq;8IU3KgvW0^ zPBYx!O$3bKVbNLg9ZE3YGhry(#Lbx>@4Ee$3{-6*{fxR)Y`qt#_N9Le zIgWCr< zq5PC?VglUsG>MK?ZgS#!7-9X0a=&OgkpS;<=!P(UZo8!KB13{hFki~Ic7QLXTLW$% zI_iXEr;+x9TN(LXyR1z_rN*4EIg5L{`gS=Mya4Jtzeyeqmizda6670G_8 zlxgM@2kjMmnvo$dtPi4y#G*Bon5)Llg#SQ=;qM>8;5R(UHxcK<)03$q-xC^$J8A^S z1#{We+(A)J2>QLuvt{Ks*~ovI^<+GMwkU=5|#$ z*hhpYVd14=+Pz987B^FrF4GKuus|~1!)zW};w*-VLHIZ&K#TD3(n zEt>W>iH|%THaqmfUrg;T3~4Dc-fvQo+`9vLzlRYQ4u>g|o!Fsc!1p(QrIXo03q55T zjH3zc5UNnv0X~J_EzE+Ou4tidAoNH<0VFN}5dz*PrQfy25UidgP&cE{`Br;VGr{Dl z9sus6>p^uNxgsURAJ3%6!Il~gc+x~~*N|^CC-pyBfhFwCt3n>X6OnufwD^*7t&V6R6tOmD(y%w3Tayj)APxgb4+3?AXws4xT}%&H9<(~3*N z6~;ba;dSq+9-f96FL_;u&3eECXBu zEWjKB>oH$@>H(eN&vl(W(ZngAb5Ip3voi^lCFZ6WOP<6EdwqzJUmB-V>FG^)4;nKl zSYfXi7z#3cq48(p<86|gn=a~~TL8yTh{%FmR29KWmII=)9^KO}Tq|FxgZqp=S|nSD ztOeJpi|P&H(~%ZiIAGXW6fZ`Nt7d95PsI&7Q~<$&8>+&Pk7udu9PJeB-SU z9?=X%2?Mi?9c=Hhb5IS41~7s-()q$=&l)I9$ItSM-?fyNvu(=4lXT0c1{+8SI3VlO zBn``fWjPe%wh7{i76GdLNwR9D0EA5RUAGR7d^gBFPzIIY63d03Blp0o`8ov7M>zpm znrE>HGe0D&hIXqy#wY(bw{zljn? z(}5VZ+?o5FdSvKlDBU8lIF0c6*gL$D5eO6Tt=`d1c(#Ne%#&ySrjU<*EWE-DOLU&V zj4%Q{+O@_tIFm`)w>gGQ2@>vOrufM#_{?Xq)1B~kzlE&@LG!Qe-3f;ps=wL%2D(64 z?lsb}A6BQ(;zlqf&LJxn0|j^YcqcpY95a7D0=Jj5G&4zgQ^#s zP9<+jCo~S$hsKsZ@02!>VDkZFy1$Za#_$-1eAa|USm zqLHt8>v991>1>DZ+k(iYkcaQSWZtsw81`Y^yVWi>BIAw5^piSbEw1`kT4)4f&WE3& zWZklV@mLM0FPKbnFR}U8kK9h{8EP|!t+rzpx>HN%JJQNLAyJ$RX|@t&QLC0JHU^hl zLMi|2ECwBdH`pERjmURLD7@v7_(0(J0GaO7$pYGuhPZLDZV#%t6E5$8Zv-Ggwe2(r zV6xp??z?nd{$)rCPq7x>3@kJF8zH+Pt7>b}^ReUai$6Z!{=ht_pc$&LyZgcAEwF?5 zsb{q5fV-d7m9rTrbeT0TwQ^yqGEm`Y$Y?C3taJ6OJP-D%3d|c8wPPM>DXJ&N$?{BBgMYWP&*8ccgkm zcFe7ny;O@%5kztL*dXxc7?q|Y5*0gmD)Nw-G{y?tvZbS@S}!zQE~Gu!Ar^hkmWrhM+bPcz%}`M63`1X7S)N=|3Op6JEWC84xGYj@ikvRkY|40? z#W^F-&dGE2^j|`d)chnjH?sPL#DK}@bzvIJ$piVLh6jzEv2~X{ zJ#CCQ4N#x)u*{Y+xYV#JPvB(`x}wxrSu2(n+(Hn%;Ex(%gq|HZgg&C>9iyC3UUP8A z(hS%vM&kWYd*^y=#r8-O!t4{mWI1|!?k9S^1C1?|@`C{yjHgxJO)NW}*8X~>#dcz^ zsXw9Adp^bB<@*t$DHRvnVD(CTC^2V&4?M)P1J2b! zD*+!BATP(@lL|=H3O!g%8yy7<|- zHFs)9(^=53>gUq#i|CJ`G7J3VplIT8e22Av>yvi`J#IKd^Bp63+#`K1@e@=)!_ac_a#3D!fo z^9JfkDT+on?}vN?4tfpyod3rU{YC-olUr2fL<02Hf%^mQLli?0a8pa{{gyuYDOcvp zu!9Nai=Afxak@QmDtOY3ya@CQF-QB*i2LM~{6Yh}TNZlVM*ax##Vz)1?Z8Gwg) z_m^lHvRxiIF$j1-q~K452XnVTq>zXJ41R%6pQ_r?!UMGY12ctsX#kl)xoeM0J|467 z{ev6OMKsD>HWV#n3wtM=Z;R+C^M?^>F8Uo5H1dZ>aGf6B_dx(XX3xZNAz7%0X0%#J zpI`?d)Pr-h_xpw(E?HnbE93d)1h{W&*^5XKZAbNCbpU1QncXQVB#cD zS(-SJPO~26%uri$zrLU<6o~D$nAIXa!y;EV>QZQuoiqPan?RwwT~`|)M2pG{y}`kT zJuIEZ@kRKWgFX`&&8FhAfi?O|B2&?9!CO$pCp2EJr3{;WtG4+7fi&5wKb-z$6Ptdy z0fuacVAk~z&68u~U_0OBU(cp&7k=pDX?YjL0LzQ>=IBpy>?m1+B7Oe&0rj6&dMUG> zaCud8z*|+~{A%grPPo%929i*l4M=nLfU3IS%UP!v6ga@0XN5^7#tg0&^pOI#rEs7S zMe53oYR%v~NCFR##p&Qa>*9|UtZ8`Z zF(<}iOIab2At`u@fEi269yT(@zz|HN@rrq1N3%c)1STIcnYOyjNb`NPCB7D->H5Vi zgF?*oQ0JxT??}pOt>Ea!fesR_j=KrYa4*04oFKZWf80rQTB@2U&HG+|tB)nztF2oT zz$<=-Iu&x9M%3UIW9Sz?7xC%`>F{Q)C#R5#FOgh~3KtYtvk^K_n%@TeRyMz^X-gR+ z4f(0T`s-qL$;yHrP8~)mR?3AeWW9ndZREBfqmw=V-=TKg&~1wCA2k^Ez_un-dQ1)A z(dNn_*JX$de;-?y^{H@ z!$8_QO;vi z3JPUGSam527K}L84ZA5ps6wRx5$uX=&uh{mW7=sEJ8~WqzSGZjW-ntg**E>n{(o6SMt8pDAyKT!3&C;YLJ`(kN+&YL)M2~~;o+pVoG zjvV57cwid-0b)>l6WUJMw+`s>w}ZctgY^rtQ$LY;2)_Lx(M%tXiE>&9Te*R|(>4IJ zgnqSOBjd+%26Z^&{%F7K{xBC{xN%tx9 zvQ4O_SJjIsn8Rq&OzZ%xRDee7K_T#XKigxpKaev3*2_R8XRx+nQiK478I&!D$}XEPPRg7*x96E#L!O2+ z(#s)noiNoF3RDlmS9~TSRDRa)k=T8EHU|A{8+Zbq!wUXXpmGk;7uj!Nr}s%ZF>Fpz z*X@H;$tb+^z!L4E{|pj*JuvkbXg;Fc{I=x$;L@5!lL&N{@mpH4U^fS57NS0&dO0-5 z1!hagZo|I$W?h9s{VpZbXms(SeNaQW7xI+b4ShBYo}T9}S;ef8L9K=Eg+p_xcySl} zy$TlOV>AMu7o3yc0TT_veX8VTKqdbUL5(4!m#jejBBmy zBL;fFtHWA}A#AxnaV6)Oos(pW zGW2=`j$4tMjItjN6ziRo7)Xj#0tUeVg0UrbTVgaPk~7^0NLH##<;pXzI^9J8dQO9e zH6!5R{=cF97IE1rzZJyF!{(q&L483zoZAvybpx^>hErlDC4E%SCA!znORFG@^n0~$ zSZBM#i+efCW6;^$(TcUE)BHBQy#;Qy>Es!Fdd9Fb#_P(COi04YXkZ1!gQn-*9U5ZOUxCQEn-}+>MFwAjoM9h zMHOxdT)r*^PxYw^vC2DPr>!v#00FF)Tn=oda(Ocb^E10{1%G@!xTPtUnfRF|ZM)}e z?)<#e`H;rR6oMNk!X?9z76ap4WVafbeV}r4wE&N2e`(B1-XrBNd=Js4&chxVn9d|G zro2+LwVG(3eLgv4P}UJCrE`50`i6`Zk(xp0!1cmYVY@aNKgD*>Vz413Zu3fHWi%LG zs^M_vFrDL9@p(N=NPoXQKrdE#tn|_}@V!WtSof+0o-9-% zqG%R0o8nq*mE2W)O&DLdB+SR|Noo7?UfmP=`z}T?UY970L{43U1lLU?oz|}(kFT~~ zKC#^bzha>-QS3;Z{x(7zE3RRU{sS57rI@_g0Q1JG)H@i8IvHOf&mB!k#W&9S+vrIJo6Ypq__at*5WG-Q55p^FU_@f{ zgW?W(r}PA9TSdvEwT-ld1aeQse>C7(kob@EPv~ZGjZ4EPx@IJ@gzkTa0$|VBZsq4$ zRf14U3Ly8CHOkA}T7CpKjStUQOTZm-%5$N*PZFkFRwVldL;|O}PnMm;t18;8s@TAP zz`pl#+H+XSbF@FXrQaJKZ00}oIC-AXupm7O1f#zV^^%DaNN}WJ;rc}&-J)vF85F?E z=YZ6%DGTx*xUY1KQYI2lX{4ig;tbfF0Q&hRC0zNRA;{U_z02mPJ`gKHK;Z$a8hSO4 zDoG&mFnsB>9q~&K=wzyR4CA6l0#L;c{4>3i8(ei$I(R15j@w_3u&M6Rndp6jm~m?@2e{xf&2&ifPY|;!fO}8F|Dv>LPGp1Cbke8sL0z> zt%JDna9c{2Uz+H9mHs8)(NN>u&;xk`vAhwr){fom$a^RQO zS!nFYO0!bmKDN2jnoe=6{>#8wuBi-o!3o;qY(bz5Y9QYI09{@R**t}GAym$HTy})M z_!MMj?68VF#Z5m-GR1GSf1JDn9;zfWcs~)bKm;3%iB7#Vhvk)n!<%VDSw1ErM`=N< zg6V9_;iAtaN?%r|96CMso;LJ$r*809qX?-fB|S_M+m${6xx*+fC4*{Prm1bjD@P&c=_!w-maAi zRuRSZe1lL10G9$|^{lV!1E9UZCW?zl1T%5wtv_` z$ut7v9)$iFzWQ+eglAfX^E!`UON!^Z7=Byc%boD@nD->HD|h;q*fa6E*zVRxcL?bY z-8by`wy-OJaM0<3$!=%nJ4K7m?s$Yd)Pa!j5d0lo8a~}nCl=WQVrUp1Jtroz2GwAz zNv>md2%*{pCHFK;a#iZ=MzM0clZ{C-c1?%GWD9!Xy6TZKVuAdPW9==V)Lccun2bx5 z(2_pYBat0RYD09Klm#+!0iT+2{^%Ua!o_N+&a5>cIB#8+Qe2p2ouV;<=C|q-c77g1?h& zPBYF43CPXdRysp&Z||^@bKH;Bj=K`{fM!B4ZLKeyH5wJMV0_kX!^cz>-{F;bmZO?k zRKV}%kk~xo0Sa*G3aCp@h6$V-IQtt+P5kU@E+c^U)`58Jh;OBKZ+G>Dtx4 zQCn0B;_AWQ#+GOK3A4VGq95kY@qKbv9~&qM_DUe#*9v)H$R!k?ee4j)t^Avb^Npz( zXysFAedLpQC3^AqCn_Io0vr5k2Gr^p=yZ(3(WTBbrDL%GPs0=3ImDK;pIGPf6v+$_ zIy)r@N*EDw;@6Mx@OG{)g?~9Ht|p+iGn;MK3Yco7T@1pKSI8~?V;ASGFX3_@1p2jf z@sKr?Kdgkur$W@Haq2>Q91o+P=!3P)LwL<4wndP&k6X|H#DIJEm_D~-ds7;IU`Lhf z`SkjaMkV*9ec=cR1muYHziQ6@e?x&BziS7K|0y5{{Wi4!pYjx+I63)2CgkAlru_W; zpS!Shl4NB_vj8H^Tgo`iI@am9lA>?`Z<%g11k{dV7_(%USU+6szat+7R^Kmo9}&XP zmFRkWW7#nLw@fh$=(kf3AcnM#jcJuPP*whPjkb1EWjaNXC}xuV-qa_ zSZsJcQR2$%3OyL`5!{lZGa!^v9dqfeRo>XJC)2%S_msqh`cO1Kt#xS@)ZJ_TWwcsu z#SD|Q!J%ix6@)TuI9aHxGjsX7CYRmt?n}QK+g~NQ2F~Rlli9vWLNfM#R9w+jaoYH}U58yiS`eyk&3Dnf$kp5&D5)h7Qj_c7lL|I^mTeXW777?{fQ zMjyHCx%*uE>6vvyUGYVzMX};&Im6gB(w1j&(a4BssFP-@E9A+A?u5#M>b&fvt#r311PKeWhIbyu3>$SH zjTU|^Km!eakX#}{dZ7x|FI_{g!5jgFfdfBtch}t_(C)5l!i2OJ{WZpVGKsG@{+Qmj zHq!gV!#3`iWs>oJXKqr|&Oov!qYTO;H{nR_D3g5)Hdt`**T&}nM)mCN?>?rz$UY}d zvHn9L#a+2Q$4aQcFBQ|VNN*i<{9?wES5}ZawwzO0?)^FtMgbmVBnU*R5K@VsmMm2(ezD zKHxFEV6!6eS{sLh12Eg!J;zXcA$%^yPKv4QbMb2!yN$IklDWrJZiWx}w(a=mP!VYqBX* zi)*UEY8q2x#W&OfDsXpkySf@saD33b>W@)}KWI2~F;lAF6F3SF7wLHz`1H*P8b_5X zk(}sj-?r4f!{${5U`40)<{in1#gI|O#(#wc3Zr}fdl7AIr7h>B^Q`S4zKBb6u_y@C zeR_Y!(!27A>Hs^*$~p_y@hH)?CQo$7bKp#~lbpe9^4&8iC~p)|ww{_GI+&+e7`vSw zXZE7u@6(|twraZm474(G=z*bdCsFQ54nfUP5Ec!3eJWT(4Yl(`B?f+HsjaJuj`j2)Toj0YR zj4Q2@8WR*WD{ciHmL9Q~>j=XhFCtMfQMrODf|TUEts|(2^W@`mDfJWVqzQ>W+aZm` z=0wHJ{YvFaB=>C=yTpqQE$i>BXrhzzqxaio&L%&tp!@TL9dtgX!Gva@F^N8^gYNJI z7jYsNsj=YeOI)(O@-TJQQ6wwL^tk!RpCBia>DGK)?r$LRlt&L%g1tYmn`EybC?Lu( zN)qc(CzY&gyfuP_!B}?Ks*PmN1$*5=?Jq7Wo9%Di5LmsxK|ca}={oIb+@@uJp+};mZYaZ%dMpxG zR!olr?gG(uAqc!7Slbx#Qn`zh)aM?kNe`J#+o`9%QJzQg3RsD@G$Yc{?Yoes)Iv3O zl;O!==VL-sWP*hgF$H;0-C#>j4)edqirEr``|-9aCcu00Z>>VE zl$P4KQS4~lp{|u{&LouW|DaXlPSBU0soW6QhP9RN_;?fTi9itU8sB{}y9s8m&RRp{ z?u7l>lq;OO&Qv#+Hf_wXVO992XUyEgUvX4XQkqdS-Ws;u)Y4UTEr+F1#yj`fRP-U-}$%yyL`k zwa?1dhEWR$KJ(1jXD<<~c5G%u_YMz?b(TxP!O~thd^3PK@%7}luTkxegTT{=NUKo0 zr;nxmP0U6`yaT00C{@8hsAlv}B!a z)MFPOz4J-WtcDg&iCubd@3nttd4gl5PW~NZ z7unHnF;izzz>}frQMX87fQ|GzQfB%hx+t%Im{tRk>TsM$vx^c0onwdE_@%U`#yl%q zJ*KCPpiybdoSLnJPR=@3;k6e zO}3t7dl_wmxcsuGYbTS3S$jGJb8pRq8v9pgkbUYy&6<3*`c2FKo)4IOzf2Z-&@5+O-v14teyXtvp3m) z#^M&%Ci36TpzkD4`~RU9&(>J?QvJ>vtY%GR<>qeZ;yO`HVlF@=n*^!O$45`5a$)*G zjsnr_&eBN9ZGV)to5hM10b77k-CE%;)%AyJxKn6i$4t=sB+&P6_A8&!r`E@=^D#Y+ zX{_i};%;iqt9HWfYf0bgT59_1t@9dXz|yY~_6x+pLhVYxbCO)#ELFRY) zm`;-uQe`Y=_=$R=MKJ_0as*PW=>DV(e#d%FNSW6pwH0PAW>vO}z{-KhehsB)!`={h zf^Tx%US7lqw36S#gL)Nl)wSD3e3cS2Y$3@xZ_J?y!urf>NNX#VwEhx(X7B}m!EaT1 zKi(NTMjU`a8!j|`Ae6PA>a(f;t}TZRa9eV;m=VS95K*{oh8k8_qSqqQ-_k>~O=P%k z2xk%P({z~{4fXVsf7qAQ3j0ygb=FPJiwrutZX`~`oE|rMs)QUeie+STW%8~6g(raH zM0GPDEhq&Eq3h9>f4?$cT2IQ z%v@s(W;Y?XHFsMB?}b#0CTzue?u?hJlil~mBfkd@c924N#uXf^Dtq>fm0R|#I%38W z;ClXyXK?b2D&d|S&pd;o-1zo1Rs@CT*QnAQ=@tX{X0738#$E{Mq|hAlmVXSe%Rnjj z-xfh@m@0b+s@YelGn?@GT51+avv3ve(c-Ic$+ekc`1QfK?tm@0+3Ssv>k|A*(+BCZ z`TLR6-*d%l$Nbli_^J5Nzp`T$uE;R}8 zUG{qy>gB<^!9SR0A9Lb`AMzffyB; zD~xjseYY42U3R<`I3dS*tmTY6M>y6Rn6NW#fr zGvu1AzWQ`AM=*)~-ZU+JwZR652R4vLrloghYzO6V@lT|Y>|GC68${&n&M;)Tu_mjw z4o=iw3QRT6MNv_1{}jbqo^W>(RNo?vOBizZ*cRO;iI@qe`t)b?-0|l26tY~iWv(U8 z-w9FUKDEa2QS@o(@(RXMVE}IWvEQ{b%`5=DQyZC<|$0{MBg=Xk{ZYv&(d1*PWL_~b&2aWahaLZ0b}b5_nlF>{R%klmtox7Jx( z#cn6)_@%550@;N~C%F&YAE7;p1rNmqa~jgPa?~=XO$|{!N*yOr2_+c~G1D}-r@V(` zA8OnRf>eS)h5W+@PG4ACID(+{Td$WTrf-}N<18rE7sP+=G>D1RaS7i>I{R-4%m45C z$p3RU{2yr#9>37P{Q}=am2B$}WDKw%5wIVl&A8A3SkvD_nD8G$dFY{=QVn&h;hl{r zO{IWJHLFEsv1*K}VM`qdll&5G8$iWl%{OIT-==!a)2dqg)Qhz-GY~;^Q}FSv=c)Vc zb&K!rmj8(uO<*l8u<@4vWqn@=-D|UL3>>qEF)kCZQSgnWttJro=!;(GYr_|OAi@;9 z+ZkySadjKF&3(U|+1=Lz>(uE7)k1?s9G@bF5WL+XaQ2!F$)#!2SbE!dPKVkTJNU5W z+Yv(fb`7*w^^W%c;49l9=Ei%x*$w;ksoX!bW{#8|LH*_A_rM zcHo^EB9`_!F@O@CuY89ZLV@qT|DZg5_iV44#ey5nj0x+1P)d|>7QM}&35pJ z;E!8!h%fY;30VF3Obx)hOn)z+t7OLov@3r{PHS8FrUmMHM-Sq9>_rfEEA?M5tbpQ8 zzO|t8ji8pGx_y!d+VjsM#Skh7&3swrr?61nq+-PuVcS(2+i|7QLPds5Ng7&lkrn4} zy=qzJ9Y51bAlsyzJ|_aDyGCm$*o3g5Px4X?r#U{pXHwph7>TE|gJ$H=16JgsEGy0$ zD(9i1uAQh3Z8IYMY>7t3ckZK_B}(J`g3)?_r%aXd^A!2-R^G1h`Tdb8#kPi8-4aK! zX34nZitP#)OO9#F5Uk4q2Yo737EELo8R=z~Gb7S6w2-AxlGh6NHw^v`@pV+wFy4~P zf**$3W51jMrdLa3Qws_6{n#fa38t()LwCwfUB%>0*-QcD^oxVqMa>QA-53^fd$zzq zANx>ddpXH#@Cidr7H9ytMZ%T~O`>)e4_jk2lgCe9SLc)ZaSCyxf?eU?O>Rt$`b{qv z{qCVFV{Vt~qT?|$)BSKxbZO`B3DF~-yJ+7hbKGk7_+N5NRO-V^STPYncm5=v@R;G2 z{uuBKo3@Z5O1pE$2Dc9Fnl<$a!rL`aT&LAh>wPA5&R##SnMB0Nj!ICJG5r4!L;@6Y z1+wc-McXk<+|(K7beh~(q?tey)^b zDm0?RLOz(JKuO?N1{jR0WkuerI`82D4Eiu(CIpkYhele^jwB#xT8yEHts0Y}njN|A zQS6Rj6&5RE%C!3sgXJ9 z3+pAh8h%<3;==jI+tJT4gNZ|W@@!)mTh=wLMA*CXgHmZkwM2}SlIAn!`&}>Ld1GjCvexo$6VYqJTzo5ZB zZ*|M6KhmYj?1V-(+Nyunf0)CpR@6JLDgn2C+a{mG_vXqF{evtDT4}qDvsTp&nP@jd ztf5fLkh$M%`dJ+OciikbfQEkWL@8RdHU*=yO&P58*}2nPO`F6lmNBkMFF7URpH`3j z`X}}$&9N%Eb2g|gI!>r9b~Ne1OUtRJMCG(Xy6G9+1slxgNk_+UNdX7FdXv~PshBAr z&Rn3F_}}Z2Lz=}oSVJsWYQUn%B{G1JDF=UsU+BG zxIqd~BP2)!qAm=J?Eb2FLah*VsXQzZAg8xbSwK!EM;8~3t-B)d#m1+~H_uz1>EH3? zbpR<&z#{Sbqd(sXTrZTY#@L6QRB&}It*=Yc^-VvI{$t8(q$#!S70({`dAPgke$ z9wfE0$cz-!eT7jm#%gpbgZHOP{XaxyJa`LF+Aj zxFjG}!wqm6(%;tzWMM;Xn`QfV)I_Dbx14o#H6GOdsb>j%yGwImqN?G-kpn!yV zHYWkAA@Tz*R?do%DEm@YFL|7{iUj&e_W0iXLZZKM;qcfJp!y!}2QE>QWnGB-UO7rH zUozeqqqMgfYOcuXZ|)+`EMHz}@R|si8Q6CK??s_nqp%J4iE$*N!YbUFf3j&VAglaM z9&~t`k#tqYhGr}e-riIBgt@40oGe$e@xOKYq9@GvCh9gu?$?G(+3E1}KPU%f5iw4Rs%vo+LJChxEw03;!nCh$m1jo(awukc{{&b& z3ow&I08EnG+)$|E?!V0e%Wyza&c=3QwX9{{IysXQ=NVM~*cku1mQQj< zw(|Gi%IPYev`%~(+_};33pq9}Gp<)=q`AwXU6hM0jwXR_BJHvx_BEJJ7SG)0$Mz{p zj(6Gpx!624J6)SYni}_0>}}wk4j|um58cpEdwzidg7JQRoRG}tO8>zi9Se5bQn>n9 zf`NQ^%&RHQC@Ai1#zD^PNx^Vje=-kOY;vYvzcWG0UHz+~PagSqI`Ou0T)35;V1&a^ zW)3GI%scKsk>evy0t>ovQu`Cv>rM{{PfIMC9OYnI*4HU`Av5EHKT@v5ZLw=7 zI+%tFxT}$-5`LuU?C?NMmQ7q%0u~u)oHwJm^$qeT#z*ooj--b#2FUDu2+ac_)T%#d zwi2g`ZcU+<{xab@zuK~mPj~Xr`kS6R%AMUs4VES7vD{d3mrY0GZ;{Eto*>s4*I?AL z;>Wpl=dGpUrdc7)K|+yI8yiaxhY(^ODe|Ko%~xE3&&LmTa;+Wi{I-+?J}Pw;wC z*$~b>_~8Xv?4Gh6a9jt?_zOb+fXoXf^M*zH23EFfcxK`}E5gpPp)1&K-)7^Fn?3H< z(5Cx$x}OhU6w)nL=_V^zL@JlT7TEw)k`Tjq5p~kg_60XvF5f$K#zd|Mjh_QTKF4@r zqy?9r80m>8j+mD@8zr_M91qM38>JRUt;Sl5jqS;0P~*zO-4C{P@YM^@_FG%-us;Xd zvo555)Lt$<-_)U&(FE@G#o%-RL>5H#Q(-kvSZa_67;FJyEWR8QOOr4^{eO3;3J{sCM8jJ6}CBqy=1(LFA88xlcUHKA@xT&k@v3$Oe1+wX<*qX z%NTl)L#>zxfp#?(HBO8$6?B<0K=w^C%oS9DOkox z$aJVQ+)i;YmQ#MW;*1UoJ5~O{TX$2JD z&HwQqd7-Izdw)iwt*EXz=~lZtBCCfF0o)4I!+%STT;Ei)Mf*X{#b2Jl8YiXHUd@M`E+S64~E)E;jyIPI^)5iz}Qt3`v$Hp;AUR1*}_Sq7X@y5?jy<2~N{#8BAAos3R zoYbHJzMP3J{blJq;`Z*em=v41Dn5|`smSO9sL0((zegs_^=?4NAF4zn0>g_^79C>OI}=~ zaKAc?9QMlF(~F1~VOiIF8?cfK0EkEauxY|DkfD29-$SyI&38)gG0ihdu(qXzW#=vssE> zwUHbP_RCK{IX8gwryW}wVopRF)je`I%xb>5r8?Cb)Vwm@lRxrFZmm}@zk_;)s#xZA zXA=MUqkC=wE3JKn9}`3VXh{zj?MA!ku29a4Uh?pff`zlB;t31sOV=r6#qb<`yVTob z?(Wu@`HWh26*t@=X2l*)Fxi39-7FLLww&b2Ph%8TgXK#9}1!y5OGLy_vhq! zHR{Q|v^A;L>3PFzSQpAxbjU*fdf&$W*#Fj|W5KPmuvRSxh>&p77yh^wobB*~lfEdb3 zPg<~`F!?kgxbJ>x3*^uPo}ah29|;^iWIJ*Az2A-5Nf9AR_8mN2ZBdAW z$>5&$u9IZ~(YA^AbV4>!(8k;a7EY|_Xmhuf=(n_U!=;u+$PAYLHLAWZx*y9*DpF!P zY70aTOOPETChZ;m92Hb*c(uL1@EK|u&qpHa@)%>M8P_|EvWv*H&1Sez)maM)4h;cG z^)6mA7`Dm{dzT^C?H|(W2Jy{GE}OY&T^9PCxbUH;WW$y%9~r$(*Qelu6rOS zJ+T&2eBy1iZ9K224?)G#H}jEIWh@_IYcx-2C8d6Fbcp1~<@P1rgJ4Gg3X42?L-C+6 zwcz^bHHK5Y4b2_#EeE>l(ly^Nqo{WK+zkC$)5Vka_DyH4yhU3{T9=t;`ZA?cF}alp zt!41s30Ko0w>nWGROpoj!6Q2jW7OJN@!2xI?dxjWWqO`st8)3mq0GZcKsdW5NiBZ( ztr}Xp0u>+B#GT91R?2NfdMtV3y?ZT5c=e-L(Lihz{K`^iqv_^txJVZkI(*+j^B-l? zWB&tK|Jl0DhgR7|?P#3^UhkO42lOQm6qiVmAb~M{1-rSi+LpFr-vlVMR%VHd+s|w$ zyrhpXP1P*L`3zM}xFO@n38v_E(Gia(^<$kz3iJ8U#Aec1 zMcuoxRT<2#DSz3oE?r$c#`4qYC2*uRme;V&6h~}FY#{U7_~N##f$ z*p*#Oo7a?3FC5y3Mla20j)^&GqVpudy$)T>p9q0uUvSP7c#+*>v)z89)60prW6;7G zc&1^aFGvy04X=;_+hM4$lwFC1X+XxB#AykV0Dujhr6kNOu1^T+9Tz3O!8c_sATe1* z2Wy<%FKAY(5OJ|7SA8}lJ8%L}xJ7)aNO}X;=VwIa^Ta(HmBai7s@zY!9cPt|ylX+~ z;0rqx>fp`%ymt<3f^&kL=Lt*MbaM${|Ab`O5}o{v9tX6%>VF*kEyH)T0&{80ZwyM{ zUvg3m-6Yq}%i_))^hs3g^A6P~+DEZYzab#l;Ui8UOUd&J5V%zW0RB40OXc{kro?f~ zh`?RH`{v4PmE3H|Ziv5BGYS3Vk;L}Y_V5=AG*YnL`vXYyX@huCCd|UhL+a<0jR0}v_@0=$}BWs%|cLXYHAU%*Ah-{ zsu57aG-yz#ZvwXwkC-~SwBfDct)Cnh>4EIpx`LEJ-_ll9R9c1+XU55}V6$SwF_vRf zLVeF0EM*=HJsP)NE2I#5W)h*3~!BpEd((UCJ6-C^&PT9^=ovz4(@L9j7Wm2PCQXJZ& zsoWkZ3`diVu(7@@YIU_syh~VhIQe|(IPw$MPq9uX?Hkbt7KmhzQ(p5&5O4FwKDqG=??**!B&%T zX`?J=YhLoRvW>NUV83z$4Jlr2mQWRyXI-KMs1EXB%si9FxE@BmCJLR0gjurF zA{mO%*N9`oQRT+&0Vq^a<61JW>}${>D%$U@evOhZk{ox1`)Jy+B+ z*+t7v!5J5Jzwg#a)rrMm84t!T89t?>6AY((C2r>QMBG)KhSZoYDZYRFAd;O!bAXrg zdc>>qdW;JU!SoH$;u%)IC=bCPgg7=r#Wat;BE2-Wxz0YaMXa9oO+oFv5|^Cl?|foX>*44V_A zfL3$hqc0q;GhZ~NGhbK<8sG0dY`8C*$u~LPQR2ngxW;VL5(GRQi_!bPG9Xrsv)C~K zWbi!mmO*CVv~uU%w%Hmr(nDq)xqIRrg~qUiY8(3%@qNV^Lri%!(J43K(Z4k*nON~; zmS^F$nlR%*_tl17ml+A>0MK3G`)eGPb8)7NeRz>Cy*0>YslR)lBbQkjzKody$Puyo zce6J%LzcX#zpI!7{{tcXu7vaX{;ubfE?T`}r) zhnDmb)iU(1h3Z*K!x7U#PA&6%K$CWo4kGZvHi(Pz9r*=iYwSBC0Vk0n{2f zP5TKe_VUg)CeYqV<1(ldt-@3z5?e`-%)}>B=bRIeo7NiOdz+Ws_4E~o-t3Y&rIlngE=0h&D^DH>^{lI;*fiEsHcMyATM%ul|t z+BP%b;ZQ@)>)reX>29%(f4UEJ-*xeo4lT z^lBtWoQ*G@rqPHwITqwe?z67X15C4)Z3Q4vpT1UJMT`y_REhW!;Yg}elfP&B;smRc zZMin;EG94XSp7E_u9hnt?V=VrKlG>jT7PXy=7Nyx4wY&2qHm>? z>>u=YSdYqR3MR^orVyff|9Q(Y6}L`T^c6Zi4I_BBXb3=e&c@< z3f6|j>6~xWl&1ZynK%TE>I;2WX15Gs+6%ZduNLE8oE=Xacv$%A6^Z|lXPZ;k?RKvF z&@1%goM^yYs?MzJ&c27VEG}s2;?Vkpp7o12!-zR!%#%utkBrPMZzs-0G?sZqvN~%< z=~Y+dG^cr{~A^7QZ75R@ZYM8>%0d)Kv*VAmH4-M8)#tB@T86qyj5sK)iABhNdd z>Yp(E{YhFDo!{nfiqR;V$`a6a`KQ6~ygTABQEA+aWgY(51er`k4W63O$ISW1 zrW7tYdh%BS$9g@NJJK3%UFv2wF2O7_5Z!1kX@ef`}OI715L zDm?Khg|0YAEj;$atC_BDf8)ATg|i_9;&pW>KR)7FZ)*^D*sRxxr)U9z7N-FgycEH1 zuVV#_uZjWh$z^!Zgk6uI)V2n7aFPh{Ir30QX#>A6& z!ye~M*jCsAp%MEBnVI=Bw(noTe|Ev+Mt6>iFAF6;EviQ-{{>?4j?D1?2{rnu+6Ss@~SVHP0j}yM4RaO zdlXM!^4v4;y+~GfI)BkoJSyV_leg0rfQBHpcv0bzn}sUE}W zF)Mb#8KX8!Z6!xywBAb$D=)w)HFQ<@0I zMm2@+<9U3uF}aD|T{Y?a71TXL3$&Wfvhx*dV(%R%tBm#KE4rT=R?Y)T;M|6?!D}uN zla9M?8FxKkQ}ns*H>pbwC#e5$e|$XxJ0~%d5-73NN17)nzpvUsUlDd;*3EZH+k`0h z`_k4Sp%n7kuVBAo6g2)7N&4Sed@7dawlao}|Di=_zQ=UbWw~&VIrD&Gs(6x>E0%EHo#pdV!`jrcogqSBi1BG!64%L(t z6Yfou>kUO!>J0@#14E){?s~2ti--dq4@h^#mrc1Lcl z%mjb*I^z$U>YX&Ql&U+tPeNf}ehW{5$=V7WDU$0N*=M0hsZXXQ^OhYcx8_Ki8kKvhVG5HW&XDjrmF9O#a8hebe(FC0z1PrvSzsyNDqV1`^;i%HjhaD zCN-EE;PJ$qpkuOLzD>DIv&VtmJoaV%;=snn-eb8;bV!M8*YXwV<%fwj(TVO?NUP8C z+3ewQy*)RVyF57XfoshfiIOAu!Rjjg)EaQ$9y`J~dV@red>tCFcT*ZUw0u5f`W8QA zaC3;t=M`V8ApOK1(;au+05k_1g=k0=%C!;FsTSYW&S#u8EQ$QmZoXGzaI(n?35XKb zS+f?wK4meNX{p=VB9ezOBKIH2B+o4U?8mR1Ntrf|_Oo^^FXo-)Op(D6%0X(2^%&6_@bXU6lxUPR4=m`+!?9&}mL@kvEG> z)M&(p?&RlR{$0Y;Xv@(nS*~6K&fe(NJ{-^T9Y;@a%+gb2Q>||7GWDLL+ZkV7x3YaG zB06)eynWbX(yPL0(#vY;)=nL%x{(M>jjm1-jcm7pJDNtDZgDqQ?1#QhM%rnFh4k+d zgP7%F>}C?}-sl>6b)X@B+eHic3GRJ%!$dNN-SJF9wCyd2S(VH&KUcanH0HK*MJ;zut#o>hHq%WWV4cI%P&TW zRQIZ4)>bXp?>#{w*+xA`%!)2^ocw!8q;=o)4pP+{+Pv(EJ{vRjZfi=u7nVl9|4Q|Z zfKl3AYk=@t65X$t7DZp}21mcd+MvNc4k%dR4r&L(=K4253yqy)Xt9!2Bp7`c3`S`_ zl1t+oy(n#R4pRP0Jr}r01O|hd*Q+uQK4no4UCA(PCbhlB57(|uSyI)^C`Q~RqmW`M&A>{2VmX43SRmtB;3#F z*Da;)bW9y=v%rCU7wO23x2$q6IKMQ)QHHWdOAV9EopjiHvfr>j=_mVj;& zT#BX!!s^J;Ts3OmN>koCd+2+6V)9dkNE79V0PnHYf^y5KuP-3HXM;rX_CmAob~SWRwdJ?f8}HXgz1qZ=6w9@0YfO#a+IK-3e=C#HQEs+&#k%S z37!GAmEhzXbQ_1mLo_gc#?7XKWrEqIEANH#98TXEA~M8iPc*bkX;n^(l_^X`xJT?m zR~v;le7xnVyk8*tb~%yo1+sq0DAj7DGZ!pvpCzW!f)$&~k2mF>H!4K+Y(IfJ9bGj< z9fCcl&$eu)oX>c`a0~|nyLu)uud}fetL4MSU87X#bYxc+ar$mjdXux%AAT;%oc3$U zztz=EBv93qQAD->mcz+}_#0-pS+Q{w(Li~5e@0yuzsox4f3JE8ruZFE5ZmH#MDK3Ws|WibC$!v7T6H$~CzuA$3m#pK!T?84W={+^^8d@V=pL5cl4?+wf5*1DHAxk3HUI_!upXTA+&iN4|8>>^wy2))y9I z*G$YF7GdZ&S8`XKPAz(cJ?_Ha3ss-y8R;#N%^2eXmAHFwY1FU^GtePnINS>C{DmgvO*xtdWg1jEPq@|>uoGxe3q<;x)CMPQ>=-&Q@aFwF|RiudHVfM?$C^L zTN(FC4+8pmCC?RKFo65NKBD7=c4eS9O{D|8M$A4|cu{WRsGF!ZPePfIhyzFhC`a4I z4#b_?jCrmCX?g@7ZzJk!Q4RU$y*$i*V4HQ!2(Bs&P#1h!LJ6fI(XY!tvHonf*E1>L zhB%Fzf@!%PG(x!#Qq?T;GUq^#+nJ;s)Fn$P$h*_6u} zm|SXy7MFX)fJa$_I%GbLlN6x*LmYw zjj&D>8^-;ia!^0c`n{GoYqE>eLBC!sUqSBV&RW2aC_B1Sr$Sn3p3^N5gXwP4a}r%QY;nRBq!4mFG7|AQ>EVxJE-a^h z-T4U78maNVokSSE0$dRFaHEMYNS^56jqaKAeI9&nV-0!N2qn#1m zB5(hrZvX`m)*ZhZC8oEQ&ao@J;=JK%G%+6)eHv-yfRP77yvjZBF1yY zWqZJM4UYkzSPo)o{N@2m+1?7&*VQyv7UKz0XYdLsqGU8;GK`v2klIqQtkR@o1V!># zp7}!Kr?EpMqEG06ehZ^;!KPPh&VwCS0YNw@E$pXTbkt+71dp~ zDY}NebdMVN5*c3UNwCLEx(nV~9MNwXMO~%Z-{rFP;Lx=$Yi?8;9B^ZgV5Y0VhUtR@ z)cQ2s?VV&1dmgcRtOg&TG3KeWK23%Ycrba0j4wt#oQ-ZbBPBmossTz89 z^k%UE#BG+9(ok;F8XTz1mOQ&toVwKMYrJR+u5f1fA+AU#u4rcPD=W>O^5Dnoc%af| z9H&b~wm}Ww4wr8q>OyA#4q#UeTGFN@dkNRmRBxYujbo$3*5es_i)l?2dL_Q}EW4JP zg&|{v4QRZq##z8iV!Wb1_<#$)M(pAG)D^tML~K}NlY7n`td?{0lU+Dv4mT7jwrm9; z(Fgey+b7u&zw*h&t_zvv0gn#PcpLY!7XCUJC$8r2KC8sH(W!;b&PgaxyHizZY9!6I zyl9~B2Gl2)MBj1%9$ZX9)}amn7TMT~*OUbl>0Pru({YKbIB|OO-&HoCJ_EHm#oI{d z4HWd{-Cbc%?$KdXhSE6b5nQQp8r~HD-t;XK-kl+HU0&4*Wu+8jVucd->Pcwk4OhZPN5E=Tjaq&=|kZ>cYKz^nLzUU z9Tp$)svn^*Z%occ@-vc^MLxg=Qno=SQnHmrMbLW)k1pxquuJdOge&ANO0umi!n1up zkv9csk33$%&5_T@ryNufAN*Sd6o$FwcF+TDPslLdSXsBgGnwsg_}z`2FFv#SR!-vwrI;5s+TK zxl+~KC$+QG%0>o#_di}I9gkbz={*UFTH|?IqDlywCJF;oI7Z-VYec7R1@tL_zsXKM z2eXec^NxdbQOlCALGP=rjfq@J!+M-i6-t7sERDD}`&qd`Brb{c$ok^!avg3)Z18-! zR{D>XZE0jO7kvQAxO}*)*d-a@zIn>s%71Yu2xm^OoF)CX;Xe93-h#y6-ctuS10ixg z5dXOqi+`gty8pTnOZ;nB?SBvIP*IW-cQ-XA6En58w6Xl6AgFrS|0kL$N=aU!R|qY$ zNa(vT(tsTT1x}Bc=XEJFacCH{NFjtMAAQZD)k?hU*--avLRi?xH^0OibZ)HPp1!VT z)>kw0y4Q#I4`}#Ts$!&}{OBSu7-+gP&4tIQy zdOYP~Tz4M_tB`;OkC{@zFkf;!Ib#IN;Pr;kx1uxnR?&~_*HYtzoj(tBfido%>R6*L z_*=Q-!Mh*tLhDb1`>PkIJIkUvN`H=!S4@lTU*u$V7Vs`#4fjXSWi979Pg$^FVrZF5 zX=D~)(N5exl0bAqXEeScR|-pl+$$OvA_Lxgl(gx*!OF3X!soFcmN#*iX>G6$%La!` zBCIf4M~)f7L^*I@g$gSU*z0j8Bqvg+7A#h!kdJRxz<-Tye9Ky(cHq_|s*hPd0q?|pYMG|pN7`uyy;LRs-m`LV<%(4Yp4Fx{CQ6ZtI+zszec#WkJ1Xpc4fzwEP^O!|Rne zB5LxBUUpPkVK{tDA_BUZjQPrQ3TxAklb8vG?__=jRaIR!R%AF4?bSq#ZN#Z_3!@=H zl6qsQIZBT|0A=iF_(A?V*gb#l$A2i^hxgnu9wanrrKYRZl+P@vz`9iC-oyVh1^Kg{ z=9Ioh?Cf758Jz#;5mR+Ev~~IdWPHW={-;Q#_P?%$%R|$I3lt(B|NPm2B6!Oa3?(!W zs`-F8AsAc(n63?5+k}A$+u=>Fhmt4hv>EJ7C3Aa=-DPaSmmb0c`>!TIZ5=Z!Gsmlu z)+4?n?kWEE=c6sbPZ7AIKk$(|@SsEX#PW+7RvxrL5mtWxkTINf701XMbvYFOB%%Fd zzH)QvFeeH;gRuR<9P|iJw^JOg0}*`V?@uBy@1P?YMofN@>@@cPCR%(S>eollSu=kH z(ihu6=oKMc(DP0s%E9xu#h~7L#qk{{h|F{Yz61lyOh&lE?1sYav^QROI|$>kh}`4J zMXfR@*{8apfdNlOdTr~aj-l{O@dbU!?SMVl`|{Vbxu97nBZS(nSIhp(u5EiQjW&8$ zIgeDZNMoNpTXQ>RQqi4NBgrCppM|X*Ee*+>)oT*Qqv)j+=QVaT;*Vr%8Rg3DDE-RX zhRe`m7+9C}8HW_zbq6siE4o+$(e_{C`BxE(`9pn*K)7ba<%@ZQ*xs?SW#RUN&|{Pd z-_wq84(7njFz7`2j_@Tpydf@7xy(PbaK@kLI}%WG6d+vNh>_DYh5icutZ+1xdyEkLowz8Ykj29(Jxpbl_PhM zKhLM}R!0#GrpGR6^!@oMTRX0Xy0_-|I^inF3Suh7rH=%Y znXj?J{7c_09Y?;7jXk}=e4!&?hislwcoB@kl3%==K`Bw<)uIcQUa;L?GuwtJdy0Z1 z)>{G+uEYz;q4$-*@&eMNff9>2W5-4A!4U9h7!N}tFwB~$@rn$6L3x|m<1F}L6hmQe zg!&?bS@srqB;^{LU1SG2Shb2gs1o^8FhLxV_&3ZRv_tsJ7f7*HbjvWlQgczx*%5}9SsZ_mnkwj!Nh<{+^>&{|cq$ks@+XrLXdwIJX~^;Q?M090m93bn}K zhedZhTDPHuSFp#0TVmspd#O!sxr^e`#~&?n=$Q#)4C?V7lHTx_5r191n(wypuH<)< z9mk7oboYyQsaMh>cQSsGM}PGHr$XJ=Bc@UKwHNRGYqZ+`p+fz?OZWdy{wyw!A1bD| ztXs0L`g2PdAU4vi0lMTiR3RY6zeKnzo5ZP`F)eRbA!Z8?k*)xxQz;DGlbX%dla7W>6Uip${4{1WLnE)Mu%f zWLkk!5?Brt*r%hH?7=}uvf8tXk_V=-Oe)*EBG5lz(aQB0V{=OmwyLK_tHB*=IS4Rp zuV9S2XQG=Ku~+bC_dvreQfXHF$O?!^blY9tl5>( zE!rMY=L1(TwNH;M8EerNjtPKg@kGBLDWzU6{gDtkp{^O!3iI;21!9TjT81GL_#ImZ z4NlvTJ$SilQI`+24~~QzYalhie6$5H_*G-C>BZq2gYo5CgPDM%a|bYFM;z5YAJMvh zkI)-VjY!=w!e%st)EhmHI*%Q5ywPxH_R}AieQ69xp>+pmJeR@tGY-1Dp`q1}TGG7H z?f~?hX}v&z+a=ym&{~^-a_&yReHkB6QPFI7I!3i68)z7!T@KWt)-s9nG z_AE{URoj1cy+Lxu2k=`GdKkcSc1=ISQvR~dWgA}8Ik~asNe&*FtVhMRlbu6L@NJd~ zqKPS11PasZqF;-VXp0RVA@7U#Jnz_3(e1%PdE7Pp>K-6m=#}MYuoAO|3G#k02ScjC z5e^H^&;Iq1wr7g|JKKV_w=`X`rL1@E^oHXn`ivqKQrR_F0lLyGQW;mACJk~OC~=Ge zENSG#I3Fd}LR9(8ijrMDKyAIsB7d`Mwwm8G+|4xD{mexnkt7wg*TL+!n&I2Wv(O>P zp8@kL7(b(+P!V{DYb^}vj~DK>>ZRKR&c(4bSJ(RF68QzTP;B^Hi)tF|wp06L@L(gI zMX>y)J<@*bN1PggMm7Fj6_k8v*H$q3t?)Babv{Rx)vxmqKY>JjI-LEJ*vVhoK<+p(!>XKGjPd@-sxsCsN7^7$$Csz4(0Asa?^kblY3| z!zgFg&5{Kg;|xNbqRZu#`Zm2pe5v$>bd2wN_f&(Ml;xl!vtbf9Cw9>Gc&zxlLayEX zfHoOMXt7+Z|C}~qcu;4$5|ygcGisVn(Blp$dNvTB<{XHRwsh}V(#v{X39~U>(CbvA z6Lho#j;;?(QFTxI>Kf_j-Bxpl|E{{+M_Aogulh!#whYUtvREPC#MZJ>N(`o>BRVW4!Q_7nm03cdaF znp#AuP4Z|E$1*U%cD-QttVLsh^I9G_@_Dzp`@9){V}ric)5+3RvFlZN;R8Xq9YW&^ zB&=vb6fBfUQhHub72K9B#O>831t19c;pNrz@r8`ymn~#KCyGV)=j~dAiRVW{ObAyN zsIJHO8TJV%-Kf0L_9BN=anbk&=Ttm_f5;DZS3DuUDF^xeNlBzB1CL4iPzmbpHK*}L zFd%~C3=i)^C2!`K-aIjd>V>LejJ7i9h9lh*FENNlDOY<(QhS3Dl)y?qWigP7;0nkq z71gUH>h}m_gym>_Z+KN=~CHIxNeC2 ziq`Ua^N$8`Djp7o0v|SXCY-nX)EW5PMx^-&6`aXSq=LAaJ(oHx6A;#;Y9m5}Ej}Ew z&)Oym7o}{)ADYV0IbiaH)ZY6M!ifg^kegv@!t9C5Evy)QOdp8hLxZoK83}hX;+iiHD)5aOO$%zr$M#dd z!F;O@hXji?Pv}Iw8th*ma3Pi?JB)F3+hMA&i)(_`Xl7JRoF;))4f=JZN(}untSsIX zOWhx#-AJSpugttcQ?SAu4`Zkp+$O^iVI1X|{~Rew10aZRb5oYKMzhI#49XA3GfWb% zqEUU5M)x533f3$lZ2x*o6GfHFLJy(Hj|{pKh?Y=}N&c1#lYvzj-lIFcg&9;wm2ZtP zurDK7s))rXpVqE@^;C4GxnO zNlZM5Mgk^XtVI{HFsVHwdsxKLQn?YEY@R5(alht^vDyIF zpw!MZ4-e9?5$DWcgfe zPNeHG+agn()^D@ETvo)3K5N$o+aY8VsP|C}cPdu_eqx+_0zW4C>OMm2eWwX7SOlo_ z;(!RBuE59`F1~#(##Rk+Z0f~?ev|T2&lCM4Xs5*yqi~wy@R4#Z*b||tWx7>^%m^=l`Buh zG||XISnXaNbFEJxsJ=iCK1Q^<;sg z->4CQ9RvmLG2LZLylW8R$Sx!z~Eg5lKjP`p)bR0JykSM4|xgJ!W0C zW@i&BWb}D^)JuLMvi?X1VoJf9YW1tFA@+X^`M;wTKS;43jsXywd3b{H+(Lay>(vH% zYskVKlgd4^N`hutQ%1{YrraCv-_ypk_Nm=6DQEH6H#x}O^La=EuMjRLfZ8k8u}IM; zj~uCs^aJP*9^p8N-?KV)G}1V|?+l9so@LZj)AN}hvS=D%jxXrxx%y!l#@(L_??}>| z%H(4m&Nw+OfGZS*m2~Y4(WXHnVgz{)o6_QtmgL3I?&^y3B9}p=Y>XXNpOng5W zYKy;OR-%SBzP*=pc0~OHj2Sqf3PiICS;cK7Kv938z#-Y8{d?79@`-s``$If{c>O~Z z^aFFJtj=l`-uzKd06IMHvU(wynB@GV%w&C^?4{K2yl%P7f z-0>i9w5Nwf&{Fs?FoDCC3rFkn$e3!c4-cGdDza!Z{gxHgJmEuF%T}zujamwB@Py(u zP{8Irf6y207M7iz{4kR{PE)j>k1Rr_g0(*c_uD8VpI5X0lW=F=<3kn^0$|!b8bi(gRsg%2gtb`Xo z(42)Rzo7+gb8@{A1%u$cYK_k{ zY>B)6J&4X=zrk6E`3}MGhq>Zz1N_A=L!Ds|U<_1M07*dO4}bJn#1en}4knOvL$(GX zYG4oe*$4m;CC#~VJafuO3f4igiJDX3 zl5pNNY4=GQiDW9tN=Lw(^M@O8L~r!loB6Fm!AY8O9sZzl?jW~@P0;r&rff6ZE$AY& zUT6GQDyUcJJI*IBLe^#x4rqWB=5yxwKJ@2zgLD#=2}?*D$RnB2#yXsM{NXy&ld5MN z$8B6Js4bMgIneE1zvt2gc48VPbD-|j%s$rHdJ^P%VjlWs(dC4<T^J#`D31-{x*ey_Wi2Qu` z!CU=fpmfF$Dsxv#Iom)3n-FSR8fWeHIY5Rq=CKC-Pn_be%B6tR_qOMO6PC1rOaSfKiBfU zvITew%uaBi992sOZavcM7xn=9H8ji$1!Ntg(1EDmvIjbgf;nsPqb>P6hA-kHD+2uHsz+s^*7^~9Nvg`K4 zD^WMTL`%{u(OT8H^HED1@s{}Cby$`IultY8*B_$1>qL2t ziM^7ED>id*-LQAWDKl+&hpsdGKd0F9XP}R4zSHtJunIs$JUB4YEesj_Xk8|sh&NNh z8F?U0N-0vk0w>I$5qO~4{7#eazd;?~S+In$06NASxDloj1$dU$lRjhxU)A)=PjWfIVDrFV`~Z8MWh$bD1&=rdgAFV z?g?d(KrqBVi`t^G8f7Q#b!~Hk?=86+b0uxC{W|;j6n9U0+01o~YCC$rX$_-^q=Yq) zX_O$o0i8Rhu4qoX-NEH&s)eb$J!uv4xlFIRv4O!L?i!(#$mk8n;HYzsu{MxpKSGh) z+Yutb5as7=7ZRnK)xOQ*)|7SosgaSJI%Lppx_02Ynx=7V?Uwqyx9jOZ{yjUazBrl* z^$aemyA?fL<++MQYdBV9?FWC^9d{6=L3C%UO_?3!f*V-PeGR2&T4WG4Vfrs z>3cOpCiN$t9iH;!r3Bn_tt|UKndYLSUqsch@fq9%z|nqLyk7}L_z7wo^RNrpwDH*+FDn&0X1wdFVH)&m^q(6Ie7ect(&oU*R%H% z3AUx%h(%;Li>PhR3K}Alk`>b%dUQ21FJwe5r8|tKBaKmcY~@jGnu`Ey2p)}qwTt)< zLyup4Ouu+;6;NxrvKgp}WQYvlg1#Gpp}|5%A{FGSMg|)XU}=&K_Tn%jfb>EmD?uE= zV6Ib9^r{%Kc+(aCDKUcZrj8D-?w7lDz%a|uDVo2(acTlNO`6e`S@caA9>ZyTekaU-2?q|5>k@J+fZgyZt= zxVcnigTBIDdX@3b?FUd|UNEtrd~8wLF~vJTz}GjPg=HSBo{+IWGN;#bA=>`RK+V<> zdW1u|BT}FvtHy^k7GtMFYgD8>&DEz1RuSh<+9$8krz5Xk=nFF9)@4xtGqG#pE|v+x z+g~;<3eKo+rJnF<(ngQ<5fS_87+Od86TW&~Axvu%eu~E?!^0y{(vJwTrKtxLYL4#E zXkDvcw*%U?&K{F%Jo|uVd=ml@#_{;+;4j^pDBmglkGz8_(AP9u>FF_dMnUVT`~!hm zgonaj7J1u{lY^lBZhDaQaJ>_V3cVek5;QZr0KCqX@hI9RbLJ?D*jhz~hPTT4x0Uh*sX2P* zc3GC`CxJ`-=-2)&D1XDY3V|X-yau`G1beWI;C<3jikLG^Gf!MWX1q}fLX)50{}Ha3 z&9y!?Fur|*`|{@h|I^FsEmDC_tE%KDP4@=ED3BZEn(@a z`z?)g`7rn}RE1f>)5C#Me?Yh=*<7To#|S{jKA_I3XlDYDc0r%u1i)GnBrGv%_s?37 zGG9}9_qP1}-oD~G`DSzXv~e(N7$$;)&sySoR}yCJQJYoQ7Zt^%gYxn#jZ_9OM9Y;b z)E}`@2kae&9!U(n@=YI&tA?e5P5L}_lFmefzf20_OP+rv*PMOkZUZ#g#D*_=j7fY* zFb7TeF%r(lQJ0(sSc7F8tlsWhlp}DKZ+J6_Rh;;{a1mGetXD4th-I+6Od^yE+26RF zpI|jmR_c#C-I1mGZ~J_sE*Ns=tFET#$TTN&KY#|NSaV=0mJ(;z4IE!y@J@c?(y5R zeF(oNmN!IyAlt2}ySE{3I?M+~Pq;zb`*FQ)|Bw=e15s+8SZV%NJCJ;|M5^24)ReA?bz*$J(C)>+`(7AT$%v$y;)80hRn)&Y z+MkX8G5dmd?EUaDhcE<+B(RZ7J2slwKaS{nr=Z0&9}B&Nrr!mbiK5>f4>c8SHyBvP zWxI<})FFx2>>$}23DgR{w(a_ZAH0aU!vCICh2cD>$f?U~hcgG4m*3cjojQm_&%3U_ z6j4a=E@B*PlO!woJua;y&FzXAuBa~Arqok(9ZQ~-);;tVqrB!KPI!norf=|MNF*$*O`-&G1E#~#y+%N@}i5QWwXM*hq?n_R>1 zIxC&;QG3y7R(M~asWVGo&t^Q1CQatI|9gk*X0aI5AwSl9J}Lpggn}D0?@Z`!CkS2S zajy~zMmQB^bqcyg*y8?sIDmFR?Was;g;IWAzF|M$;1QSld#y=-M5_oUP+2xxa&40+ zJw_Te(u%wBXYm;PjB!KZ8Ukg~>H~2;Me35@;cH$_*FDBJVlc3vV+38E#=3aIm6>XWM1Yg)pMtQ- z-{ET;v~_U1>4?tzPWbm6BgB3dWdxon zx$t#`-g!ly$NVxle}{{{sZ#y)tK_0sKPrt%ueNdZP) z&M|vgECFxf9!zw&AZBzg)$@esFZbVww-*+Bi|9ZWdJC-E*lsoxV9*!)Qq3V}{IP;7 zm&Bka03J4iG3e$S0h$0Q4MF_#jtpLZ9t>XqBW$lm@Az{COczC{0VYa_sk`a`C)iB} zO&9r@UBwe1b;bApA?+Q5YYCXP-5uMuZQHh;?AW%G9ox2TJK3>q+qRRF2XCFKQ}sSi zo$vdxYF5p!saZ4KtFP|9Z?(Z^WG~%bxIXnTyx=-OzW7}R4BQ&M3A_kYIq=0CayP|6 zx&9XnAKJMuLA&hu{SuWA#UtIam!|OTQa90u_o{GHl@HlLN62ir0wh=P<87!1FuyPI znH=F0G++;fTt27=G`}y(neD*AZIln9$QIAJPo>-x;I|ZhIf@ro^sbi}|CIg{G_;3( zlvQ_?UQ5WIxwQ@_OC3sUCrnrY%Sj{X3X-4KO&8tC$t0ojuvDxiiiIMAL^>mlcNIl(qB=!j-R>ejk%KJBhI3n-y?79< z>9-t9TQB>fgJ*<|aq9lt0xXeGE)+ywQknD^M}$bVjuUUh#@<}Dg_Ln*^ag*7zVj&$ zp_+3aqth_DWnF?LT2q>;ZbJ4V(x+&GVY+!oSk>IY$y0OTtR)-6)5k0pwNmQgVbpK6 zMTsV{bIK18eHN-rI+`!CUGtJ`|B$iT0!uQ>d1;j0T+}Oda72O|7Bph?TEhSte5w=;>EV zB~5BG%&my$y4jenKG?NU+JiDRxuREp!$U@hlz<+(gne&E{6n*qFdfXTuuBm{Lqehc zjvE`8l+hbpZCSGyU*rY5Kq9CP`?6ry8-8KlzRr4L)nmm|qfrv80K+DYtn*8jmFa|z zwcT7*#Imi#xJVS6X?;PS-x7m};6Nagt!`dkuup`r=)MWRZj!L{w{6Yh*_ zZC0#ZTqcF7&4Y^cBm~UmVdjHYj(oa z74m)NA{&%s^WkkHCLJ_fQw(E@G{l><+qFYFPTEmo5RQ7%5{abosLof2Zf}wZp9!PR zN`DuCS}d3`u$VhB(!`N}po7WXx||Qy)wyIFJ8WWxwi!zqomp%l$51pX7btD45&BI6o8J#LNN;m(S}mU=i(&bEUd|1Ev8 zX0+1Qs6@{{+Rnh#&wFGyp=r{$vrIDTBL}{aAvHdFh2Dc&7swH7ETLic%t{CLARP~- zai}0Ii#=UjU5c3{U>~JABRLz9#{|L|VZqF)Wz`a{QevWAHEZFg39Kpfp(lfN9Y)H7$J?rl}$!joa_WP#+q7Ph^~ zVXK}9?);5aqT`B)*s0Um>$8|J+Jp@+I>d2AvAWWbq_kbNu{iXUncb}Q&RA^RXr~!- ze>T!VL1-GU%{xwj-Ex@Jj-psMX+V*q=*f+1C_G+%Xr5OrQ~hKUI8FOa--H66I#Xs$ z>=__s5E!e~ZPh}gCqkw4lx|>e1hCSeRY>UIfLxAn{K{^7a8;?#7RCDoWw{NV9ZLTk zb*nCWbonF#z~x-F8@@gUh?$+B@ntsKZBtq`c>oGsVV03z4_0YCv~rlZcVGsG0vJ@A zTj{24f6y6pzcSIfoK)E|7^Cby38h9%{U#Z;MzNn-7TQ^A1%`1(rEYkOrNh_Uo9Sv* zpxitT>0ZVldu5lY{CMudRWi92|5>44c!awyeJ|ybef7`~F=vwVAUND$hJrh*AQ5db zb|8&ni^aoX?q@-lm{l(5%D#pGW}(A~WJNTNk^t0PqS-UHo#7qg5)VB`4^*d)gpv=+sdT#&$Y@(%rVfS{Dmylcy>7#6iUHU{$f>i1mMN8k$J#8>xE_kzta*s z0X54E5qS;*X@t4Gu2B(jKjR_hg@Yf@*E9dAO1$Ijl4tT5DfZEg>GiL_U3SPCR$#q* zNpL>D*A15desdWv3H&}Dsub$nVlb(?$?0$%iRrL%^%2uQ3f{_U^K(5O-&iHH=ANdU z->Ct`t=UHv!4H+7{)ytsfB5zN|@6h7tt)kM3;_b0p^ zA+RGv!Tr}7IeT7o4C$4rV&L;VdxVHledUU~`k%?tVN~jV5VIi?_2KtGxSaqHg5-KT z-fSYGQUi-cYv*U7ifKc|PaYBvq*bGxYiAVB^4b0lyuPHMcSopaA?HUhc#I^1iz^#r zl$P5mmBU*yyojExTbiv``fA!8Qw^xy?jheJ`20ueEKWyrT&1UanpDBTFDfr)B^S6Y zr-K%v(o@`Cp^aPmBN$ZrqnO@QFZ6L^ zgMqzU|Ghf5pxuPvy4tEOp>i4z@gr_jla62OQwvIpb#F(WJv^b#auZj7RC8%Y(2!-i-%zux*VCQ+G z=-m$9Fg)vOtIb}Ft!(Ai4-LNNdG5jP*$sUm$b67xcT+hnEYR%$e zebX2N4-NeHj^fQqMG>$DRM6VdCKqMgE2GsGL>7n4L=s0^wDaVn5MkGUJp!uZ~AlDVO{lI{)n*F?8$nexiWQm-Vk5)&$r^$?EMO||Iur8Ne==u zrxi7$!7X-n3ygn(eB85a#L_Ks-KW9nNo$q?#h1nN-fX6Mc-Ldz;<}23S zgYZD*%Tv28tU=^^lo>?o=5UK-@f=$YF41VveQn;uSh~>Ag`I97-RV4*4Ho+fe5jvQ z8?KO)-F;T%9x<`#g7y1+v{@U(B*MC5cZHvaRJBcMs<6tb&GVB4)`uxIQ*jTo4($wqTFplyCKBkRwlb&LFbt67@Fb@XEoI*IkEmN9o z202|$sVus99x?o`yu;E3>iB(6KVa^XF20HlPGf>=*>Uvw8AU<97GQo?r z62Y^WVcE`4=Zsqp=e#^XHHLBu$Cb>}Zg<55M2A5Fiu@{iIF zf&0L5au|4kle_BL~{RK((Ip03?{Y?*8h4axgKqoc|lD;bwGd9;tvi^{hgfp z+duNxBq1$D!(e#iZ)G0F(8%At%$)eKk-yhJXV28qGZHnC<5LrXkar=c=x8KmoyURg zUj)Mu@5ATsA{-v;5yuhT(bdt_F)$YHBjz5Fpb!(76d$GT?j6G)k?tiQq!1$-loaQ~ zA9p>#%blvkWoT(69;XfEjr0IHQGwC@;LV_7jezcqdc8nFRjV$cBe8ntF8JeNsLjBL zIsPys0g?T4sym&yk*?*3cs%}m{&!0L-`6{o9i8;8?TCe(9i42ge>}&m_5X)ds=oh2 zZ1=0#x_#Zrub#W{Pb> zWp2uR=0kOqPXUFP;bo4uW4F!*3GhVubw>}=qYN(BtFHUajL*aEnr;yW3;Wdw5HpH? zFRL8`BD9QFv%`Fu0TT$VPWW4PG%b#mDbw|r3kU=`Nw=|xlG{kMg4;@98R1kpBE9@|$l|JDc~mnm7S#;YhJ@ zo&kqSOxmX!gU7yzN}l7(Fc=g=51-{}q?nwh?}C%F7&2tc3WG!33^<|2Af7m#xh!e} zG+@e95S5ZNiIYKb{s?abI8mOMJw=m8toE|5&mu~+*HktQ+i|89h@CwA%#CIx0hW6c zasBQR;g<-&AVC{uJ_EIsCFz^6nD4U}92@O`S^WbdeY1%}!*_M4*%mu)Hftuz?2|dI zRZo!oBB-raIB0SgYf_mZq6k}N-5OHibnk*{f5zBSjLn0qUByvZUCY|DFe^i}uUL^* zPiR$jB^n3e49iAjhypw622N#6EtVCDqD?(Oh!IgI&TsrxEgfim1Z#5AktWinGTvEm zfN8T=8>wb5JcQ_T!-Abumza~SFw^jsh#OOV8eL2LEcbV%7FA{6CVC;&oP=3y;3qWx zWw3dZ0f5gv`ZQzJQi_{mu}{_ub{vOR^Nui(I=OANX$UnJ7Qs%j2eeHn!T3W8v1#Y1 zJtqNyAdkIxLLlYB(EQ_SM<2%4c%hGZDTDpi`dFqOslh0_hXVkh(xTGuq%0#d`(EZk znZ`^LBC==~BYB~O!!}BJoD%73A6Oq(fs!<$f2!{wEK_JD2E&xp-2OmLgjQl&VXR&x zQEdx*?&4qNL5N|R32wQ$aVuOIR~LEQLzvS94fbk6hgKroNw)8unQRYgYMj~cj)Ax1 z9~!~PJ3xZq&8WIx8yW*VfhBRM%o3YoLbwmi5=<~2t507+P`%39;27Q3W)0z}IIr}= zu3(B*TGpqcY9jwYiv<$-tb%62ZOF;eG1{n}Ox5f;%1Y?m>$XOYODHc^{F`YZQ#3fF zh86${s_o;O1Ot@TZEnw{v_BV^*^ISAtS8?o(PET%e^Eh6 ze3zD72^6{YAhm7%>eH$vZra&-H59k?CV|R50>)@M^p5cm4wW&~Uo_AlGu5yUN7Fe? zbiMd~yVSlr4<>P)b}2s*Acii{d>n_v`Vcmtn)8-M*XOmbKzOJ=p}eDpd|;ZQzsbFx zF}}W^`R(=hFMdIU>vd+Ty{dJb6rvUH6S=|ZE$rh^&Y3vuitaqVk7NZZ#f8kJfSdxR&eBVzsAx(Sj^qt6=VZ8B3@Sy zODF2zrVa}QB5l-$UTX5lqrw3qyLQ!(*Dm`9jwVzutGaI4s^_W>&3Z}0nf8~lHG$qG zx}{gBQUe2!`w5iy>5pdV_7$-Oz=ux;Al?+YBua3L9%t0alng?K)}-RH2#vgHRr4|l z54qF;#{!v2p9G)OB8!(#`d9xr=)z(g5{dzheR2r9#PI+WF@_{|gyPDRwu!gBmwK;Y z%9EP|#6VHQlEWGKA)=*@CNPJVT>`n$#|D>66U7ZZtRtqwS@Fz*u*(>6 z2sJpSM&6h9fxHQKiw|@OGhY-uXb*{cMY?$T)AJ6xX!}J?*MaHo{OT^0i)7|`bFP0u z$7~3rC_p498UJ*uI3^YCfMY9I@}9ILpCnM>DEuHDf-x}R+Q$A{d5A0)demTR-~o#p z7!z~&z-RGm5$MLT3L~ibbrb+t8zmj>*;he;g z9&&fzeatTcALh2lO=;}|X~a^o3o;wXfAxG5;s!#@f9QVne-vw@{O^SSpV{o+kY9P- zVO<$nXSj|=LxI*gU7oG0kh!RvSw)HhxdT~IS6o1LZcXAG5M+>7B2hD5ES>--JMEOI z^A^b48Y2{p5s3R9iTe)iFK@j>rXJwPzT+xeRoBzf*Wojs&j9?99#yIz>2A0`d?WhQ zUU{Gzig4gfdgL;)cq?xIk73{t42UgZ1%5~d<5s-A)X+LZXMnrDla}ajU<&Ah(D*=C zLu7Y>UgRtAQBTCJlw7J*Q4Mgkpv(9`V+dD_1+VpcoQi|isF576PX`nWi4o-(FIB&_G@PL{#2VauR7~0`xc8z774;z z>)*ETPKx2{&Rcgf!^No&NPLQI;X-U*i7`^-F(wce9#ox?EQSLQ0y zY?Vt^e0G9)%9+ht$0SOf7Oj?!8o4U=05$ZHc%s#N+$I>J&xasFf4DHfy}BC{Rs4BL~vk&E50+JP_WM_6<6fzAQJQm#Y@dsu-0&| zp^w2pyEj=gqIjqPtfZ)8RG0Pd&+lS>Nb$$*uN3bl;iRBF zD;CY($Li(vAazZse6DxG6{ri$E1@Yi3P?^62@*Lgi$2PQ?Dj3H81_`-fj-?-Sx5#Xz1i0qf#V zA>jBQ#RdNRLgPQQ1dNPL{uM2P6xL+{8Q^)G{gR9kY~3Q#U+@JwAAsnE18&36kwUM7 zXj)qvGd2zOOw-V1yl#L#$oG*YZbUBnCmtRq(oQFim*2s#GYy7?P^H`xYcKRcDrlFq zE13?agiz8!1C)5$4M&)r@i8Q;uXqOCaleHz z=AzmMzJ6w9!pGOY(b~a z&g&k;wC_m_r7iCz5z0rQ^a1*h-vb_DZ<6h2%ly}W)CTzPx-lv?PXE)OjZ)RoLtaGr zx-xM!bzy`sCWuu5gaVLYg`f&;+$>$>FYS%Z)qnu7%({?`C&);MIc zwD7Hjd5}|B$;}&@Q`LOmo_ng2>wc=5Za$tcN&sQo>Cg83k&nr|&vKmZa^?Ma*?g7{ zV*QX3AbS$7g#kji805uxCVxS^O1e1&ui6+M$BYm_#X!|S<;;MVKu>1q;};U3d7?5K zC=JZ?Cs`pfj1)@#x4g`qZPm7^zOlY^o&GVqZzb2Jq^TF%oY-4% z8hJ(XG;`#{eYsXTWFh*>=3bE2rk$D86KdWfCksK|e2xo`eWfuaC5bl%x&L%}v$$dv zYb7L{Yo;n6ii^0je6Qmrn}4JUGVSML)oy`0NoUMf`z2^|J}EK70^d4l>?cCf75zTb();T?9XDiH#OIc@2J zmPywxEUr2Vf|_o-s2)Z3fEIPWQRfgH;#m2^f3zzE1GKYdFNM8k@5c`^aJ%&7*Kt|R zn`o3*wi`lKk^N*Cmd%FUUXWLYWs@;Wjr{|nYaj4F?k&{CGwfFK_FiN7wmruAc)>I3 z24gth-ZSObAHMPzB-fD~`*=*({op9dufBut@Sd_(uuVXiLtYPR*A5l>@n=VO5$|yH zPaHJ!4yhxZE@RPgPV4ph{e2=MtQ_FZadf2M=w0RfHtc#J}y~mK|1>J=yjx znuhM<3o@Lxid$+Bl^5Od5IA2bYMLe9qw@ATn{YXqJVVAh8(Z2Ozp!o=1u0<84@&e2 z(CLuu5Oe|eN!_KVH3u@P&H7x0S!CGdV^~FL8XL=A6CS`15(CaCi|EhG*T>AhOsZ`( z@v9JxmaaPo(?M3IFznzt*g|xjRlYN*=s%Ge`nIBW-CS99cQtuyGMqRXRW~}uQWW2f zZ?*(#G^&54=!`GRZ)A!%Xaw2mOw{;%QIL1&ai76JZ7O6HTW-tg$ao%H8$?-J7AF)8 zZ4|W;0WN!&AB39j8^b9an#en*?_V|6H#}3SIDlmVhs(A%_5$Y@{ibRarEQA}jlEx! zV&T=t!^>NxoqU2db+cl&Txk?q3~rdLEvrX0MN9YoE-d!O(fM8GuZ#hSM=0Wm7L}HH z2%nqmb(t&P;kW zmXc4)$y7?c!lN!Cqs@M#41~>@*n#2d98oIB_`EZmL5oW2^F)ey5(<1#Lw@S?v(vFn zrgb)u%SC+$jCRm$!+pY+H+N=r0)ZSD07ngN!5%*3Wrxv0?;`KOa96R_fV99UUaA*AUZ&Nd4t@gA*CU(o+!= zD$YtrGS&?o5ZGX?!a6^Cz6TNsn~C41_ZnuWyQ0;hI$ph`!aNZu_Ever784D__9l&y z!_a@6>k+z)@lo1uZpFxI-4Suh^j@zv&eUF5@#F^YS@R7^RlEUr)gPrLt>1r9zOHbF z$(J7$dW3VDiFVS2w?b6yZSN6z0aO8yt?-DRXh79^}6GF0+liG=6=ihR0lV%Si?V)f}{O(uUgW;B$fQyJg zCpi)eeT?w)z$RH528wb+=?JxteOaEnmfgF|sbF!E1!N9JqA|6b{76&era=kr4hAt+ zN6>ZT_>$?%A(X*%^#%03Br#nY&LR2WDqOwHdjI+c`bTCCnYaQJ`uUeM_=ENTcS!i( z2dC8j-@JUTw4jRoEfQ-agsd)dUVzy|NeyMGRYjv&^{24{oDv*FchZIyeu9)?^loO& zwP|swyTa^!bvmo8gUPwr$I|po%-LfqSS{s|0s8qU^Zh-`^Ebz;@7L$PoN^vYPw7fP zqrV{owpffmQs;Ads~Vg_Z~`tfS7;fRdetUk$!I ze0ksmlUaNU1;#w132`M$kZA`K$8Mkw;mBJuT6=fkA`j9~VO;%&a*J^U5aQWH&^%Ew zg*3!mXkdCkvSCmNu`&w_oMh>hlZ?O$?l?l%tG4J1kmwL;6lSR1$c-2cDrWkZZDtw+ zXy}B~6lp=Q`I9;ZL|8HIGM*Ghb{q~`*^KigzA?K#W#+ALEM^^d@pDA2kpPKmi8Zhv z_y{(H(UgNINu@p-#6}8Sm)8p3Ti=L;S+(AK_+io5pSaV4d5ztmF^WCpu43ZV3_wCOkUtvvWK7<_EHHTaI{o8rBK=}7>V47StLGzH&28{;fzF3N{bMmPkjKAo)j>-$XcgPl zmM_3LcXw%l9-B@gxm-4-5$06j>&#x!=ND%%5L`JG9*B)a91AxfSTFHHZDHq(Hs&wk zRf{k4AHGcSvc@$e(Xc=IFlCg)MBPgoh7`@%23nfr&HiJz{Z zcoZ&XZ;=Vivz@LGTC~NRc4nh^8I<42#^t4k zaEZO|j7Z8!CA~>AQOwL>8Oi(Lv+Acl*=mM_+~zM27O@S;;wd5sqlFhN4#-naB~D+0 z>&u9AI874p5}WSpPmy-q=_b(7=&kQ%j&`T;2Miu_Xa!4+fiNf>K+3F;8!io^%9~Y5 z*3T0Fo5YnQH0jD8ZK)5m11^yfodyB2 z67T=`VW0i5xQ`j2+<`iJ3&5Bfk(B5M?J7y?qJ4;$x5oQz%6t1_rwpJXj757 z98=TY!T9FIwIl<&ObQkaZ#Jytq}J#vDfdvW?M-$PCzEUD`>UeGdi{Y3OE$7ZsDiL) z--H`cB&Ka|56T4gRyJ&vt#S!Cb4@6Bj$rh`V)Z^G=KAK2|0C>W z9s3VuJ^0{lfI<+F*Snq30=t>6@i>0LxxxX&zRAi zhUtm-sVN_yF5lcxEp1LSb~D7a{x~)_Y`zzyo@-Ap3}`VX!FjFGD&#O}G{RbqOj?gX zP2G~Au?1PZ>dBLN@IwqsT%qv19Yj?ueYk#T&Gis(+ z!PZmkXAaUfi9r)a7RRi*v$xz)J{q8|QNg6)z&Gj}(%;mE1@j%9i8G6hem2NateSldtp;8i+LwiAqg^1s}A_O@wn-TM>(jFF{) z!Dtg86S$R(9l{%c6#HL!cb#wd<-h+~@17Fl|H1yLcl-XMvKq^Og_Zxf@$wF~hQ^ML z#Pa$M`u}c9CMoIIA_^e$06{^W&!K86oTFJQpw(91jtcJw$jC^GTMHUK*sBj2Q(nYx z_AcZUlKQA2T0YDU;Qg5Dl;YpXyQg{{A8a^Yw@rL~JRV}juM8A}K&8}=?A7y1zNs_S zW%mXLA&+5bGuTfGC-s86$kK3h#|fj;Vi*W@a(bp;{d&Ffjy(V3qA{jtiKqWmrD%^1EpMZZuF|6iRB% zXV3&9kz}NOBzA`RXiuhLOe77MI8JMw+R1inIMl(t#TBx^z62A%&#$75F%(!zA?Xe=PFp2+X8$B_$j53Octr1X44Xyl-sI^us^9`f@q&iH^yofH z;|pxhm-v8sYF6joHl9kfPW?0R0PY|<)ZuKU^=EcYg%LKD z@sQ+D5V%Qm@}`@jyoT;?JE=~_R?-B zEC$YyGyB;vLuan;Fw93#7@g`4ug3IE+nsU_13i3+0Q3<>OlVqwDGwjITTD z`s9x9Y?%+^r5f@j8}_^M;QHMjWQ+L*D9g9Bzvtv8dF`GE>HBOr=C(O3hx}S@G0~Ul z=9=`Ye_&erV`IQK{Us>g*L(+uk9AMY=OcyDX27>1`g`{CyQ05FrO(#s#hOHQUq?tU zJXTE7tSK>F(L|EN8a0O^n4*{hrT8T&Pm#o1s)t&s+^M=4yNsc5DJE2!iFik>N7_`} zD44=Ik?!$rKVLG90;Zi+DkQ>Lzj=<9!8n@05e5QstVLKcPTy}aO?;*7@iugSCHimZ znyiNqHA(5!8cG}29I8~ab>!fsiuPFqdvk|TB!@i-Bp|L5cRae)da~>wVt`SlgqUK0 zOS>VpHCd)QBf(8nDWj>sFEdU=%cj|LNdm>)y8(n;dK|Wlr!ERnnNiOryM#r>iQ2v> z;VD6HXSI<Suwu&nwr^+hrVcmnciIVF{bZ z+Bl}IDuj>X5(BgXOn>808NnEXl^(bb=y)1pQ2P*5L6N8OBr8uxi{WQs2O4Yk@-}5| zF`u#6oXge_NR$j3d|A4ewbmtoz&r;^{GjY=n9p^o#d)$s>O!#<8Ai|g6p_jRhL{?F zkm|*aJ8_DPkZ4(k*nA`xALl6x5tK;p8K7?tMeT}*kCSG&Bs-VypFAuX^SQP*hig%u zq@1?JqyV>Z4ICZpgQVZ3^`ku({w}6G?K7K&VRJds&;y|6D}fka)}so03sPHaoibG( zq)^xWM5x$>G?8a^Y*%>!S|M}&_E3gz1aA$c8m+pkcr&{^FE~(eyZTU`H?;)! z)M<23)SYNOa;+#l1MRcw+?;W8{t<|yJ4Vr9SqL3`tndv5!PJdLaoUnh#&rZy$;=X= zquUnZ4J7*JbvF=RbA8u)&%lpC0=jIR{K|;z>o{MKnsb!a!PIpJj2adrj8e2IRMZ-@ zRMc&Xs^y(7y}>XzTFow%y6fw81S^QraI4w+z2fPN@9Gf#Q}PbXxG+zvy@@z6g@&%{ zy-st7#JH}rA`v)}gZutVdS5-fHJpI~VMc4l%krENSsQ{CL8dqMy&I)!B%~^wy}Jrz zRhVHP?wAe3G#Vso2*F)t;(hu!*h@%5h|Izh+pSr6VyK^{PwsRQCdvxH_hz z9>%ZW*?Xki5{t)W(CwB1BslH*L{A!S@(7B_vLZv!ZAo}a*PoQngs05lPEM(SV`Bi8(udo)WwRsy!eUV)=lVjOjEl&F1tMNwGeN??yNhylU zu2^%1qb92cqcHW0@z!&eqb_Z;eGP64eU8`%q^ks}ylIf`8mKGi`UeH!OO>AB$yvg@ zBKMpuTu1_46082`y-rpuHm-F}P!%lWHa2B*T`{CS#t~upF}vXHFC8lLXRI0&sa-sI z%cb#MXQ+`!kj0QaS&=VFlZo5`o*{~(o=zzwt~&?<>)#E~XXaOp#Dw0+72Qhfci|Bv zpJyedE5Xp}jO5E&jD@JfPAeoGG+`B&4WwNn^98SjwBUtW4k=0}8=aeRPT%m>7bLq@ z@~Lax^hrohJnnpGIhXb91()XJV@GAI`w~Z?5s7VsgU-enXU#p%`qb_S`7#MX(R*e0}r_y&d zX)0|Qb2_UV$L4Hc4c^FgE9#YHWfb`KQk~bkL!+r2c7!;?>)tG!0bH|Z8IAl{&LW_Tl-W;&6{YwyEYHiogmvC z^qn_cV@3^R`9JX;;{{j8n{SP-Q^e1N3@I}kt)^0TetHu28>zeE-qW58%B%enzkVW+ zf9yhz7%+TZ)ySPP;|7|xxu33aa%DVYwW9@RyCs&qkQTnIn*@3@I&ftr3@&-Jf-59U@efH9XI?{S3DHpzA>c1A-+-Fwat|e6 zUl%CAba1n)@Dej{T9G{*bJUpyK~pe1g(w1zITR=v`>goYK|Jgko8CzCj;NtsIfphG zpPm;wpC!Gj@d|rH5Qgweg?yF_v`6wGX?M!Yto2^qs>w3DHFE$HrqWV5=cgpH< zGwmA2bt@t3b!|r*Y!(e>m~W>BEK47P|fF$nNbYzGP_q|Ooh2tk>A zu|}u}R<-ouXQZwa7Dr?fVF5QEzxSPk_SlcVf7}j?5?+AijRA)hlm1T-x*(EE9!kIZ z(7tY1haC%Ci{CKP2Z0Qg!u)|4dB|uRo70c8CBr3q@g+3yi{Tr)N#=pJ2WAt&l(XL( zG_7KV5XJu+!2{ZG|%J1qS*2I{C)55z% z6Zo_A+Va(ga^e8`ONtVn!bYbQS~|WzX|$fL)m~)|r7KH3hl*;rytfk_wsBQeB~ESE zzf^ICD;qc>jE^gz)v}?3=qROz-0J2KB!%%kDI=M@{d( zvj?`^aQlSQ?dWjRp`fQ&U?*X)lSbV7H}14n9&Jdhv3kYb@fU&@-+qIYEe9NV?d1kG z&^a*>u$tFx7x|=}xP>M16-NbqOb!SVd{-R!MkT_b9Me%8e3QOz;~z3`|Bl>N8~L`r z^9@OaLp!FUI`B>S;KM(J;7&W#O+2i@4^LrONcoAV4D-9ziZAGsHf=-BSo9&i&9X=_ z!}dXa`8L?&ECLdfdV{?X9E%e!JEqW2(+V-VvF#~-)YV^Of{#7LZ`-kVWP@_8^?!6< zu8?$&&j-iN3?3<$OF300X~;c{CzYKL^PkRU6ak!&|H zxTVs8&K(h1Gwa4Wtw`J})ju8z1Su7$R8obsX_GM<#c60$el3kUY0G8WBzbI5 zFvTTmAf0UVDc!(i^GMN|8)stiEN4uL&D!6vvtCUsp;}@uyM&w$pL=LV=QkKLf;a5! zA9JHK;w4iLSZM^lI#AFW+en`w9;qo5s-nKNMfv;|9Gf3}{S5jTAMNqio!&8AmGtBy z(i(kqHEXHq(q8kPvoU*IZ|qwToX0i^GiU2-s>0Cj+0Z@SjzKMIF{09JUC!mN1KcL@+MhM}I!;QdfgUe4G$_MwJic^R7JDROFdb5@GWV|_C7 zv!%!M8m?_a2CJ>y%+%`_M|Imzb#B^7hA5C zeH!*UJuiaRe)VkpE>*jQt@NSx_@Vr*zV`S&DbKEZ-1TUpjiZ9;d|X~?>3MRu@;Ie2 zMdsG)p4jmPdEzE;ecZtYOm;U3qNPJ70DA6H2wVc1ryeT$VyGbgFH*d)sHmI$MvxkD z6q_+JUtGs+bfk>^b%Qh@od8jxd7Z{7A$x$1?>}?{PW>n+#GryC-eAy62?@oRk!o8|k8~3DF zF4i%ex&%_P-`hJy2bIdTU_?LT{lhV!CVfNrrqeo0(edK@%rGF;OY*e+zV&$pK%E|F zWl%2ftjiA8M!6viW}W7M*C~wF1+64oAo+Wc&>hD5j&tphY6V}{xVR@e)C=c%lhy|pSCs3fH`lCu)luA18J+)|Q7yevd#TMG-gPAlZ+PG>4D? zAs|SNv)34^VEnCQ2hxCeWYk%$hpR@?nU|}ihiasqa8vAWQ|Bqww+HFXo3R-fm(vz_`p~l(Fy|uV;m71f>vmr zqo1);A(&s+D4QU)Rw*;jd9C(EnxSVTi^F=BSVAh;6M{>ZUiymO=)Kr+EgY4Ng$gO> z5xajZQhHsMv>Jt(XM8`~I>Sc0q4Op4h&D?2?3{b9$Zaj^9Hrl8!_}U*2!;D9lAe6u zl9SFY*jl0S9s6qS2vROJ{d~&I9goN5Pz3-lV zd?uACxs|FHDlZfzxOcNX8<86{t;Su+NY<3S!Ls~sOpOA6vI(PjyLgBIsu4meFEUm+ ztsLXPvyp2kx{Ny|&~UjXhl)?~!@#K=xO&U*Dv_2^}j=*R8 z2>llZUBLdj_KCWD{j1J_skLD?Rq2v8q&~1#nQN6rmh-?8S_c*y8$Q&&kQedJOfKjU zOG)Cqwk_Ck9c4KGb7S|mU(_DgNUn15U>D-27a4 zn3>YC3bgdL=l%5qMT7Wr>0IHF%!W8R#XbESB81^$k7~?X^^yEM%~nP2^r51#X6+K_ zV#VBQAKBv~4l1$!4o&0QA32?MVGebA3 z)Z2qxG8dC0VZX=aZR2WSi$vGQmte03K7n`n8_zD=2W(x-cm->{0Jhx1Tz2>4e1vwq zVBqb;dHM6*QizTk#9oMzFE50Ty$-?=L(OUD^7qYuX0XR$zrc87&98@2TMI zm6?gFtW_D4UJZ`a#+K8$wq7pFeFxD*r_ita5X~LTC z5s2p|zbWbNIa@reW4Sh6BVZ8GL4WHKO=~&|hgZjUa0NqKsT~o9TXA|Ln5( zC5zI|{M;Ct{|Nj4|6~_oV-tO6E2sZYlKFRbQHO9-UVQw{GD=Pvl@bR96b6R{M-(ST zkPrN0_6I)?Lf&7vmiA{6iJm@Yy#f_wV>wr)Vo5p{yj8DM)B63|Lg#Ew z^-R@T$HLlr+WlI_N1#@t4++UUK%BTF2)YBlAF=4xE7t?@M}cG&t|jaZ2f6=$DEp@9NW*m94m-B( zbZpzUZQD+FRIzQ_w(WFm+cr*S_Uv=c&7Qrc?&_-6s`dZR_kQoAHj9#<@#ZNoq#oQb z=+=RP#9&F3&VhpY+{|fX+$~8%znlyBv(tw>>2crInWtpLJm`_%P_U+B$o37uaVuwp zUw%DZ50h+4#G{rWs8d*f;C-h#1Vt&BhY2c~Sf&XMQ#xk|&Y^PZ=3+uk-q-lD5ZNRN z)}wL?BxL2!ggTDIbBoJY3OeyHM;}rt7ta7|@M+`*K`l@KYuRT3j`$! z67Cr4?0!K!ils`4jCGqP9ImQ)WJNXV3u4gf1_~g`Ea7s_42Lb}lFSjsy$(F<+)JIOUplSxoQQ4PazOeC5`5EaA)_`~Qm1we zm2rzApxk)5WQHuL3T>gQc!tF=<|^EB398oxN~d}Te!XEuhOOm9RM2)E0%?f#SX9e} z01cvQu?)ElFI4SkUg)W?nRK`s9W06JG*OF?CN~40H3Ag&BIqJmS-9&PBoX1rc@ld1?ts;QK-F_dw}Q&yaj_0G&qt0kEH!gG8$}c zj!W9#ykU<3Dn$C#2GHCbktO7BfiYfmEn|nsnRsBIXoft>{F+h4U`NGZN^bREe`!|J zZ6lh-MUk73EVSSIJzm)7upO=JIIyB|gq5sm>PZo|gz7@oJk25S8+;n;RgGt&W1z4mB=Xhxo->cvfsD57ye)0{1G;W9HzP%ZXLJ#8MlnQgDnXhuzI4$L0t&gaTSmGJtk?YOjg@q7#CFWl3{X>_j$HC_|jN?QY z&thil*pNh11hH2fMVYmj4Q_K2H?w7K1lpL+LN-;gVHW^`j!QQOZ8jK!gFD%QbcQX9 zxnL_yr<_O?#sss|rot~4KgA3`3OofR2vExE`+^5eX${{A!P1`ykT#lx=jz$BcwBG= zXvhfrmU1TGM6J8;m`@~#OK9jDFLmD4$kGy*qaI`u9%lGJF=LUaXYpv zw*}U%Vi@Nr;7?FZQZ;WSQiF2W9g=ItwrqGVb03sE{CvtcC|Ry^0hBz#@a68{(`EO> zrXf5PC_F^VPX0WU?{9%$M*bHfY)5f+^d$JH>TkoLrHXl?@SAb=@B_${HpS%Z-u*TT z8!x2ViJj@c5D)sR&Tr+;M zjBG2b-&OI`OkmZEYb=RbdBrN8qOwKQu%Jues|_uZ(_;>Lc|4RnVja5~+KpwtrIJ33 z^~t`wWUQyqd1jXhWfa_^eKc{m13L}w3jllR621L=EXYTYq?C41xC|wgL0Q)6)g%#p zTL;p9|B`2xEwqmWT|>$*BEGe#VI>t$%qs*_W(UPZ@5;8?Mf9jQO_10Y)e|Pzv7UD$CXn1s|WDZN>c8 zCn|4_<&WWNgp(4;I-%wc{sikB-7!8N6c^hgk35>k*XgGcR)wwKKo@{gmH7P#LGQ zOQ$$KS?_qG5OO7Kv_-;zhn+TL$(l@07IJq-at&#&V#%LHZQ-Z#e7Mc9xu`&K9S zq^ee3u1qSg=XItK$)B3O_d6ymsNI8C%APVf!#3HfgI4aDR+Wi7(&aDD+c#MFdL0Kt zB$a>Ya^Ex?8lL4N!_Y}+_0VjDc1E#7k1Bh zRXj;(RGcN>A1PLagRENFGU7m*Tu_!X!E9WE!O{@G9Z8vAc#{I<&n=B%g<@Tm-}{-< zGw1i-E`WRGX?&97v^g&oI{7T*KCv9zcvI8Nbjer!W$X)P^e&jyBVF*Bph)M9^?qV| zZ4YZckxArDwEEQmr%#fv@Hcy-amz>fReHCmM_TxNN@aJN(nnUW@&I;`f%0Ijylt4!2cbgezhv5pF|W z&H5CB2=~+m-}uO8n{yT-CiH9j%I>Yi&xiUl=0BLHem>K-Q-dKHnR$>>W3$duSJ)MI zW6TeQAXRi`PFj+z_fPLeKaG+W9^j3_Jj+LqP>DD8l8uWF5s4rJx3QoBxibcPf0&sl@#BFxB{ z;)_kxRKNYKp|VpCAdGlDB6rB10bROGhhPJ1>pSM+XX>+KSnvaXywubPOg$_P3?yni zF_Yqx6R{HlZ7bo30I;Wq@#%CrwVgiW4jv&Z7j1$4142#XuI(m{*ghpxO?e86KYr@0 zckEhhZKDJnS7c`HckTZX(ipW$Vm<}ic?P!CZ-~jXb9{m9``G$HR)X#uWGeI5GP23I z9TOl4u5y;I(AD4^&3aLzC$u-m{VZGdl})m!j&cO}g=hyC z?gsDPT3&G>CG*9`RJCGY55u6lhO|VieOa*(3euSaes8EI9Nq*8*&VVh5gs7XuOF1` zBxnvJMzqt?S{ITYb1QOq#xb@~A%G5#GsqOsela6mqcs`y030p>jkFWbrA0j2f@QV3DmrV&?!xbRumBd%%YjXw5MCt4I&)yvwLN zs}H5mFQdlyckOAPwk(cm0o*~5sjD3?(C@qNon{^K@MJd5Y!}HT?@VD;jU}?#M8oe^ zK~3TKp5y$vUS^ja_g3UKqssB>}L1eVf{Fu-DYH31Nl~JG0@Ap?Z|rBZ0@R&usaMh zji=#d^2+`$eZO;RZ~EDa!4U&wNcwU|l)4$4gK>XsJEoT+Kx!Y^m-cP@ur{leMhGuW zKI8x+Oo<+eN`B}rP;dK-dUM}!lcVFUX%uzCUam@9;6yZwUykh-tZd^Kg8DBL6e+~T6z#SFeqvou*D#779#%wkGH+>!$hA0Baq#d z*@mDqW+L;!WY0xC4y~!4(fnB1Yq7u}?v}84=QO4HL46zc*o7T{o#zPwq8XFLtoEF{ zGcnr>BwyA29_rCjfBnk;hE6X3(Q<%u`Xco;S!<8TU0&mOacIFmLBC)m?;bZjaI0-( zF+-d_yalj%GFXt>;m-w(!ou9W#pn^zg8}6~)yd!ux6q_0-e6EFUAr0Nu`tYQKdBbV z+sLA8Yz?b#MMQ52qI(uw56`0%c|^d`rmc&h2&7}tAZSPc5mM^ItpVNl`q1&4`Nj(f68?}<&BLyaBIM)1mR0R{C|7*TIWF}tGrwA14im>E=dE+w3L&(vw^doc|8v+RTs)ENmNq`?4*z-wGcSmU;@nWADNM&O;3NEswGNY-ob5623droLG(orR9>S9!-&8tDS zo^(j(^P}LUG-qivy_M;;dL4DvOld4_P{F>pkM*{o;3I@>Dp(ZMNBsd5_e0 zj(4S!QLkFRT@$fSxV7UBT-=G9SGS%{g-_nd+yH3M!>N-#=@q3RkLy0HU`+0FRw}Bw z3A$Yy(|Iiv(~fD|E|TOi=|#6sv*;2<3+O53qZ93Tfnp<=%pgZ7eW*r#@F07l#$990 zNN}k9)WvOT&G5SyFJch~;uG&xw&jP4sC^~YnlXC{8nQ(jE?U{0xLqRIY_5`_RGn*D zlR{4iO!AmYmMUFq-ILDT`9Z+- z!}iby%cYHdVw>C2ufi!_6o|QWc7>(=jcR4;%R$w}LsKRbPK|smPkXD#xd~k(#TJ^# z^{hVJLfPL?Zcr~erlRd$ZC2Q(2`zXD^>&whZ#<44t%}1PPnv0|($p&4d0}R5GQOn& z$VKMA_3l1i&V@)@fST<~DR=CBQ?9JYpGv0wpj_jB!)YiCHz>cjEGqB_=Sn8B+k zJkpoP=d_^XdbiaUnC618b6O;ss-3+?Zq9)^T6M1HTRdm<;KE>bjkFYNXf_0R9 zVd}@}km@!*2Kvk0#N&4V1@@0k8pXUOAQSPMXdwP~WCO#0ut^g$viz6+PIbcx`I}j= ziDQ*&u_2X5@I#`;x0q!nqP$h1vG6m54nnK(E=k{5tFftTKi>>OLzTb5=EL&_%Er}m zpTQJ28~97^aou}E=g3Vi0UeR6bZ7s~CwyMMw3$thW`DikV&{$Qtbx`oclwW%b3T&P zpuZuF=>Ggna}Hq_oXSf`;!9!Y4)9PoOgu{p=-4UgNV_wRvD+RqHo-r^aueE02)1S| zz-KLfD~cQk@Y6X0lZorxD(iCeHX_ngW|Mc zHPKCjz@{hvh{8P0`x7j69!-b94;k1(Z67pBeF$2$tK;{S^NV9Yujj3W%pR8wl($C) zHZ}uwco;al=2^)bZTJXSPrn#&Sp}-jN(oG-|69*Rb`m>kedKuq%hDO#YZsvS2Sk!%(;PWmvDt z;dlv3qUx$a0R0|DZc?AHe)+NHaOGfSm$fWK1L)HzMZ{EP-Lv#QG6+$D#Em#W;|XF_ zi}#AX zd?_l#gKsPO3$65C%6UCG&3^p|69R)y*2dluPt&VRwYfU zhdCdzP%NTNCFIZ0u0NR}^ErFYERt5NPVlkD4UJ*yMPW&?)~J;~8HM+x?;}+zS_0h9 z#Rl@+&{3;Ip#Li1MIPs@G=r1ZWGQ!v&te#~h0NxZcopJWq`bZXA;sURbKL$gjGJhh z%=bxHj0#p?8Mi{6Hufx6S4nPM5E=i3IqoMms9Bk$fN`^*7)M30Pv&?VzS>=1O6e`Fc+0mc`6 zL;nYkK2*PnoqRJA1d#s@NB?&X{r@9vB@J8+j2IaI3riza*S@h7V2!Iz4(HJ$-bYakO`T-u26cIkVv0+>W>X9OyA zx#;$Rb*UscAR001_K+gdjV=3+6IF@NwA4CaQaU4&LW2L!h*20SfQY9n5|$3H0kxi| znRHnzZosVEFuoA#QhVq$m}Y1Q`@`ZvJFS_fGxg}C9sQ?hM`JCWnOg~cMzwfC;G)2M z)dc8_W%#e@+TFMtQn1Y0eH2tkA(trFz?;S>!b}{SP5!pp5UiOncC$DU))LIdQ^XH< zg+JcAX|~Ed@hh~kfv#ZZ(n}r~X~!oa_L_L6UHRDLGP0E!MLs@TpD@D|CEGDSTta32 zJjhe+lJV40YYqqtdVpsfjEF!v;GBe)p)ksz9(PE2&(*g7e77SV#c5e?*OiuYmMf3K z_IW{hPyA{LvjT2QRhqI?k;!JR!!t@sU$CY-v$%8~O|h@{P_3eaJ<3L%Iem2{NLTB;(TR(b)X~^K+f)%^eT}_DN{~5mm5fL#+ttkvc4Vk60`do zLpig0&0kbON6x9EBx$5n`-2z}pXwR(?P@NCnv4Ga4?u_)HO9xed%f7XzR?uj-nkHK zelg9?b$&gJu+s}kIk&DMm3kmvQhhP4yBInqJM%H z!xD|Q=e&I~a6ZAex9b(p^h^Qq|+i-xTM|=bkA6jft;tLid!bVl1NtCT#-P&1#k8g|i zCIYUJLS)@exAor(yHzIZv=X?&dYI)`a&ZIyDdSGP_2r%21*y9qRq#7 zO)tkGEA8Sm;U(DajBuWu_34xh?z7&yym7ly+Z%QBe*nvrK2OV|`)_2Hy0>&&5iU7H zhbqqr%3h}RU#6RnvN(yCdEntf>y3pNAz#jP6Q*3{W*+h#!@q}iU$f0NYCjsVL<+?? zfYY!`l_*#bd%RAy|DhbZ=HT%Ok{WObQipj5K)y#w7^abtg{NR-5dqk5N|mKO2ZK>_ ziH43L#a$I=yK@Bx!cce?avcb%DL=52l$ou8fjF?RXYT0!f$s1byKi3K*0hU%%Qye$ z=+5*nbXPX`M>Jul(5!VEbwUwjA*K9)A<`^$NS=H}0<$@RM6E=*g~GaR(Mg{vo0%KP zv(i2M^B`STKO`OxgztlxM@M^P(`=6M)RghnrrTCJo82b<@6TIo!<1n)O4I90_F`)! z4pff}_*g-tJ4$7gehIltY0y?LUL~qpx=}9No^}ptmMYsag9?jmi;udz_t^Wp^k0r+JR^&1 z*W*yBqlB0^odMs(tt9~?tBl7!__|4X${3B4<&6x_p8sSdvV|x)7%n;oLnD2ewSUW^ zu+t<|YB%9#o(NA4dup|051PZ0R7V@BcuAT|y_gL+nn<&47V9d`sn{XoUAV@?*oWK| z>Ape%S!(uu1dfH|yk^hoIm+ri&jyeRYZwJS1Ip8;bCbY%zwA@Vw%pAX~_roDI0_(06T%--zW@h90 zcrFn7EhZvDt_3r@aX%?6JD`1vQ8Y&}vG>AZu-3A%Z|=XMZNcr3;3GcbPSp#`I-+V1 z-^vmChQUnP%L;GXOxf*G%Ltw#=RsC=z9ZvE4kCdJ+<`=>D1~O{&O?EaoCVFhzhlm; zQa{23|D3@B!D+?H4xL8kSq;m?*Y}^PMNh#YaPgpKdgMuXh7TF`tw8k^d*vd5ri=0Y zq?)Z%F5>4K&Nh7I$WP&qH?qXg$@;)Qm!_Q6bdUg-){vE#L^>4daxc-9+@IMDP5%+JQovnfOzg}>qGg)K-luv*z z+9|N+0p%c(|C*|XoqMh%u)0w#l2N(n2g^B}i$i<+iEQKRudYA8-;E3<^Frabg)pb7 z3lS>;GLIQdN8V1CcY8-mS0Ot@VH6RDo*^SA0uu!>y%hi^3KDvrkcwR=CFZdyO=bY_-o)0ue}$zChAO z3Uv0SQ(h=)N~L?DVSq=>Z!Y~Ewpr4KA`Q!Q4c94dF`gO8x6vVa@sp#H^jk%Rv=7km^w{?dNYrS4)ES?b2W5!@NE^53b zZ;!I-M19Bwm(5;jn5KfB`pIp$f2nC1ax&mK*W;HLU?G3AoyygHJP})GFl`d#wwHcu zsn>Jd;X)U^G(dZ-s9uH#4ik;?3m&Ub-8khGx*RbA{NU9E;Ed1)MVscisPh!qJ9q0cVCj7hN+n$?G)qcEf6ImfU|^+JasJ{*TT&`o&b4L>SL zSm{EaLg!3>A0d7kg%nMZH|Z4~}o1kFvWzUyf?axZ*)mgfF6fRUR(OJ*#z9I$tlZnDp{+AYp`S5XQ-8?1I9y zh|GH>!OBzYB6EP785f4;ZD6d;EWiCfX0EVGxRi^cHE?d%>zPoCVhDqdsMzl7BOx-< zHmVM4pj!59QqHIprn8hVc%;x=D$X}8DnX-0&0#j&rpm@14a&=uj)?31O_zT8eJVSp zBjw9gyPFWMIbwsds86LWdV?U=t}It~0!4U+mfv;}RBj>!U1QCnX7wCy-DX*Wd24J% zeaCW((I#(J(o8s>M8Z%aw-M*fcwYMee&dy>h6#@%n^q`1Qs2l-w^_&5(d`jQr*voR z_J@l$fJlo%zwJ3T2T!L88PD2Oi^Rrl zoUWW~+otgOQ=CU@0-C-#CJ`mCjEU^ocrn{W9ZQ`;Hq zp?Rl2Itz{fUAeo&c9_Ei%i2nXEhgrzKYviQ_&;+n%B}ZVIw*2TVN#upHOxl8r0 z!LWz9fsP>o07mY~+OgMcF?Ua2cvlZT-URf7gq008F44}IMdY=@ z_&S}^9nd={t%M|jEa`*Eh`;Lh2Kf`G7Hz@tSh71tihpaQ^LyVl^x}@KnSXqzu*9 z?Ip+J6`6bC8j}dnwk`7LzW`=Al6E^}O5ODv$4atdkMsxd-djDxn1Lb{(#g9uW7f^d zpgpum@L_?WeW|@Gu9O}z>E6ZUjLtY^IfI%eDc1zL@npa{@AZEYq}OW=v$e%3l61yQ z=^`x(&`Y*NY>>+1+8uaHnmU(LwF0Qsb)dD_O;FpaY*QaWX{l@~cv8rz8gFh8D{KwN znmTt<3R#RY^x0`7?9`{hmYA(zK=Nm-^Cj6vjIse>(YR$YCj$`W9_2?&!6+px-sIPnY<}&Wx7~>V z-+c|{lg`&f>zvTsomt3hmrJG+Yaf(A5z|v#h)WKT6;ov=qHQ#D3R==6k>YOQ;<(-o zyA74xvX++wz{S63OPT+4j&boMn}!c0)Uhj-uwbNMkFX$rVIk;*%JmQ4@qb=%@_nDR zZvP!*SxYv1knHFhM5yGErfehGSb>6f-jEM!Rs|C}n~tJ*V7d#eWeoJzAs<6w0SKVK^Mi7bk z_+6jbHGe+O5PCC9hRDL=CQ~9&P7UnCCBL)bXy(0}`iYhCuxoHPj{O2M=Y2P$b=?1~ zHU^jQtcma}_0MBp6g`^4ckX!Ia6Il{r+omu-B2|;b}NxT{e;_>!An9uKud_-;N(o2hyMq$rcxoTmlt`bMga9EJXqJ*!XaIp=ben|GPygHhH|Jx4 z<=Mvd!5{Y=hE?f!HkP0@F2kytnmeX`Inn2MHWb<2%ct*Q`vjxUk-JMhRX%-|we@F}EuF(;gjM_o;qE>G{q#zL~ahjs+Eu*-n_}FF~EoCX#8%n*( zP-dvOOF@y5G%tZ#T*n@n2g*db8Pig*8xdAdIVI7lfqF#Rm18Ko>w$`1c+%qBO;E~4 z>LSsb=RXcZGi<#SHH4XV8vqTHDlv@$b3wX>YPKh-0ea`T@_p_s1|f!uXQGH~NFogZ~XgVfi+A&tE7V7Iv?=f@-$p`s+RifOk zY5NK3YM3{cB298dvW^1NE=4t+H_&rg%f-fVILBtwdkqBbse5P?@;e4?HVVk4V) z1>qO9tBLyLn~hyU9Jt5#o_|C+^LzNDC?2u%#wCh2v^n`wr8?G_1c}Y&s<^QS~pTCJQ z$Z2qz!L)2-7^>;cUF9xSSSaCz$$W{+fS&xTBbA;HQN^N~5K#Q=*Gv=b0JE!7oa$}3*0 zmND0dcq5)jrt<*h4Y@~q##vDmg2vLSyE49j8 zEMS$akVOPTW@Y}hNxAotxwUw|WD+6}FEq3#jH<72w_J;auB{3pZhapn;xc2Usq(b? zE$7GT7jrJmu?ln>@^~c?BhN3dyRRv34>X@lnXpCcFh}YBLQm$7#DZr@n-z>U^Gh;q zr#|Mw!gFO!=hb%HwGNtg5^b&3>dLvlvG^UgTmEw)OSGhs00`}km58N8yBs|n>OA!6 z8HuEB9sOHFBpjlubb8`-?d2bDSr7mNf11#1lwL#}LS#h~hL0y>@mIB-pXXyNjmojD z(T5_tnyfhq5asYSX5zb)uIPZWk)paq<%T1;dBH=xXZhSPRmIpco4~7l9|w@=Ow6f^ zN+Pj7ANUy-?ZLg)C`wLJLX(BG^U$=2_bWM2xkb>{;?n^jqLG3(tLs3%l-uA_Z@ICj z#g}5G{;nI~USCM?wsLmwpOS}M#%Y(fNu)hM{!AlzfwB{d4^u`zpp_@3F#1h!io0Xx z5bg(wMj5LNgIZKt?2l*PoMWnYq+UUup{$<4&z_THzjW3Ic-l_*{<3@pT|U~i1Z|yI ze)+9EBkS?!hhT<%Q8(_i7W|%$XZiJ0w00FS;NzdLWthg9t^Pe=V?zA9A^SgpEh)?Y zhAp)ZFB}zAUvdei_>+c0EyXhYZZ}?zHkYQ<@;ZCy0opNw8*o+y6y5RLC zn04~m>TtlD3%9-@wly*sic5mDHDH#(L|^lMBIP(J-)ONXBgO<5wfAT+jtW98}t1>`ntVn zkgS5xlkc!g9~ZOpV{w$#G1iTwWIv!{uS~mAQT{Vf=a*7mxl)-rv?qYW2OanM!uqTjoYis@@Tdpk zaZXy8K-bj^XIAYs2)ES^EjM|8O%VRB7#7kna9ct~It^L4ZlUDe0I%K7@N;Mo-Hxqj zA6&3xqJBtBF2hCDrh4y|OIwTa5&rv$k) zr+{LTML&fUB}p)t;?278cA{0D5J7ITF&s&%ip0SbSJ#nh0yf!^%~mKc)+pT3-CjSk z8?>WeG5Si~$8H2ub=-&3U&Pl^Lg?-uDx_N{n2E6=&G!u~Tm?o58@`TP`bV;ZIX%l3 z6PH%Ao$ol=psj5c=*ya9_;6QK$P=nU-q?GkshbyavAQF z`SZSubR@FD4)-QX^Jd*O>t^jW`aBIal#4(~H`GIwywo$c6;tJUp4#pdbw{w;Aa&_e z(5W>3hK+%SI5AK4yFa@9PxKoU zB3rb124aONHx<%Y`_ls|&uif~=ZDrymd`@HVa>Q*E8AE9$m%Zq)@n`4pq;&)BuT(Ny((~|;g&)u8ya)MdUQnlNi?Vd;n{Bmgwu|?TcwO^-QDiBNR zWG_ywz7R^Y`SE;VW0QBy#~a5V)$~>&<5?lPL?&7r>q1Ob*tGYW9HxxDp|_^khsC_9 zau(iIC$zwg1~3Y05YT>t=WH8#BdF5mLHIIr!iZ{d>(Y)+e5TtUL&;Iat&%IDu804#lpJ^4s+53 zUOkTVMytIK-k7y7B@sXtnrwH!Zu@NFl~Ww9&7AK4_+c(mWj*C4_}M0YSqqQ=F zWy%U1?eB*vDE`heE~FR--Tl6ZjdgB=jMXds;E6Z1G_$t>lwQ@cozYBVgXmYmXmf!_>nJRS|cv8N(Os zqL;dgKBxl9ekfjo17z@2PM>@$hs;)KVaH#;=UJUW2Sc!0clI$I7 ze5GfNy7u%}JDtDXT&zB8D*&qO@Rw<}7rKG>3mM<&>w-tPtgmBj9Z~2MBgvNc;oLC{ zo{{9=A(P~a}fjmBRhzqmkR5_!}5K5_SYoc?qMOt4uI+j@@wkhBYU*zJsiEb z>OHV74Bh?qZPLvPy1i_7u&>=PLb*QC&vR2}E_QP86uP5&spE_SH=S_xdYoc{-?(b~ zdKq=NE#z4B&$wpsR=l0Qu&e)7wWbo4-pIvKjds)FXQj<3be>(`B1ce0e704UK za1k;Q0cau4%*-psaLPC4EAIH?*Hf%x=?Z~O+Ph1$asRKi>)Gw;~g4yK6 z<_bqO<_dFllM(J)U^!bxlE^V^fHKXwJ)pG+{Tf}Ndh#ci>soQh5PS==1RjVRrsD%h z@KYf=xM07^YIC3Y_O+QVjIGO3+oPA(F!iA`MhSg_E;OC}_->8a&p0lVL^>{mYB_Rn zENNU7?YR@HMGU08^4?ho5H^>Jy`-qMmi#^1%afMqpD?EE_B8EwTz0Lb{WIujsEq|Q zn=a2?HNMHHs^#M~9*WmWU3Ow!6_FrXxb1W=e+)bf{m5gF+@drHz^y5M>ZY?J!B9

    |Krg;9<-gDhDp1ov#1mndYSX^VceAZ(q*mw%YaeV!AIqL9P>&pDS93B6+1#AEN z-1gn4@DFpN6Ro|YoxO>pvxSLMVX930Dmwz;>J?S_pw3GjU$OPl55trZl(E8wY^4*j z708cD_jpTaBgpA%u$Wb{!YT3cj)7w`Kce z%Z}mCZ<((HCa}g2%jFhpM2w~*FD=$|^`kc$o5BAb3#DPz2;vZbbn^gGydS zMD!5--zC1&EhbHg%Ei#aDeRnO4r0Si+mNSd+-LLMvk2?=#`d&`h3yUkzYFpRT+@gU zLz7Be!YE=4or^zX0X7!rtd11<&h1bL_4-(}ztm88P`wgoNDm!28kM2TAQ+4qfzBvE z=zd1Pe#!T~;lq59jMU!3$nwi9pu{4eY{_X9_6`1}NYerX?6{8tsG zKUv^!G{SjvhI?HhIo3;(WJaC zhe2U3a0ZJ8rbSVY7JFuiu}`cIkRCyHelv<4knAWOb)LTGZ4S=o9>)37XtfAyI??p0 zruw$7(%gqMN9ulO$cMSL*yIG$$&$xkiUf{oim$Gj#1eh6qhro6O=*$+6pK$`(^g)_d_sC`%HqN;Ihh4;M7(qcR=iKLvi5NVs~-4WH6YulPofGkeHR zuWAGlRZzD)^sFg2BHMH;IceomZ~3vWyS3!Ac$v+vUBS@$V^S`6#h%7gK-;rIPqP<> zd3gjrtwU18$17K3{+ukt86u+d_%Yqcu;@*{f2eFB2Or9*Oe1rPh4;Jk5RB{AC*R}t z%@}s2-WXs{UY>(xIJRx_Lr)=NDCy!PEVA*2G=aH8M_yFD7 zs9a+^8UF>7Uwv~gfrp@n`>7ksK&>w+LCcdB_$!ZIRQy+%UNnN$ehrm8`A|6bITsh1 zuo+SmIeMab4FdYQK+;ip$p8Y8H9?z{?aLg&OAb$P>?rZG6iTU}+x(Zsq@>R3p1onb zlXGA_BezjpxJh`Bm7=xYiMQ4Sw7t&W@LFY%4YftBd55KqUf9IT^PV%_K3C{MWnole zH~6!&n(EWwmi30UK&U9N2g`kh_D6|Lzlu+n)QHg!QyE7zI_Ys)8>juqj-dkf5cmL+ zDe%W5Njn`;f-mMtzAc~Dz?MF>X`}UON-|iupU-?%Jm?!V`LsCEo^Cp7H8Ae1XHrQR zd5JV6>tWn$1L!3hf!Iidt5!>tsu><#&#lsHPpIILVqJsI-dn zqP8bgRmrts*<;Hk_HaSX4HQssFD!yaf=4G0fBLQa;kn0u>fq;ry%iyZ=bQ;?C--L! zeE*%=hBVr$|^Cv9iOY$^S(Z~t0FszEDZFQI-ea;t_6F4sjyW&<0c zgNoOlC6N^ru!5tDK>!ax+9G?!qSdOKk6M~Uq_bOWTFj=*OU!X+Fk2|j7FZaO$MQ@{ zb7h`Hn7tCeDsg^XZklKqLCQrwo$^lc9C2-Vm_J;7eO_FZ2(n2UyuAwdHFuhG?aO>=nE}1xI)=hm>{?No((%A*KVbrE0$__;0i!rh{*Qby2wJLU&9U zGEg=35c{i@zbjI{otCOKG#rk*Bcn_o#HGEt$Y!F$qM|>C$jDHIWXL69e=;PF`fUu4 zep!;r^VpSwW}>082HEj;|7J%)lE2klqKkFt6#1)32lvn%Hf83AjC)bGT>hC&kGG3a zkfnZiqMIkEQS%svl5m%llOZi=;1a?HqABL~+K%4w*aw~}1k`MbuQ(DVZufm0dQF-Y zi|oyouKvNyC6Kv)Iyv&?XX?Q{#@Zfd@!*M-7-xF9L{%x1S7BwUs<4!a-j1gMmvrlFuZ4I4PJ2`7rOK*=-ZJv9|jZidzAe`_hr z{mG|T(~jfcq85Nfc3lI2w+~Wqa-!6XNkv$?CafxZ?gT_%Gf+up$$AMyQ!RVE$vXEs zo8|%ZiD}Qj1p0mYKC8ZadB>V9Z1$s3i;H2k1jHqUwOG9UP@l(j%0zDVqs zn!y!V8ddr4Il5-9&AdkkkTq~@RBq5=f1@(IK`k+B4=-VLAvXAgmqT%WMJMIx&#k_j zMyXbSE)>oLckm?nHU}8_26r*}|ey zr9dfj)SSf-7g%^bGDV&XUNxyqAbGDneMDyfWY=*~{si`Rc%%4^X zLA71Z?)$IMb%BSP7K%P@$m-N!L;LA!7$rt&NJf!1O6iiVgLfC#DK-xV|2iSvN_uqM zXldQGNo6%86C#M4`{pfHEWu;uPeRtRXSpfGP>3Ek>m{ zAs`sS6$f6Pk}`6KoPBJ%ayioIm^=aZooi|ZeCj9tv7ZySeeE)v{8q2unR!Rh&`44G zGWQD$RQW0_%$CDN)5SxTfxSxOXbBx#XE zT7^<1B2-$0X#dWW-tuUkneol{&HK&w`@R0>+;h)8+dcQ*hk946CCkFK*)ydBE^(Yv zcxWJg+qXA1KxnOW-)h5>eNLNecD)XE(b9k8Gq++%pykvDL!W!UY@n@(rpdn7)sU;7 zcR9g(3;DRgrOH1v`BK1(uJ3}S0m#VH5r)hgcMRs_wF_YgP+2)eo(LF#J{(_ zIo!+lJSX>ky}rVH`9Li`jkH|jVzWdt{+!8V)oH;G&)lqO?t%M0lYZX#{(ZxX4F*11 z_k3~>QNLXco~zw<-hZxJTZ+K>h=zB>C8w<3I2WCYTzRv5$`!%FGCfM$4VjAVfg9cj z-fZ#e&@Rmxo_lmg^8uYM>-NOj+M0k#S&Q!K5F?cdd|4f)S1xELs?w4p|`HXZH z^4}ickc>ww@{JeI=2t0e z2jL06L=_r^5)h(-C(~5I;J!2xJRCrapmB%ra(x;cKBwNORT5#Sj=#Ijq*!14H)Zj_KSg6#R%&rUskQc+T zdx7Y(5QrxQs93^3EaBdMybp0SklEurEkdM;??;x>8j~#~!4vc(C;R_Q4}cHjX) z^AGg6m0}ir_bJ&cZTN2I6-v+D72R3u)dsq?wfpP0B_0tCX=LZk8h*jEp)$_8qujQu zXt;ffN^APPJ$mGi?cORzL?d$jY4fU6k|BqZRJcCxO;Wi%NbVpDeJ=JLDKLq)GjNs3rim8Jg8u*!qun<1|XDPm1&f9!#Qg4G*zkIdM0Z}R+#?#kx^uF+15 z^VL|jmM@i4z;>jFu)wgpk2WbQUTtvswmi@7cr z<`Q6Dc8lLLZ;R3J!4nmM3Zi`Zw@=2q?AiV!KYQzb9z!Qn>91~18;h4^ynWTu*G^j# zXuJE($!i_Kg$jcH(IEkgo;=>mn|F9gXY#R#+-2U<)oV<*DaRisEH#vzrj{-`MY-8Y zew}r5Y)#-wQtKImfT?S?P*e%2RYm7#-SvJPGu3YTrB;)apg(uFOo&Y6W0!5aPhVWT@Ux9l`jdOlgfDw~5XKPfw-u({H&X*`~X65?*8Wa=sN-R22+7DFb?(*1 zb(P42$p8;*BIJ{^0s^kvdE>bE?z)HbHi?mdN^lf zar(l7r$6t9cAB*sC`wL#7+0@B{#xGtiQrwK(d4uCc^$dzzR42P=;`Mlso!qWY~Dxf zE95<2ntJ|p>5bI4!a6&a_J|p8pSC{S>&G3>-9fL?``lWD?^oTr>OUYeJ8s9`SzGN$ z&ppy}tipR@trbk)xi?Wf2wKCt17d#n?uNQrpc3e9CT%d=71y{-kd*v5x zUa>;DRDFjE_mBIpD^hp9Z0m+{jZWF5Jz^^IwfBQu+^xbyf?eE=!ftb4Bd;m%OKnP_ z@u#$g%5AG|<0(BkJkWoG)hIsZzdEb7}+EbEkE&$!gL!oGec8?07gwp>$-&QR4=y_US+L%l2J*YLBbm zx6L<5+=%-|S$p({)AKyysT#KLRtdgS(%l^&pS@r2C}kw3_<9wG+%3^M+SI)3M)C=_ zHkz$;7f;X5Ju5xg%7Ru^J&?1wd5^YTc5LUye@W&!oNl4dFD3Fy=&Ov=0*=sHh5~QN6?|uamr`iHXU*6 zbgj6Qz+?*7nGJW+J>%SczD{Wgq3TJ9a9SumZ#-hKXittA=apM>71f_w?Y3^@Yc%7& zVp$p9{Bhn(&QBq&)nOev7KB)9%JC{6T3==3mt`~79n%vwrig2ptHxa(y7Gj?p7End zU**C5&?=pSWU;s5rq2o9qPd&edThVr)cPgfuGmGW)?MGc?A_JW`TR{HQr@H=HBYy3 zNUVKD;4HZ<-v8!SxQU|ZS51KrcO{Y&UpM%2F6-_~Ba)VQA0)(D9i!^o3+6k_Z|T|QLrd!c7@W7nvrJ=fZpHD}83t@#d0t{b-b`mxc}RcDy& zJD%A2`f-`Z3^<3EmZGBMVRV4dbE&T9((sWLt2?ba%RURL3pQK%+1RI zGiC>$Bx`I~(R5V)l8r}aSfES!R5jVRTNBmH!*U+Z6~29R;dG^zJzQq*XobSzd)|D~ z54Ss+eX~SSbG@1Hz|N`?z7ntF*%tE*JHO}KH28kw8ELc-J&|y1r?=|tb9^?FmgLV& zupiQNzgx-QwE3l<^5vy7L>kZZ+SXL&X5`J5JTV)8$i-|hj`}0+WACn?2Ui;k(bP1H zUhme|+^8~}y3Tf3M=`Z>J4tcw^@kFQEpfLpG%M$71#?SdGfbscEj!C{~!zvpFO(awrzFA4pwK2bJi)v;~|%4aBC%H$cy zymN<(c-Eg&DRFjTAmKpEtGwwJc9{o?9|`0?OSf<7$meZKe6&O-y(u!u<=jE5xsME1 zJdNGwH&4q?TjS!S(ASM@N@-nOZ{-tGZKjQcZMiBokLtDD{KOgmi_3Z4LzjP#FxnDp z9lxmXFG~n*ULC4Os>g4%x0MOQfp}_R=Tzc(};1!nd3!=4s{i2sT%3 zindzj^1ivj=H5azwG_v5TWW{wg&%4*m7e%IyUZ>8t)jF2Yq5*pAB4ON7bIQ6kwYc? zs|^pVy5jD3J>8$$_J-!?WAdp&tj&VdCinHuVA->Vt|LB?TJMhwiEUL_`=*8US0+fYelnmvt5{O>`lP+NG=%66vq z?A~SUfQd6$ctmxo4k=2s}&MAJnb>YX<=z14RgIRm} zxh=%LP5L3+Im0*elFe?*4b5sHKHZ0-?)BZzd@IKJVu@AVt_~9(TQ9F2CvldIbEvi4 zn!=T5IK4URQ=beKST;!8?3sDRH$0$NuT~&!etM#1RapEXZOW;hQxQePQWeEk2@}Vj zqlPAmPv*TbD!%M@@xtAv+0J@zirxmN#Hyy6bF=Te(U5te$V z%fy{l_XN848?DXv+>s_WS@+u+@0&AwxL(9h{k){+s^T@(?6h2o-hC?%e%N`@!kX`x zk1Kv(C%1K(va)M~!)NKUU!2(+M`ZSv3yX>8`}0H#EGemY+$B#=mA#uU7W!6%ZC_9K zcC*L?_RG2lmnI)q%E)%s)GrP`+}6JMa<$~;fjo;nc@E-dM8rk3WQUHv&U1B%3<|@M z^s~>WJb(IKy(8y(1Ctik@I-g{y)HiWE|h$Yy1rP6_Hgr>9Z9cN*omq??S8i;e6r@ZUpIQU zj<6k7g3U;6hMSQ{{`OB!`b!J#18G5a#E>8gIfQ6O#Cs8`qe)t*LyO(4RWr5s#RROL zy?e9k4Q{!*y_|12_&8KHi*E_y6R2K$ahm?>g}06^6{!~Muatcr(Z8y2$%(xS#Y*bL z`c)d=S#r9>>>M1VWi4xHIIgjB)28oJR!#}>FkGSBn8Q1nYl>s+dJ+9fLyj~Dxw4az zyA(3!dcH4+#k+RCHQ{{hc)e|%T3xd0y=PvHN}tH*F6OLrt&GuqklbBPV_*JaZMQS6Z=`#}ZE?(&)8fjZxNeU}Ga6a8~u0j!kXirom+&p>mWt(KYyL2ougd;8J;hp$T z#a!$%Z$srD2wXTzJ(^@{(z7Mq#6DL-`WZ3({*xzKZ(W9dOdfu~`?@jAuG=+EmrI7@ z^+t^2e2m3ZtbvyFYO$ zTp%P_lQg%42rqvi|G?>zv~WU>ze?1R6Kt942OaLIel}eiu5N*MsnQ;lJ5WEf>g1Gp zA#B-)GB@(})E}2fn9n;95P7kHLvb;jC%%xGg73c5b!>@ii&f8_cv9Y;ZHfGx@2`5Q zo{`=s6=q&?z1puwzFdVu)G6~HTL0=Map_C)-nz(meTn&sPMs@1QsYK+C6bFr0wWcj z?EAS(mMq`Eu3vQ7SnPue&t9)Yx`5>loH=*NBLjNf8BkW?f9)yzFCX(zs<_8 zk#aFTqI1Wt^bmP?eIG^sc3)xg{rmx;qYqyzWJ}Edo`6p<{9Y+}UQ$@Bzvwe()QaBN z2iq-^efc`VIo~B+3h%4Q^59W?;mdbdtgwV9drRNsm=81YC+(CHgQg_n+vo21AWDeX z(h^}x7#0XIv6=3Wer?T{`pu37Z}T#bs5@LKBK|y8Fw7PABd7GoGLiN*rv`0h*$LNe zBW?U6+O<=zO=tTt!!hAVP38iDJ?mdKa(>_6e`0#EkQrai4@&h$4r9(~6-En6O&@Cr z?1?yN^pg!K`gs1df4~8YYaQ(BAmtCR`0yFOqeHj+ffRjc_z-`n!i1<$f@o0u!3V&h z-^uI(I8OMF__)fECcRZkAH;!*UyXW*a=+6XX91$<#vPY=cot-Ho)y@-x?C~N{+QeB zl9XIIWv*OL7v9^7iqNaF;vBUotpYY)`ML?d2+6r^i!~K(NafUd;dEsm-G8Bo5O%wVK68IBE*< zvCE{Vn9DUUez;hy+Y*u7ziP`}F^~q{q45O_MnWrB-RIen9_py80{IRZf@TGK= zRO6jx-T8-92UB8_jvtc_Jf%Vs{_eE=O?PojhJWtEWAB6$VoK|}(>UbZ-lT3YZNBKP z*~mHH!o_s>G`mOHKrZ{HVr`O1vsTji_@e=S*K6Zn&62S$o!%V$OzVWtUQZ9r!AlLM zH%m5MyJta)bV;-pIq2VVEaz2f;l=WhjSo#U4`zn#E6qD}edyJe+{3hhxT5`pkl?CI zRIdkjWNOy64IJyR5ZR%CH;>>@)|S+%mY4tRbFcj6_Ccb-G>w@pyE?oq(}bzi zy0dCGb7O91cl_v(^v!OyHwb9M#|_#S5Y*j2pE|MD{yOd9!R*+TVx=ojU24cK5Hu(l zx^=5F(umf5_=C%q5?S}o)seAblZ8UnZm+quptWaNp-SOb_oJt>xorh6eb^c+bY^Y! z{1``?q-2$2a<$>KmaLCbF|Q|0DXrw^?q4HV^WeDW^nr!5gG_G{1)YN&^#&SVm+(#f zynNc!$6gx>BzL@l^AHYt`rG|(jks3xwx$G|R|}OX9VMwJ7@yl66H(ffZJ=t|;Luv> zCO8~qU!7K_f`9&VlaImGE}sa`o4W=&XgV$TUe#|olO3sVdig+n%rlV%%S-c#cRsC6 zC|nyHrYGh4d6GkJZMWUZw2vD*Yz`Z zPx^}v@A6z*CV8l_SZ9Ghk%vt(_L;!Dx2N(28yiSfo*miyxh{0e{ZwXGz4+;@(0<1TS=vsy*wy zFJGHoX24U_&RJypZi>>gE{%32mrIuZ;T=iYLaUG69^rc2uYPJ{)w2up5AW7mXs9LD zeq`tI)$?8y#BLf6I>6hT^SlKvQ&a7pzVwLh3fIkJ~zi%eVMR2H3y#4OB`Y-2(T&5qbls+G?^5WvD`#lfL8rOz2_nV*5f2{>iU4D%! z+9dZTHo;x@h~RqPz*cAv`SZg`ZS)SZkk=)+Avzdti^-&Y|&Ee#!3 zDVbUsf%`!IY}A1ue->CD`!F2-g;e+oApho{58{*l{F&t{D^nvwdk1ApqfvxW!UE%5 z5FAJN{Xqz~!*3*PWb_x@|NQ|D`3p9<`hQHI$>AfY^7X@lqpc4jhA`v{o*Ehhl!FQMU!XL0jN_S- z`w!}ute!K)B2dU)BqZ)aaX20o*<2g_AVZagV2`fk{)BSWKoWr=Aev2YrhtEM<{CTr z@i8V^kSDQF|MU=z#Tq~4+5e6BmmquTVf{)EM=?gN4T5p%ec47suuk>-IGofU4CIF> zn2vwMhO9sbJXJ5$+xx%7ay(*-t9@w`D19ODfLN@*pL5XhjfJQW`6>-o*6%9?#)D1@ zPY^Q%%M=0QT<{kWem$Fk4QfcH{r7a$c)(7|(v%z&iYo7n zhkfy~F!$?Jc#jL-z=1H49y3gd^bn@kwwgSkHeUo@)w zG7MA~QV=s#haXyVz5!=D0Tn&?>g5=yj$~4VJq=Hz&*pdC-Sa*Hm=LHa8jxQL0}$A> z_oYxV068Pg_5DDa75_~88XXM4zk_BlONCOwCI`SMxy_+ ziX?jdr9oc~n~DNn^1`ZG`_HQ4H^qQQrVD#j)!A>^U^*wME4@$5E#pgnAI=G0(AM0lAetBC)iN!E;$b~?EKT$ptrGR>aZ!94sV%W3aaL*kOw-YB0htwPXezy9t zK*$X5kEhb`)>I1Sa1bir&+^(Mt7RJ4AM|j}lUb+2g4|*ki@lo$L$L$9gq#8T`&mL| zM99F}(lCG+NF>vosU)~giM~E{Y2M>I1CWzo-j)AC!>>b;jL?nXZA2@4Akh*Z1P43l zV=KJu8mtDc4}kwbdzAbrX4ni&K*~>*&lbS0C!$O!mT&B42pfQ>vBGxn@q0YVFtcC& zF)=}LjPQ*ED4sTW8gg?LBdI9$#uUf``_q7Zw8XzBFoHMrf~h3Y)-%HHYU$YMk7_sza#^)5)p-O&z7otY z+Ok(b;`fjL{bPabDWOyX5t&$f0-g+=<@A;Dm~ciSVigX+QbH@^tV|4ey--pBcnkvZ zS6!1n>|mm>nhHp}0iYNBl?nV>dK3fJf$rGlaDxLQ+8_6EJWO#=PN|1>7xwtBw+NQw2j@cx^BcPxcBRk%>~P zs6L^Hm!QwO(u-jeLm)8^NT8R!$5oa|SmLSvSnE>SuOp}!*5m>{98M8629E2j5}?nz z+l=`A!oa#Nu#VRA>9-jogR%0JLjLjFf6|BVzvOa8WjZWUQ5;Sh#rV#y z0?%MQo)vL7h|pfxZu5nA-o{YmWN<)DrB;NsA;uo)_fbluyiT{k3$k*E|hvP7kv z@Kh4s6U!=6Y8(a6G_43Q0pAp|Okf&a89 zSnZ2iy^Wh8LSo+Pa}G*qS2@%&rlkMk)-8+be|1EcL4oFJN}D23@IRs z3OS!fUnJpE)+!|c;}1bQ(NU-jKSS8jAWLfWf3SVVBE>+9FR)_Ez{JRo(R(O?3$lPu zpK0A98JQ4}bSnU(*C|1iAt)rd3~h|ry1G;XNMj~Q0}ZSq&J37g*yeSrtt$wIzZ|p= z9WB3+WC%>>==s=05vla$$^OvX2)LENIGX7T3ox+3hWJ5j1=a=HNidyeM5pWqb}=08 zsnPhPKS7!?F#TzpOFDI>9faTy%%c6m3j++iU$HCtbmjQrzb1T4xeD`T&5gqWvtvGU zj4)6gpn^@G#n7*uUlYMde*!lyF$M~1sOFepR39v#b>*pdSuDVugD-l-Yz~-kA^uP^ zrQso{!N>uYSrf${!(<-?^+&tx7g(sHIY1cZR4;E*jpGFC!T~}=>nG1@3`XrjA&(0r z0f@-7&on_rSA&RUP&!~7h5`J`s4z;~j8<%q?*lw@kTLQi`QJ}NI0oh_ zGEF}K9};3gL3+KUp!MrlhWMYuz|6d^zpg!+Cy2xK!#tuL#lk3-NYP&z;zriP9l*9e zNCqtxnPd#u(Zx&g@xfB$>344lkpMFSzEXch0>9QmW=A)eV6vT{c;Q-$7A%Veux*Q8 zaI?Yj(?v8Gz1#!NabxnSyUj470{jiK;LveHemW*?9>F% zm(oXP6Xo&a26U-^(7zW?09}JVy2xO{H!eVz{s-Or>;%v?>7y^35gyC~=tvO@J*)T5 zPXK)xee|z0?x#)v%{w}=*Ss(Rbk#-l;cv{Iv>bs)s-0-~yo(co$5^e?c9_-8_$?bW zJb%SR;4zk~YRQqw$^h^85BHm|OavZdy`J4RQsV;fcmILst(*uv#)54qD>^3z@NWOW z->jMlJjRL*5z4za3*a69fj7805qOLx%U;#-<2=A`hhPOgwWYNafyY?0Z-SPHA>r#B z@TO?^Tel|ykFjXgK0y5)jO8u(!lv(-&(C`kfVYBE*hDXVIPd`hBmEUNZR*rMcA!!N zU-aG?`N4!K*#jA@I7#z?It8+ETpxVV<)fDR2@v{IVSrK?X5^4E{nXsMd^nsDgd^xo zU`+$-wCD>=CQx=c5?R9v9+$XmeTji>fe$4ko3U6ygG#qiR4-J!Zt{=cxZv$!0!g38 z#D~3xi{|2RkznxA>7-FV1|Xc9$JhlKKD}J9WXy(pXJ8mTFbwqeP@e=#M4;IU$_5NY)#MQzv*T+RwEeOtqeuaV^h znMiPs&#C=QF;J1x)haK15T^aUJ;QdNHrQ8Kvg5pKjU@)=>cD_eYa`_V1syMjRhPW7 zSmh)T?lt(z!1wQmV9gXBL%1AK0`8wdE&S$;F9R4uO`Wc4{9&2CV0A8)EA(;UaQRRN zL06skx?&*y=^2H(3w=-zk7uWELtTLeeIV#6K!Xo6(BGRj>**tVt6vX13+;}Y&^U_D zGe&64kbzw|mKsW+g;Ftg4tz91VlqI(h~Og8-4vYLnWBfmoiNy?y=(bG+w(yM+Tn{f zwLkYTgC_jx_=TFzXzwq5=@^vV?U)LFDH=?n&0l?kUp$Hb2N6Ad2vO<}Nv7qrDq2qc z5uo)EzGxGfy!Zd5j*$8Tp?J&=-BW37IFP(LI9@dW23f3Au*T^B9oD)tTLpYd7$}i4=HZ(3J>x^x*T`LiHDK!>wR$C+aL22wC4H0^_vDbfiy0AJ`P9`jjM z%na5rf=GZpQ)@EP%tM3%zaE9=OP~AIPvtZ2gZ(}P_8V;n2T!w1hCXyh@^dXafZh&A zM9{8b{uNfBu{We9uM_dC2370@WkK77x;j>nK{jCQeznQ`mrBteLT?+@ssIS(0-;r7 zrT~W|%hezQT{(20)sM;3uc?-^m3=sY|x)XoR$^#;tm8c_TD zsTyFBiZjyY?nS}q(Dzv1n{o|inj2ov^XLfyIvUuEpBXUhUSc;2=&1De?*hwE3zh*L=Y@$d z1O5{sV+-Wg=C~UJ5R`ktGD3SjxB1NA9fKSwkkMnLEZ4fG-R}hCRL~K$L<->0A7lN{ zrv$C{B4I>#-!n5RC?E|r5I36TZbepry)k=v->$3mumnLIgd9!|r5(kptRT}@4bj$_ zX{(^TDL89ufD5-aVd$A-@~&c}_|gl>H`>2k^kfbk zL?nAbDV@G7W>)>|AcHN626@P$^g-R98MGlDLw!H&3tqCD8;1)Q8V@=W#0=C73-m~z zLo75m;o9Mgwi1svFaw2#Iw@ygBH1u7h=vgit?!E#cmS0hSHMOKV)I58;OR?uVfFq+ zk+6=#Ve-)B*Ss`lp#R;mEA?kTgg%YHX95pg0e>AV6LcoHErVqm_Kc1&C|*eMnG6dt z3GyklHCmO&Dh2wy$4d*#J^-zQw$^cNx`&HcMP||ra(^GYHv!W+V&= zz7#3s9~Q(gVgUUi?7*L8N4io;ARx3sO*z8~K7G{O{ZC)XgDEkDrHSret|(=S3c04# zXl!N^8i;vb?B?TZCk7yDLMnP_#!bpuAwi#UqupN!oxrps&-i#O`8q48kO(4?6MgWf z{oD?2Fpmi!Z#2vGwamdu7$$JVfUVtHSU`~=2(&whxy>9k2)1A7b33JY@;!CHEdX43 zl;&wPGQ)MCgc3071Gq-qPCrnM=ip_~>{hihgJsl?5>Ftqfg2 z0*2*KlGrQG6c@rJ`lzq@3=YJC$`Ak z#|jBA3PH+%LVzfpfm*J+v5SKU1eSpRL&s%y3nxazlk#22b#ZXAZCx{td6gRb?RZ9=_;-Jc8;v^9ezu_4i0G{ec`QpPIfK@KazQXcOnF z$|?;LS|CRJWNv&c8v5&ToPdrVfwdZ|=&J|>cn<>mbdOVBmn_nVhO}RzYh5$dS)~EK z%%Ab$&ETIy+{2($S)f$t{ej&YtWq(iQbL0mlR44xp*|V}h6F+7(P^0sam1s9lA zbj`8OlNm5H7%=BN#wT4a4C31w*r7q&Rz7cL1h9kK;~B!%6kxdkJOMgfd`4x8O7bUS z6g&I^TEc-VTr@ZWw8_qiUtr!UhK&aLu!c12WMrrP5J00HNLelmu)a{GhR2#{$T3s~=eoDq)C)+!jMhP&1s%Q4 z%bx%h`a^iy-?Qu*D0vSQf6?W$LuZ(Q+rf=aR5;zmfcND#b1(RV-XN!o(FsNQMONXZ zR{gq1L*JJ|0)I|_7~To0{24$8*|*d~S%f{8Sf=AdqTrIk! zzWP3kWa#ss_4#6BHxy>N7mT-_7h9PE!*z}HQJ*iUvO?~5It*X5zZ&XehWhIgNIQUL z*f&|P6yVVbGn)%b8Qo~H`rSk+VBYJ69M?X6vvr#dQx{l)#6Ea5v_V1xIT zL@X_Y8Il7@q0@|TL1y6gu;XNiT=z*|F4jjcy+_X4IfEW6qb5IElsR;8C>#$b;W4md zR!(oFg34Ay)eLPgy5=**Ci##tx1S7gik^eOun{agbYxL1&lEU-NW`e9R2TTj`GK|2 z1bLwC=oclXu(lRRUzrr_NsL%pb?P3y2bUVgT&G% zkWL6#1attm(2q4D^qHT@_u{SwtWz9FAFbuiuv5=i%MlBJ*}${&&O0`JU>3P05^chI zpzy#L*b%P!z}W3iP~tG(1(CuFFuQ2=+Y-(U))@=*m6Z5qxFiR69lmJa<{r%qbhW*O z1L`f4@w*Z)r|V7^0qM>F=ZQ}GA8%v@9C|8|f+O5ohPm;vge~jKc}TVPLZ1zqf5$Bo zAVFV4#6laAA!)-+1Bn};7QA;7GjPIa(;GEJ<#+oV^>@6OmWCQ3q$K8f-x-g&mL zW}HA!=%~5z!URdcwa{>DD^>(&t7mU&3FDXvwi_L)B$Q8p5Ozh>^WgHV)i8>=5H_Qy zTdQ&c1i~;<8^?sy@EYLX46G~~exRClcym7t_~0LB!r&w#4q6k&g(`FJvJP*Lp{q+> z*POo$x*7%fHk$du`^?b6@8ClN;0FDmKUe>aHN42{17jaNN5j`NVZi@+eE{mYOZ>3! z*g_uC82h-nILa>OKEr??^M?9ZW)ZZp@06qcnot`C+HVp3*SZDIqmKne((18~JfcAl z(gXeVW&#}CMn8By9(3%Redvhc>?=B){sH~xwaD?nW8W%6XKI>#Sio2h0FGjV4TR75 zmni;90(mea{XHFQJbWzxV#X`*!zu9Wl;{ z7$f$Man6}@&4s(BQ7ICC-*rF{2Hp9-a*a8m3)kI49Er_>o z7Z5TgdlAoBk` zP|wQ3!phR_UrfON_b2FCnVTEv*_-_9$yERO2YWk5E&9qbg+bdNj{XAKrjJ!r&J$QsrXy7-vy&3@?lwYTolOSvV$~6i+)aK{XBt zbfvLq!JOf1Wn}&g8?O*aJh1lUZEwZ$YVujtKW-Yf)A6F)%JGlb(_oQU*l7bitW9We zc%u95n+#R(Z4%- zdwwfsYH8Ql#Z90JGDb<(6h|?hu-IK+@e8{YLeapW$#=tGM=~*-vxNQ~2=?R9m0&dN zo%F_Wv$OMLnGkO1U^5<=C&w4gmzGM+_mbG8M6b+5qLH=ntjb;PQKG>%@z>WoRw!(d zNalefnRJg!5B%@Y!rEPv^%X5&Czmc$l{|b5uugxAcd>f{bIh z8yP@wCbkbVUPc2eerkK;^LhZY-CjLFoK~oh`gJyufAwU8X1{?1k=A3AVn>F%oP<`$ z3~Yc~&4u)n2L|fcfy5$-_B~%5za9+xo(;KLwV1k%{ty7p?NaMW#tk_|CN-G{&BP|t znE2HariM8~*av8u)Gia6&iV=W=IZ+vA?H`eiEhx|SytIyq* zAKLlgsY|%QWLgy>5An#MC#T!NyxLo~^X{UlY|@e;A!yTs!=XE9HuWA7!h*`imDQ z^5dWJ=gmdMN3|E@DB2%^XYCCv(^wzZ?}WFS8}uTVUA!Nkz5*Pgs4H9c_0u(gev1Ep z>Gr*cZKvWllBD3Isp>2TGe zX@y21fI?FE2^LGx1XkOq1XFnlMTB?%-0Ckvha-@u{2oVy#0SM-mMkYhQ)c9J(8g9{ z<@x?>3k8-fo{1y^wz_^Uy%yH3Q8KmhNTqTi|W{p znCNN0X>}8mgH?pNJ7tyT-rx|_AqNBRM)!t@MeKPEop-rr^+m&R2FQkCE-D5z0pat6 z>Q1FqqRcEC$>9t0@E;|hhd5%{3%B;Pv`;dGPcxHe2@1-e7sKqyg~e)l1G;M8D@t-; z+Jr8f14dx_H{Ms|$sE8rS~wj0m)&rgiKCD$TDOt=O<*HC2b*Y)nN3tu7z%`6S)q^m%7kERMK-1dN(7%jM9cMdg2A(vJo8?^BlrU^4p=#liL45u*~B$1@@3Z$m~8WxH_ zQmz&oSpvxM-fA;~`~B-5cAWvi%3O6r`1UVF(2 zdw>P0qakK`V0cJ#8*h7fdwMxx^I7bbgaitJT`@tuD_=Lh(d{|6H!l&LVs`0a>3s^{ zIn0!xb+TV@B=*B7$2|;motiCEv1#!9&JJk@19@S#!7{oHI)*S0mKw7cnnn}A5vxhl zFxDyI$6QK^PcLTCrn&`^NSHKs#^hIjMrxEqhmBTo%jIz1I&(s*ir|X_mMo8en~4Nk z&%H0e>ZC5~?L)=5g+`)fBsX!Ya%$Q!wa(xYsChpAyQ?MJ4$P!9YDhJ}ps|97%Z)L? zM$p?Y2%)uT6K$SiW}7%==*K+u*d^f(oD!rHX2Q5F+z0trUOd)d&Q?8qTS)a{w*XhG zyXUp?v&Pn@6;vY9RK*TN5FG_B$;@g=*Y|aWEh&#SRc?y%?!fuN; zfKcFT{H_LWF2@BNG3k=2m4{clN|dsciQK+T1`=)$G`_7JtoMXWXy2LxT|+X~30eA$ zDdH<8%||MtBvq2LQ}BHdqXRkR1_nf*=K^cZPb zWPXf+kD4{dooX@fZ#tUPlzDUlb0uQBFr?C0%-+VktZV7D&@1Q7bVA%WBx0AN{=PpX zvV(D?UnxDouafKNgf6%73^S4sKD;tE#z!N6{%j}oM&+LVO&_P-p}d2~wvuhwoF1_P zYwU;v2&fOseB$L>glcLk;5SHG-+O6A^RK@lo2m4TBBbE_;oKQT9`A%Pdr(e-L5k(5 zYA%wVf7#$NgZR}xOrEupFGx*eA$aHOnX|wtgTBO`h}PQHn#!4hT_QpT{UP>+^j04| z7AfX6kq_(=iy^itj1*B%ltxX9V9z2Ifrkr@32l#S>w z4-jMst86PDa&xds`dM+#=r&}NS6>WZsbG#e>Z(^!(oYkxpYojnT-Ws?=xvmDYM>1K zo>;=-xyG}`Eb#u{bXuonBF9EZZ}#+AG98^0yn`5eJ<77RNz!TB3C$edOgap| ze~V=vnUPW%uY7LGET1ae+_L(^JfS)2THH_O75_`UB>&HuCjc<|n{p0vBQo9JQFsKS z>rqfq zJ%5E)O?otD&^l(6ePo)*5Q;e(6G2DKQuxL+-QU3dFlBgH@svOog6?Ab(U@Nx3D+}O zRToW}>;=yN+C*=sjUE6%DexjQngR12P%ZH)hKJeVdF@8y%v(Gx(}6eOJCJkzs#bzIZ0D7o>&DMI>Qsu3h&mp~1=^ zZjsbZOm2(~@dM#pt+P1M`ei=J^#x&y!~?Vv9d^os-geRK`bRAO_TU!7GaNX(jq~zm zWfx+9ZSq#wJK8uO(4Xh6off%(_358BKac;|(rNz-&)WcCDGjhDX88N5`^!noc7KLF zAQC{KKHCom-o{hpuJg`Oy}iAWApI{2=+q`oLym-3KaYgN!M%R*4YPwuh2g9kKJSl> zrYdquJQ6pdD4(8G|}_!{g*>femCHXQ8>DNsf9oQ(!G zSH8x~rL{vKxcF8uP=-ipX@V>+IJkr_vUpGX!OC485eR|o;6Vq;l;|C^&{jw>R%RS9 z?H>wEXy(w9^1Tky;G)43gJ=AvU6D3~95JmO!tFX=c=4*A$}4oD7S6>*WdhL8pDc$Z ziNr|e4RuOEc&2>e+|r*@4L|+0J=BGoI5ttMRM%VX@`X0et=7-3&!1v}q(j}spP(M0p3KmfwC2`zi*1-m&&{2=6AHq| zw%LpS(o&&jsOg56YZ!YHu7SE3gM^i@poag-RymY}f24j5`v*VQOFkz3Pwa$0ZRS75 z@4ukb0{_I1{%-)|mCO`pKFwx?N>0Hg$H%x2SlrA+UOqZ-SaK4WQ`qoQ6G9T(JXWUK zV3Y5O-^kBr^w7yGZf7l53Bj;5eQ3Qc)o#44$<4~^{rMjEPHZ#Xhx6;2O^tYtaS}%c zbGkrR6;JgOH=94nL(OWXYM8D)b>469ERTgnrWlu=angl)N66gY!C5nWG>}x8T4<{* zemjhQP+Gfb7A~EW>FqGd`o>5cBcb^ix<^G`f6m4KF%8Z5Bye%@9%8rgY%ovKY z(HBV01AIIKro8l-C!E3*e#j|6*IUCY6+(;I0qh3#9h#^uQWGB2Ej_`~?k}(23j`v{Jm_;B1?A3W;QK3Z5S-!bqChW3; z;tbf>6>c&S@i9f7WZ}`}`lcW(>ZnzKP^8a3Y@p7lW!x;qIy7m=I}m0~!*ybW(nBto zJ&*RAbeb(U8!ubj`FA!Lq56X;WyU6jU=1K;_2$L)&5POWtP>$)s|xs7=rc4+USjUC zAJZ<+#BL<%83D5aXUN+I`!Rjzv0GgYgS+fPj*DmxH-S1j(;|sQiFOr2sjocH`T*R) zxl*Rq@8h!ovju%jIsMxNHZ`u)T9OoyQ-px}0sE$>pB7_wEleeAk(a^Zog3R?zOtG= zf}JtIlN%%_D@#-sr6*xl&?>@d2Id|aP;|_aEf_)nbhdjJW1ufsRdLA458p$EKSwyw z;DbphgS+(p#V(f6Bcy$dy$R%sXq859*UmqezXECjyt^RC!f~CB=nkaI3PO(XEQtFPGahELad`@T`-;FoNFAha^DIzHi&0)V;_ZQ@Ij}UMeyU&{e`& z`h0@5{@lrFTKlUT_yzlq-9&upiCy`$nK!WiDZBZH@P&T{<$v6nlI|v|u+tyg$qf@&-W6X%MYy~oP&~1l#tv68N zA~Yapl8#1DJMFaX;Yp2A9q^O_0I+fI!W?M+=zI|MrH%Z-uAONnSEclYq=H}229hHV z5=V-NDq!ikBR@X?DuKjO*w?2utgUqOm~XE^co&QZcEQH?)-A1(HEc%7sIp|zM!HKH zDyf2Db|eVCn;{czS>8Gna07ofLVyPw2q1pk>XKs()Xl_eaVLj&F=teYweFeql{;jr zeJ2gORTA`t4E4iv^(Mn(p#IR7R4|)4EiCNPapr!A&A78R6b&gWv4vte{oN&JPa!5m zlz6^3ID3E=#lf%$W6FgiOzXA(G)qd;ww`dkdkzK^>F7Zg;UX0>E4s{~FPCs3c>ugi zIU=6y!V$OI8s!zyidr33YU&|$#6-*3nwl+PtD+zkkHLhLszb|AdswUS;Z2oUdC%LY zTE)9FN}Bdl-c5Nu>GwPC5M!0FlsFzzQEVcKW)QkpSi><@)x2WnO6YsbiLEB*@oS7`wxvU8i5XTu z1}&~yph{nzP|5Tn7eQ12WPtf&9T{#zHA$0|_=HhXlm!{N3Z_Ke6!Sc0eu@X-iWVnp z&u-Qp8m{d?R7pB2LG66KkA){OW(>&=P0wOL!vrSnJWf}GTRP8qNBzB4Ig$Snh1?~l zeQp6m1hu#D;Ani$1Aqf#3cQStV%>_3f{y+{= z5&h_^_Ilwf0EJWq`nnj8bes*xB= zTZYw*YJ}w6)XoViiR^v?!s>=~8Nnt{v5?p_mME|~i>-Zzk88E5bKpEXqp9Ce`}cY3 zv#|TPC&*;F#?eb&A%oe+{v=A9m|AqAQPcpe^!;Hz>oX?H1zEX8*t0w!G``+bq_8Xj zMg?~7rc@HCJFaXayb=^Mlz4&tAq7qjyI*em(+rG;PZ)NFF26+accco-t2UU+Kxxpl zNiNyl`MMNI&dEO4?^GW0a+lzbIlWBcA$1)p2ij`cJN`G6>{~5F3GgZv(R4?_WaKHaxWHfZR}qmK z-4G`6kn|x)fWdqRGu<^}sQ@qZb73bBULl4~c2Wr6m?1uz2dIaV=tzn%m!$Vf+elO$ zw4WFsMDtZ^c8`Uw$9kYle(q{Kd#ERD%k^>Lc|GGzv>U+Gx)E}5?g(a_)A{+;XTFu+ zFHcMc#O}CcoCkh;UC}Hgu6dNj2O~urQ1-AQUsHp8Ibm?d(6vfxb3uvH)AsBhTJo(>1mg(Q}0m+_Ew>VR5qG$S6xRDw7ttuOpn-UKNl>aPi+XK77 zLZUi)EPu0OIyB@@LLiZri&~7gYH&Z6n#@+yf}d%1F{lTxiDnDRHl5zwi2g%$zKtA) z2$kup_ib3_bAdu3mCa9{T6&SB^WgSEZ~=$oaFs|iYAFQMkK4v6fxa`bKn3KG{Zz#I zwUG_jNXPd82tA{zbmBNV50Z-5N|L*9W3Xv&U!*LZ?EI8{ zyhM#4j{6-f2YEuM*;U84QlK(bKAXqo9DH>I)APoY)9=V%K_L_DTZBOv2-@yaKTtoW z8aX``V+s8}26W3rl55{7(bv!eJ9mbgP)xG*(}f?EqxJW3d4@A5u$u9U(@0pkwrUgO zu;z@*f;^J#pYcC9#1KCI&7XXL?|%wE=6}QQ?|jZQ3k_BH^_{)22&>PREeu>*N=gn6 z<3dvVcm8S2neO%{epvADU%cXMH0ZB(Hd$xbtPIyj$J@PH+X+K?O1TCR+%1+-r;zzY zRe;ydOi`IcqG8OF9?296p{G{Z?db)Qno*syks#;FXHy%rc67ojZ)78>h?G{R^QmA7 ztvWCOBNcC!YHRP<-@?+4vBi^0{Uv_fw@90m3o*suaic(Rlwi;M6-$#pZQS`9&+T~( z@JMBeS)U8dCf=a|WcOvsleHs@4-(U^piU zb0l+K03Zzn2sfQ7^YPUzSmCq~&>$@ZAEXH;x`R}20^r*+r2wwwam)qLL3)@wzrfV% z<$qN{fO8nS7?SkE=vh8MBGV;#c5Ys}M@-~-^6q`+b6gW@I+~tRiZerZ0cB9;;*hWk zn5DTN%B2j=pZM|qm5&c7JtFxfy`$J#tC}zVk;v#8?A)YcYf>Y>}3LF=XZNmMDvz}!m^U)~H z!JFw=2rWD@0258`E0?*9*x!h0eZa*BwcRAv;a+HpQnU9Yv01DA;vlg^+=>OsIXdoQ z55)r>(i@^hy>-I<_~M)_y4#sFpETX`!cN7;j)ixr;~@N#i3wefDJIeow`KM+8qByU zXX5+qET{n-DXpe@AR~UIBUXUhNfvL~1tx-0WX5ovLT#6$r`8M}kJB7uxEZRv-1bXh zj9~-^wBDutFa5yOxk-7+@fdnxMZW0NtyzzLLt9TcKQUj97|7liE82C#EpA-WC`A@h z>xZj_Ntng^Dp}sG^a2@}=4y8TN-P@YqqhzI(}euLA)u`P1n?gP6=R^#>~Ef4I6)Lx zeX;1_e;FV=!lwaN=KlW-P@bc4?Dj7Kt@$IMVxIyErvNIODkFXC??qzD53${a2yubG;`?3eat=x0&!-moR_ zz%4YGcBCnuR0J;Z1J;$sBqbYF0-YAhuXGO940w((t~K)+a7#Y%BGW{!o3ObWYE4kF z;upg9<4I9#A=n;|2~NWAXalo**XB2{n}C?x9QJz2)$h~vTJH;8pgrgPm{8?7NU+SG zT`AsHbwxP4{Az@|*seP6E_i;eNnEb`Z_W@i(0REW(84G~5a85eHPTUriG z4gJ+f0=^v5touJHpKSj`Z{&~pm40;qLeC7k7yugck#BXGbe{C<1>O5~#ajwOt8O@W z`hEMadKh14B;!3WsSwPC{BqIR~t6#SBJzJuNSMBRoww5q>}FNvCfZ1h20U(K?hrw$@l^LF^M z@NAeWvJd^LRc=TkIE=BLM=p*CYN2Jc+pW=TS zxbDFrwA-ZGz(bmjKQmh|bE){WzxD%NG`pcyF!YfmA{1^&-%6oDHV1QV zmt(TF)hWdb61}7h3X(A!f^0F7!Wx1xRycZ@p8s9Wbm`uOmVn2=%b2)&^3KGz-i~}b zWT+u>HgjSX1E>Kd2Jl53G62n@{}yc7KbI-3EW~6a1fYe;j|~7cW0$IYW=a zBeRePOQ8w9_6tZ4K_u3+mRkmdILWV2$@z#mSadX(5Sqlrh8 z+6z7Zte23EeP4h1qs=L$R3B)j=m5anXk0{q5L(Hna76}H{@Ssm>tIpzK z-_Axw*f8goD%?$C48Wq4@yVSbb9g&QR`DpO4?$JQ#tK6h_GI?bBc9?W3Q%D>F!j#w zjziGvVk%tHFe_1p9w{(ewG7(RhmhJRq|k_Irr$ zbQk9A0dBUwKR!x21kINADd-$s>pjfu0;iB)lx;J<)w^Y%!+1>~QHsEZ%gei-{Kh;z zBQ)ln%s%!V^W5F~SH#>8-qq|4;HB$9!HF^kq=DMgkn&gHKT)p5W~=weCrvv4QaL_PWeJIKvZP750R1=IAc8e@02VEMr>mv)!lEp8ynf-Re0)KaW zfR8Y*(SK*%g-^{!=$j>3Vn1^{Vin*msAtep`N_~c*WW8lHdq(keuR5QWvbyaa4P+d z`L0kH`eYe{LLxtC=RoxlLBjG7FqH^LDFp1^;-h>G**)X+{p&0EAFP|mvf=|jvBvtB zSpVs9{nOj|kIv11He~*v{gwYHkNras)F9na_E10gs)vYEx1b296QKpPY!Tr0774I` z#fa6TK=m$hSY!18H8tboz*S`yQ?BwW%k%ZRb#p350JHDXvr50wYZLJ9tLy6T+cnQj zWY65}PNS)--}v`aT{d3cH(EL#&X_8A9Z*OL3p}9u5sP7K8u%qmr+C{4O>ZBtgHa-{ z8u99MuiIr7kSsJ5yd&u?66;0H#5Aj%1!uvKz8EEQ#$cjI_w4 zg3PTf+VV|S`c_t0g*ca!&qC&@cM{TDoD)Uz9Zz^PI4vELG``L0CA~E#>zbN5wn%Ff zM>gpG*pNXBl2e8#n4YaWXI(pHYIbRBUIl(#O)9+y+om zW~uz5m+aF@lP15IE8A~OKzh3Ytql$bW)bakmol_KeqK)y8lFayUyB4wD$pU6q&E%r zv4b=+2tG@|l)NpMe7HT#4-qaTj4KN!(Vf>25I3GO@KhpF8sG9>K7*7eG{)>oY70l5 zp?*J|@jVi1u0sDu-^0+h(wn%|I*~BC=##6|%=3`MdHR zvCJ#XOABVoPMt%gy7Z=pf63vla7;_I{oJrbsWf_Qn5HKgSvN;*M*!|xAiG9AU#HB+ z!6iE5sw3oXv9r6t-YgwAV+Ja?m%wk|)_k~zrotu+LvpdcuBT>&@Xl<=TFy_iM3?&& zi9E5;SkOu3LdG$hK3I7*LkombzzmaZqz(dm5X{ z2D6^xkT`5YP<4u=>p=4GrBp)8djwT$=!hMSzi+NFK=KP$EmLZcU!T!sLeYcRm5KEu zcAueY(PA+9ORFkMIWNdB$r%5X5WL&#Zv7PWa>~j|V{(~2?Zq+P^BD!i`L*!`TwQN9 zj>R2V^+=KM-CsK$JR00(1?J1f70do&3sPVUh~s0HO+3-p!y^f~YB4=j$VPjc%?PHf z(^uy@-IYG_w9aWUS`e!!;m7pwRfgh`Nm4Jd5o)2>oQ4v z2_vV{4=0dRffu-Gt$M;{fU%tV3Qp$O@T8heZNH`^uxNYk_PHPuc5z$hb?GFYVoNqN z3aWvNi#?o^&0`&Kgcdcp8tY1&3nEY-oERLqu3QuAUNw-e!v1Y1$uBrj!!~SiNQRtM zF|i>Twm1sXSu$_O)w|{HPCZKdi)W zF$7*JLn0+mA8OiG7LzsT@O|O8h@jy1l#e2KXBJOxiQ1J;UDw7}(NOVw2J#d<1^Nmu zO?cU7f<1G%=8=(ATB^Sa=0Ke+3UCDlqT-C7gr(GsAup)cS5P=;bm^rv_1$SetBlAq z_j;q5(pdUiWA?Ug4iqhK6bxCNEdG=G6;FP570gus8AS}A!_$80Y z^e;E+Ud7ukCZdoXa#v=r0T%l{k}@{#0sU%AbuDqYqO4o`iEnTn3YTu(w`oUcD)V9_ z>c}>o_*Y15=wTPiK6kE^ru{M8$uW(W#X&WW)W}W*UfuX8uS=ox?wGHSR0$N1sj3|5 zOW|5O)A<>~(Y|M>`;cvxp;xl6+FczGc0W|V9U1>X-1jPRR!+GK=2#X#9A5S6dv6wS zuS-##WNkWVlHjG>W0kgMj$Qc?5eIjW!pIV*YS?!FAwnr%lt#(Eq+67)L^*HPfQv1i z^K(AzZUfFTSzKN`?@ETMGBD5K+I&y#UU!ACSjkx7y(y*X+b)%wuwoi%Wpd66VNEtr|x_k>-80sC2 zdK!pMs#(5-ktDb#zy&#;IdY$pIa5xNJ3#;%!sx&rS;UQV`M}R++#t8R9K2R84}oTz z(L(HjYi#P9p|!r0!ZS8iVZyj_A?=0bGH+D%?YphUXx0+aQX>h@=&zf+(1bx2 zad9XK?yUlY+2514bdon$BS-H2hvv&@nEq7?!!y0PJw?J!H8HlK9ziOXSw%}@OTg`N zKjdB^)h-u&Lhijme-@XjDQV0{?HUHLsUe52sQ!qj%_il&=4`INzO%T-;8T@j(k`5I zy&yG^En|YQTt$Ympneznd0YSsp)42LsU7oSC!R^lmm6fK849koUoZyTDEy_tHehd% zO~>YKNrijfmQR~fZ3XP4x-}DF`Q?!`dvdSOH~pYM2B<}#vwV~ZXW@IB>TPSYbK}jM zeSD`0a08R;~9NJKx%Gt%CO; zH;u^TTOA5IDnoUqtBh%s}U~dkV{nvAY#AI5Go^ zQC}e*0}$}K!Fn1G)o5fbxj#h^RT&*Vha}Oziwzzy61yk^@d5|%?0g`0ymT{>{%sGj zkkOgD{Oe|&$FE%`IRY83{ob9|@`HSJnZJITd2~R4834^WIg}F|cm)xuGuCvnU0~di zY@y!0BOz+G0TA_4X{yUlaPY*bfd@FQK*WrzkXk99oay6ojnaFL_Tr$khx5>0nzPn^ zkwr@Ku5XT&lYr|waKotNsF<);VK`vN8!Qn=(AZUa?X7zt_sL$afh;XX1xi#%`z(P z%K3}avI0y^77E^lO>U!P?qS5>&2lB(CRZ>C5qlJ5*n>5FqoaM#4y~s?%)`4L3lRRm z0MFL+FWJZ5z85ZwQTmlEUO84jc=1M#b+7N0dwcxqno(+egHRDYBBug;RKz=;DoQBZ zZaHSdMchb{dosHo(@c)o-)INy6LY4+$H*=Re~;J`_b~U!2z}N`TOM{Td+(TJ8 zEE%Zk+}SpZ9YM7g#?MSu!CSe4S)qml0ZJXTbb)Eu_$se+tPQ6Z-2Qx@6{0sMbh1GFl#82!E@|04& z%i*~A*`(b7r#X+TQW*G>Zi^A~9Z^O9QMOSlV4)ioXb)5~G7lmSERIm1AZR=4hrU9S zBxm0R>a}NVWd74}Dm+nYLh#gLd#fQA2^nUOf3#49{fHq4UFB9F#s8=zS ztxMNdp{$TmJ#OIMHwKf2aNBy@>|Na~2qheTu?vz~IR$}H8^Na83|ISgFJ|$EAPxJ{ z+Lp&yiD~kzvq)w;VRKscRpKNgcat4v9=4iLiS`Qm2*-`D9YH^4F*tUZNXa4)a_pvi z*Rwvar?wOJ0#me5WOyE>cw+vZP~$lHZhtf+szuk)u+PPXN^Mwqyx3Ml8W5Hv@-i|M zZIg_%bhX#KB&w$h3--$wTHOEF?idqGfUS#|0l@n2v@1`=!VXy(#glcZHOewCm&Tv8PeXWG zng9vqCsg!wK9YG>()2Px{ffPKgSlhkSiYQl7yK*a*Jzu7WKV!daw_gQkNFx9N?K=O>0&_Mi%ZOGpgnGh2{PkfGeN zy`F=Cf_;$yvOv*m#TsD0R{ZZRzwQyCtWkQBRqO*`RrZUQ9bAKy_La2D3Ih~TCtU!o z>Vr|g>W9-*(kEf^6Uak>bBA$`s!%j-q%=D%>5BJ_U0rhl1%uzkRZ)Q-k$q=?dlBuT z8P9PRVD6;Ks(&vl4*Qf#7z;Xs2Z?+aE7_+^s5uUh%l@r`TXNJ43V8;Dq(_=lyd3fC zyw|bHcLvF|icMfLkp$*r*$JkKJgA~PR#$Hfn{)ulQ&hwIkAi|PSM)t8kfNQJrzS$dB*&^M7#Y??zTYL;sN>W&LhfdB*4?Dd9msgbia zaQ>GJ4n{Rk`e)N5a}hdUMY|gbI-Rn9b_=^p3>2s(m{L!J$(WO^j9(zaGUUs4%LP&F zF~+Ar9N#%3b_rl42L1lX_Pa?kOkg}IGH4DBcAqkXmF`>@I-xoNDm-vSemWq;*g)`2 zE?o;bHGCiqp%eHCI5hR^--$*jhr(D~{hpDpu09obW@|AL58*rBAjqVGqOEyKS4Al1 z8xid>KTC2~9dnJURe;F<;+}!goC;QBm^jNIZ4_&42ZgVT$S%eCb_+N86Nk|6h(iEm zHV_wKDJk11dhDB1p2_y};kU_U=}dWh1tD~g&=~FCEaWfv*#|(2X6P;Zs~w3iD|`5p zcF=?$SVC94fp@GrZ{;|@Lv^kOV5r77ECe0^_@V_tvjf??4!6h@G!+V?@0!N3u_t1s zgroEN+Hm10-T1a_M3bce91yKVOQ>Qw##{B((j}06GV~qL20=@Ri`;9PvecD zM)=p%MYJKIN&!+`ER8J)Q0wDv$H09KIC{V)9(+f8N4hx?7h_pcKpKe{!qiNNBjtc> zx=MScQ$rKi^K4nea!dKN31|3Z*f96-O=TU?!;vH-+ovbVL5Z##u(vv z_+cKeFJ0-^HbyjIM%T}vqhEZB2^(kfZSWuEL^HB{23=3t;C*AlRMvjrOlVa>S%haY zy4X%+q;{$e#cq84?LEn%%hnNu=mLV8&(IKD)SyUKMK2{5VL`&c{yT8h9NEIw93&xa zx!ZORlZLmPq~5>ZQh0}XirQ|H@JA&Ol2+&%{|iy+s7Qsy<_($cE8%@?zYC>T&LZ_a zG+s;KH}w@UTWT4oUEc})$7$Rsw!b$ag+d?%*?u-U;{MAmZvTZ6nxMIrorA5x-&)Rf zXSKll)$ptKR~g5zq#|GIUbF4rdVP9#!<623UsqROTXhN2V`EdaVjy+74tCKK(ekR9 zD(M*^^hpv(jt_|U^G;sK41kpB87m7^a!C^tav2$eOdo$sYMKQwFj|8hB%+ZNG#l)H zLB0AOJ_ABwps23{+6)Sc;hkT@Sm~_>bNW3d*c;@pb)Q2x2&16S5@6xy@gKKA3;gFr zLcxFAkgaTQVs1w)Y+-Hh@_%o;ijNwT==qM~KT%sWwYaRZ^8rr_s>y%z1&u9FAZu2* z?01U^jyZ8M>0HaPeu zE|iE8pYKCSvk(3yZMUnhybpB;18!vmvkw+D-^!KsyLAdzuMwTxX|2*~x@f9M4KdJa zOa+|M=u*0Ht{bV&nFZTbI&|q%jy34xxH3@Ih%tf=)8O5UF&J}BHQH`g-WGd-d(LOu zOI(Aw%%8p?C^VdFA?DAZ$@9kp^0&lgGxhOXE9C@|O`{=Z#gfzv7c-Y14AT6vLTVd% zp=W}J_EyGy!mEXwraVdtVg^wQesC7OQT@)Djmla~P!N*N9H$o2^TBlsoF?O>dE6v3E5z3E__!_Di3 zYh(R@!R5WW~`u#|st9IeejM3RHW z0<&jPB}82ppEbHMc@hAw%!meH=;;Q~)M?KJ>O!*MN#a75=)sst%Fz%D2b5Vxb@=7o zj>50zVG*sR1hu4fX+njF&FUtHxjqJ^b28V`;B`bi{Q{?wC);8TC~ox+y1`lnCgB+I>5WOpFCk&3r*1|Q7WonmgA`mZxB$mcdjB(& zUNkQNVL?24%I_}sqmWZZcnjX&*^6mj+!+^D5s$buUqs)$+pwBM9m6!#&lqEqW0iad z)|il!s2CBEDf<-e64D$Hr3d-VA_;hS(e!I1iSwl6*9o~%_9&Sk`IreY_$n;#fD)T{SCL`5yvz(!x6l}uNs7ti3Klz_vv4CkWhye>M1_H;8Rk4ZNmZyY{ zxs*LAx-)I{p zoUtn!go;(e3s|yTf<&7VRSZTCW#IS8#wP9UN<4o}<1*bJ4lzh)`V;T)p6)m>lMD9n zrZ|iqa>uFcxFGX#66^WR*kM(@uw?WD;Nf)D1l;GF3AYT0qjHJyW+UwFme9vFSZ3#j zc|?okvY*zx39a8;>Cz;{L?mW|`(3asmwjM$>-iFXXP;B#jc}*l;Avxr2+zf-Q1dfJ zT>e5`1`NY2IbVM1C*dC4?2uQxUeBC0p*tq9sc#dAS=kXMDnsu3fqBs-ukm}i5l!0e zHaoOw!S`W%4JktYZUck4$kf=z2JWm)Sz;V)Qxm8xE%1sz;9V6r_m-ja66i+}wm9iX zJYW;G|72>;j~^0e?p9$Y#s(*nK5Wegg3ZDHCfL(nrunqz2yN^{KA^XxzvD>VL!iIl z>0LW{ILrA`-CaT;AfgQ$eiR|itESdyc5pGD)+UP*28%3N^w!d$T*(x;`j-GK-hY-IVe`f5J$Lp^MU{AJ)lCMj284k)Q>1D4%FBxI@AyjIk z2*`FjE?Nnfdc{c``}RaLbv>^lq%coBb;j{xj~qS2uiuGrBQL~5Mzju`m9UxU6g%|Q z;t%k}9Sd@ZR4kTN(te_jWz%4xCwf740E}CjtoTZ}LU7O zW2b+(evp-B-jMX+x{A0tZ)Mrj*RwbkL+3K8s?_+UpBpi8@FW&ftkI7{R zmZ@pR@EVaFEH;O2On=~xIeEm~7|%48wa$XIPMSC-cKNGJxN|Fo6mdP1(C0=vn2^QT z#u7SX{@0m+-*h=>y$H(Qq04Pdi{drV7Yd*P?4f1hzywGTGTZ0Sho&~J>4{au2x(k;~pwbIjC1n-)X;T7nTJ%A)5p*kAHJb>C)6vFWu#|JsWP@ z6DYJLoK>`rPu~^756~FT!+r>FD)UK^;wIj>vJh$43%g2N=66Vucvh|GK+1+*mZx5oFr2oH#6 z)E61u;l2&Ec}p_O_++-}ZAQx0amgsuatlu1YdyFG$vxp>js1@nqp=UCUxP}m0$J!KnxZ>AlM*y! z!qDwtB4%`15HBh*sHwU)^*mVpcODz}D!XmfjQ@?YXemoKu;Y<-;KNgfQtuY}^69wvsLt zVm%aKUHI3!lDUzj!MX^;o$;>xExp$euYCPczRI2JC`j3`KFSP6dBs_sN)8Z^-w9Gp z#;5Jj>gt0aSxQRofs0RfDWOtD5!uMJ`B3&wPLaCfGiPTwp}O9=HT*i03F zyIA{`ZA$|9d}$_!pkMv6_6OatV)j0`ONAq=ZlmYpsXKXiFxZX*$Rd!<8cQStQm9+j zXpbb<^mE!vF(Nw9$vk)&XLaBS48$(UM9^|Z%;fu;h&e;# zm7QV0KJgkbsjVpj55;{m>bvx{eE5i)7~b^jX&v)HhkZ$AljGnrmaK=Er+u>=?s-uw zw*G|j*Pq4i)RXG{uk`v378S@m=A00yG*b>i^&kcfCou&frjJjFhVW}h+n=REkq2Ed zYE^#WD<5M5+ELo;{o_DCc2awh)l$1XQMy?ov7Y^1KHl?1f9u+ec5n5GQjx36$tofLoWTV;`tmy-%>b#Xj z^BMu18nA9F#`=0z#bYOm928>vp1bU0z&6?T)>femdeRbuBv=*`+ve0U?0i4{3bNMp*%H+Mb^yTEo>6NAdtCpfHS0`}? z%p#VxNawdC$1fypz+eT%3z<4Z^D3HUj!H{(3k(Sq{gDXY1f7~a#sGFr6-?why9IfT zMw>WYqZ-)<0W>AS5@oNF(WYIaUF@J{&=6?s7BBr)`RZ}JaLz45)}}wNRb72CR7lPA ztbyp5^-zhEMNmZD=AZ9TM}Zp;tyW^xenQ2>p4hi-5F`6R9mJ0E7gV=efPqxpJ;4d8 z4eN8;x;8;?q2vl-!WwktVY$~`qc(0t*EJW(z+MLXQ2c$n%vkIPdMHOSMZR+sL2)yI z`QUjo^+M5iQ1LVb;(ZeOTYbgB447w|JZDtYdkFn1(!P>RamC&S`zk%an2hl9W?64y zPXY|0ElL`h%{S=%#B$lon|KSJovmfC<&#%ov|*?ozx89&r4H+#v6f5B)Amh>(6&6P z&PGHfNo|?J&xG*8bI$UJ8CrbH0%=U-gm;*g(5W%iax2KakC0tgpTl%@RZk9Qenbih z)eGhN_sj@v>516$5<~B!pPH8*3NobUhVx&gLN9`w-3FO=VUub*{G3iTq7}a;LJ;xq zaw$O6$%Sa%xJ5RezNNbZsw}0a5$>7$>?5PqQ**J1)?Eayk8EtUckdr9 znqijM$8B!Fziu<6iVvOo_x4RZ$lu-O-~U^;`TGv@o9LSUODxAzL0uVB5$O{~6pb3N zfhafdo*tQU6ewhk57|t;M<}0sw&<5%GP?xK=x=&NW0J(jRUX}Jk27&?mGQX1ibC#} zooKnI)Cr>9L(XqH(A&DZw|n;86HoU?6r9nH$g!?U&AFXWxw%`Qu|v61y+rVkS>jpM zY})c^T4ig}g@MxAU1FF~3PK;$QB$L_T2Wc*frPGodIixv{XoZNkhwy81kpV(X;31$ z-TF+~5Ts@O7`o7X{)RxtmCYaMVNHXWU+n@)My{(i*g><@Ko>}@J@@ERTXW7Xp}v;1 zP^N`)qyRxT2A>TxDDu*1eUwU~0dXu6U27$lc5ks@QbS;RP>9AVRs~s5KKK;-0MztQ zaWSt_aC~H|?AYCgSFW#!?0)g9cPPx?ETUHk!Zb%^UDsQdXfFM}|}(8ia0% z=1n4Z{Bz+5V``7lX_^#jP3vneBiXj=yOq#!X8c2NL4gs@#8mOiFkkxfrVD34e+v0B zr?7*37RM;R8i&(x8G4Ivd@mnHqg6T&zOYg-5K<{OKmf1)wN1 zTaV1uySJH{w^-wt#WbLf%Ar)Hs_SDefXWAZKsJkpas~XGaMQ)QAgS;MD_5xF%T-N~ z3-Y(ze6Huf6CU@^kQX0JAh221LT0+E&oF`4AIk1EPUP>9dktAg?w~0IoT5Uwsw>V7`Nn6J>0L_DjY6uXr3!*kr6|_PD$0C6L6Q$DRT-+(+2_h{n;T@0z-tR2+wD5hwl5GJk0?i!A~~{d*{(lj|u~y zXW4xb7R=;H-d_;FFUIW%P;cNkeA?D}XK?e33F#|a=Kj)W%_L>mzh|t0yG51AKGVjw z@bJCj%|s0LIN;JVr4$0YZ4gm<1(e+;;ZG@yQ68L1;HTXcBq8$~ifL7Gz!$H3%Wy{% z=Ltl^4;X&|w&Nae1HSS61%NSR^7rxIR7b4ulIH(ty7(W<8975ILp%HbrIsm_{U^_3 zonTRpkbvMhk`6v>4L4^NFcchoRsia$(8@;CRFoX+onNaX#Y6@chwC{%qCQM4A>0<0 zqn_bva^3Uo_VpPEn`4DGhwdCycYYW9QVVPtdhMd;O75O>SLl||+Sz3!AMc#KIFF{U zip)C^Y5*$ z{3|*%T(UlE@96_Fk>9e{eM8_$#R zV;^1`q%)Mm7~K)%A?;!nmQe0$8Pj;qNi~%|dj34}ys+)ama90cR+);=-aoq@Z95@x zp^8)(D*CMNM`ZMEDEEBISfU4Rhs)WQWyJ*2u=BaGq#%ZAbr3la@=CMZlEqY+j$uij z;eVV?ev)G^%Y>5)2bCbzq7SxAf~d5-oEisxNS>OTrE&ePx{nCZY~#O$DDsR(9^*zo zYcL<_{s;T2cthRW^?T6R{kMb0e+v$GSsuHGF=7t6mruGg*|NQe`521>d z(wM?CmrZ9B*#& z)1Y07J1U|Ny}tOE zoU%4QQOVbc$D7^{Vq8fB!6oE=G;v<*^KKS+N*ao3u0?KouJPix=kL(VN6ddl7?($> zJDf(P`t>yU$rcEiGUxB`dkDZQNBAH#ZitKZ5!95@id|g$`bpCYM`WP;zNK1tXOL_3 z4vT7B~VRuQ6i^hu zYMFE>$k=2jPbvT5^(TlqOw&in?0Iy3z`^cSE9f9Ulafz^=rW4U6;nJF$P$*-As8~z zr4+eKP_Gp$)M+LXdhXzq*i-klc*-MZXU@b@UgIWL?^YXHFJ=uC_Ry10!ruDbCXLN( zuz(efaZA@lc+=x_fKw{koXO_v-g(es3B`~x9MrR!Wdeb*jfq;5mDxhpCc5ir zV~C-X%%bY>07S;9jv;{;;-V;iD9yL8a2M2Mf&pfP0&q?Rbr)%_fw%jKCfaSB1r11+ zB^R&CK=oOX5sos}zC1PV0lU3qLaIB9Kx0Z8zCfU^KE8sP0yGz%w+XKhPysJLMtg9A zSH$_+g}WvuRPq6n#_+C1-sx<<>1KX)qInTCWvqTPQV{e(nWzRS8}dE2lbH=RL8)o` zh(X9rjS|hX)wpd3A{ybi69(IR9;98PJOoKNsW(9V>YES>MfRvzbL>9`0a!|)(K($V zVy#=M*^x`dDJRYZ1}Z9ZD9r0NHiW|0=?lghFKkT8+`TcZS+1d^W|tw?x%zo$AN=d? zKMt-xka&bT$x3d#{ht595<8|+Vru;^h+n||5A(r)3KM@}#b3zrFQ8EPr=G|et1Tjw zrC)BqwPG5|up}nYf_ymy5;!<{f*5bBQdGNH6RVRU2mE#UZvcGToe^K$z?9l}$Wd}F zQ)8#c$*GQ1&9~|8>~5JJZWt&NfMH#SRoiM!Ya$LUR-9m7iM6M~WHK#hQduma%b8>@ zWRDnBE@VeTqTxZ9qeb{-Rp${BC4A}Ae}Ge@MX_5 zfg`fCUbO=xda;IbzNp<$R?~!g_P_&Au<+vLS6vO&MnE?JYgPPCpf->~mJZ?dHG*en z^kVpNaw{=EkEf|$_QxKQ6DsX&1+QJKoWhj1?byTr0eH2g9%(D1|4Bw0faUNSkTau~ zDK96Mn$3M%*E4fBI%z-M{@qqhfl0DJ*4Afqce_qLpKH1q~mBlN!-nYMXdmz>)yimzJY+w{+TS_EhS4DYN1Y5(U(!Db+(j)P}cev#wN` zah78hzuko{En@2?rqosg6zQ>l#v*|kO0@11O;&8co7mY2)jnDJzMkD)`(JVr2?G#zX$gLG@3u(l?1;m;`+vR+H0IcYuVpc0u+-I_f>5zg5oc{9Oa zk?2na!;i2+hDcK%8AzvayFuyQ{{ch-?x8sfmW$hrEO1&<1o2C@0g}Ro!s$kLSG482o-3X&{)iMEt!iEW+$t`$1Msikg%6|lV=T?@ruip^l)WPHzJ>lc}8 zN(e%wOQ=K*V#$$?IixSokwNck{ZxI^8=Xb{+NutYuqR^|%OLOrt$^(THkn2p$g{KS zq2kp#C`2;lEIE+xQb;bthMp3ZL^+G<8Vq~aiXwP)A8C}OysT7${J<6CY6N)AS1ZD* zZ=gdljAYlMXeh3YGaY4$AKC7gR>k6<#R7wr^l0U;Nzj!S!vNCY0UNudRY)Y|($lg) zvTBWvF*sP0D6lsH@=^DUsYXBGcT#N;gL=lpRbR3Thb&(*!Z_>KQ+C}9j93&^R`R0M zlNbBa?1Uw5c}7SY`AoJbR@*Y@T68$3<+cL7zxFQ=EIc%NLo znxJp@gEqVYi|L^D?l4UE9rNr-X7pn61hIGlSZC~F^9-{6K)o8X?ZDMtyIb1d?Nrh) zuH98#h@2T-da<5;P|Ock&JWLyvI2qSf+R%J^jV^w?z`4O&*okYWOoli8cgAK@u=N_{*)#i^nxr{XL~JH(29;dC?Vz|f@+O@>;pM%QE; zHi`MFyp7m;jOzzUri@Yc-g9vbQ^rw5`rU6iDgT`5MlN!ub^qgRw%60|_m-8Sh8xI; zJmc@EerY-+E`cwEZJJKLd{zV|wSk|^D)Ge5wJ22`l#4srg?J zsp{&Xu!#I=WfX@_0xQx-5DyLqN0b^UBU=s*MC%s?(~ChQU}hWVDhfivV2c9aRP8WN z?NpC!i7Y!uY+0KangX!`TxMx%-WXolxYT4;scB)(V(vEO`P3<4M3O}Eh2+)kyuIOm z={$X#X+P~Btlj!WW&svb2$KL-AwlGh(f6@irPY~BIlG)3Qfv}2cwgm^u&qu%sz88# z8F7+p;!%tPE+}sbdJcfh(bwJwU2D@(tSf&6gW#Map%aubS&&}~!aqk&t3D-&2yN*` zj}awUtm$;6l z=Enk~b1sHG_BB{V8bnmki^^}=kRf?Dddn$@jI#7JH~9_C%wWASfJ{$wrA>pAL(^P^Jr81-wsx=kc^O$2R9P?uD%Pp%6cN77#^dJr_ ztmkS#%)#+8X_rFw90es+f{Y&d#kDR|*yH$<_V}PNZRpsD($uz>v$qH}9g#uxI)lV* zQ+w`lHuH|y#}*wcwiDRk4Pb=`&h+ShI%`TzHLK7jY#y{=ongCVs;1r&F*fKjxDuo- z#qT;0jB=Jw_d=AtkPNl*@pClEVTYWx&%bcXM^FtbuI%+N`#>|@Lc$}pls6pN(KRi)ra)lrqACoV{ydWLGU zXU~bRwrmhxSrD_IgyFDiHTl(?GTH!Y88twDW&=@8cGMN=^+ zL22iNkDTvK!lMg{m!%&PWjtr9;vQSc3Bt4?1pV^N7_T#MlD07hSv`h5KuP0cNTp_h zkJNKWlJ#lNd`|HhuTYz8gz@lzP{zyt(>J-2uZwF{=suJ4w!+n7750QDFR+7h$^d1M z3f8qArj$YQ3pi?59Ez%&hu8{R`JZ#G#P#%Lja#|+EWFBQo z(YHPfINv5L-c6<-&fQSUm>xdLA(o;@^H(QPnea-}v~0nAsN<-C3#@RPmpUEA(jsyy zHA&g7_;VfaCQ2B4tKm`$1UYGXitdxiNSz6AILYfPqAkJQA=igO)MdXeXp{^?QnPeF zSQlSZ)EQteD>}l}*i-ONZK_NS*048hRuY?`6*ajlBOFGN@6d^9_@x(*sGVQrn2xv& zM|Lv~`Dm~es7V9^%yJ1%ibIl7KDu2hK`QK59j(Lr$aoVd7W%H~i(EXp$qX0^x%X6B zAXSGq7Ulx6Jx{x7QsUL)!-K?1$JX;zkK+JII;fA~)hD`}lduPwa^zL9YkatIu&{l% zAQd|Kx^mr7-F}NyKBUDZq z*14O3Hs1e%YMa7XPRMX?e|kqNCl1w{R0chAz7RJuV7{$3We?a4^>g6D&)g!hdWgsD z8B(2vAxWDBk0$mqgrG!3|8!eLDZ2pbG zR1A-6Ll`7ZZD}*nP6k3Zi5z#spwc8S;8#i5@#d}s)h4%-pZH3kO^94uEGf4zA^59< zqu8Y1JCkYkzC%u@A%+&p0iuS#Tp#h7C##-X1KxI?4(Bpna0%_zU2WN7nuzrdO+1!= z*-DO>;S4fLm-qxqA`D${3)?Pv8mm7IIjFhd(sfd6T1r&q`{CiM`W4)rr1aPtVK|=r zII)?GG)f~e{U~+Y^fQhl>i&-1mV~7=Ee>f}Ej&B2$I;5g8RM0S89MY2s=Vt}8NLkr z9w}@{&(@!ebH>b(PSl)sL{jrD83iZdQCW)jZ4 z6r*RNbqPa1VMVFC0MnMU2jd=j@7=5fTQfQ!k0NwThryB@q57{{VJYiat4|y6X}4)| zK*fz}*~1;bsYEF(;o?@l{7`)-4+ijN&>0EcSU=^8W-lGr0lk)vaSGv>F2!=03SuIM z61xaj1fYS%Ecx%Q%IzOI;1}Gq(?Nr&WWUP;9$s8zLi|yS&zPPlKdIZ%5)F zM{Buqc@>@u=r0)0;jYOowP-h6=h+EF*3TKMl*%lSD*aW?Ilxg@v3Y#axpC@Sl05Wr zZ=DqMOMK> zIk;H%yX@nOA4;;(6DLKG3KwnDUm6K+VR~%&S9D$RCXDra4)emhVUib3SRqF~@>j6|}QP9Dz_=GS1v|{(EOq&W#zq(?!P|{NrtC%n!-|H``=g~W9RXjo0 zLvt4(KjVfr6oxk3+)s%7Lm|H1R9yz_2~zeDj?_LqU0Nq@Urv=cR~C(uun50FWxtC^ zqPH*>NU4|yYTw_MabC*Uce=;tjCl}}cy%Z-3&&$X?75J43*ab_Sa2%@VwQ;ZQ$AB# z4R}wEcwGW`4`vEh(V9Fy1W#c=q}@#WchMUBISqd3tq+ya&(FQ3b9W~5%OT#tI+0l0 zs5bAB)a=6bSeGZ)=1qsw3#D7Tid4nIb8*BA$mcw@t^m9AS=M?~o*(LDG{{HKW~>Jz zBTeA9m*m^{kPk6@o24?%Z&CD@nLzP_ovKiG)o<55wpiH{yu#3P?H-(A%x61HD&;Us ziQ$tOU@v7|V(7D3;@5?z!CzK@a$QSP zMGX}tx|1+HC#9{B2N~)8&r@{M+!EDvYK3w%v-?N~`jfOcbT#Mi*-#MW@$9gV>nPU4 zoh}Prle(N^*5NOfH(+HP9o*hJXgp>OZ&JVST1O?LVdcIA)5e_V)bH-r5!vdcU0z-w z9+QBhAFOu5-vCWpqLFdjFv}NenEyiNYdKe|rWouqL zDZDvxPk>3DtJFKTLHyW@xo8|)`}|tt{4C2E8;vZi1zfl&ky%dzmAyP_?qsIhuJ^tt z{=zRj70QpI{K*0yG4+I{^RsZ%`Z{9HDr?OB@z7o&*-PEeX+G$PG{FsD`1DDM->J%M z=O@8Z)+UF1`ANNgSCsveJKE~4#4O^1_h{57TF8Y?_0O+>v?EuDto55^X&?_ zJ^LNk>5J0Z8Ch$n+jN-{K~zVfwYR7A$uLl|$WBRuA%DoSOhPDkbmc`ls;i`Dz=4k6 zH*uDg!bq&8@m3v_HF(F!)lxzum7EW3ETLaQgwC3&UYCSUM&Yg)f+5eSJCy2~C$9pH z&9JrN2?kP{jxo!9frG$|J!sIc-(|{&3?A~JUWqENHtoDT2rj($qX^D;j`jCGLdZWI zW`cLK4SzxX_(6;FcjH3l|35v6yrbS^iRzTAgqGOb(E04Gv> za>15ll`*A(hIo@QOXDT}B@-}NuLjLK0K>3)ESWxzyabo7!wJ-{#1_B8K*Vx!`L)r0OoBVzzcE@|%M5+FKR{oZVX z#4TEgnR!HPGK_}!vwk_6D3EVy#TBbar*=!C-X*K!h3CP*oQ~F%+98k6(E>@_v^Hqg z#91pkzUQ>Q2SboGSGpCRu=!;`uZ-=q3%=wLM_+I?ZgP_#5RN@zMZYvP6b7)HQC1m3 zOD*;ec4SaIIpxA(7#!f_q}OBtd*!duk;XP}8$<*|gbTcTK1DvtKAnZSdO@h06TkRq ztFK}pw=pnUvbDKzI48AmjqX7AXj&$o0TyK0ArSp*d)l$JbRH1OJxQbRd_Shy(gjP} zk2~5Q%F}m>lcLM2Xi=B&+FeJlcoC@4-eEWZO02_Axs+V}7_NeaUUV!J>`4BcM!aLn znxy$UwLfl|s3Rp!+ISli;pO_~R5BF6{UK=pzhgkvU44)1S*4zTIj`b{Iy(^;q5@nZ zrV^I)+831+*o;(9cn>jSk9lVPkxiYYH&2O~p+1_JThWOn%?)*YN+jc8hAT5_har?3 z1i3ja2qjVmmy%MqeEy#7=$g|p%O1~&&D&T0{Zu@(dbOv+7KB+9BFT#fyX35m(5-lI zD;yFaQ6IL#fJi^hjs81&ht~AqBXw0f2Ar3YOPP}*3YFhzeZm3Ct;hwL8amTbX9Q`w zP)l02x*jhl3)0t?ua15qFRGEIOX=el1yk#G^)RPdq2|=`?F{gEYyJ2F@5*BxtW9cx0v ztcx=Zl1f5!5v+-9MrpZgr3i0*)AK?BtM7;ToJCVs6|eyEK@KUfrY(@Ug1!Rt&-M3(iXB)J#cG3%C(4R{K!XKW13vqL3$KB z*&B#v4G-2k344Z4BDWu$6={Pmq(5tupLL>~u!9`|YhZSUX^$>M-}5@4?EJx2P5Bqj z5Jx%Z{rx8`cUusF7P5Pgt=ca){>O3qBmDY03Sr%dbBCDW>2R(vEYAfjJJ3)bQUXuH z))L96Ux8Ek6Se~5svSr$kZJDK`9(MM0_I1Rl{p1R7U!~RUdRQz>5wp(uhTKC9_E$6 zo=+*tz@n@#_M-c==CckMz{<2W`au5qO%%uRY=3}mQOVs+KK&_}u#os!$NK4TqTZzQ ze6T>o+*kX+R9hHNX}HE=lTUVoXLUlZy@Kxb(B}=KKXu;+d<`IXkUhy9vdA*=on(5brVcnh0$Q&Acg0OUN2)fQf5s@@aTgjhwTE=Qp8{R+LxQKS$`ew&@W zOY9T9-_rcG3ZbY+fMxQ%2bTS9CHeoo3c>wf=Q069BV9)ehi}=fZ>JWb@8AE6Wc96G zj>wC|)%=U9p-~3^;U6hXkqsUtM_Xh6CY#2e{t1eB5Y*r_vX*r8) z1Tk6yWJ;i`_JOo=kQ^6HxU|lBYt`6<=TbH$S(Trfh}E!*YF=DKGJ&*MOqsMi!f2Z= zCxVjbY|P5bNV{zt#$I!@&0wW<+Q|X6W&5KKQs(L)(t}Nuju8Z05Pjs>q%o5^V8!U? zgA?HW=iBPRLGXjD)%yt4_N9GIhG?j?)=-B5s-pT3s7xC8NFchWtU>!_A>YF1@DtiN zNuJe58)@3kPFU(>ulb(pO^SK_KBGyM>{*DL;ghaOLyT2ttl{=$AL!WV$71eDw!RiG z?&osgMQR!HtCD zhUUrP9V1W2^R6Q6lD$wEdcD!;#0kc|!`#s1N@4AcI1@)%$Y8y|u^KH_MPLWJ$z|L~ z?%fc1AFzIFxjn$NMziv}VCRdhZuV2v#Py*?v|j&=$GWYKd5Jig1XR(kAnERP&o(RI!cnqLahYcs55F) zX(}1lz_BwUQxiQ@1!iJ#XH?#)jQ)erf*tK#llL0!nbJpr!1E94VCM#rz0vo+N6p`A zng1IOZU2vm{%2*DsATSpsf@g-jN$r@7Q9xwK_Q#PTFF><#td9MP-}WhQW>%*m%+~Z zGb5CrS^qc`Bl1e>P zxnaq~=#uMc!~SvWXyax0>+@C_h|Y)S42sKIdwV?wQUwYOM0t0*%HB{1{sdDjfs(rrsk=2>CPQPz%r zm6shy$t2b3HY!n3Ml^8d-ovY?1g^oz2&u1j;S@S}fB4v(ibp@ZT4D-^W-_}0Qn(^s zb=}98I&h1mJnlySLgyWXeP(N@I1C5S!*7kn)*+=Qx1wyzs~NO12x0C=r9vqifT$P$w0Z z$Q!w$fP`qsNZixc^Di0thIWF0`o{{#C7rl+sDpoQkokcGhT|cgs`F=yEB3G)DL6^4 zeDK(~LW-fVeut$D%bihrx0H48gJcb%BCmX_*Uzx z6-mW}NZj=8_9D1w7IjTWJ=Jjo;QLQwg7|-5XxMG~5C1 zAd~4TfD31$YuU_GHkfsW?g(2(S|g{bZY75rRBF87Aibz0Eae$^a(oXdtb;+kf1&b} zU#!+w!%&z?ZKxwwS38b|epe7HK45d7{pGLu9O~PAZJ+g{5NkSoqBNqxySb=oSSfMg z6v2F0u%mPzVb)w}uY#~L#WgE&HnpklgwT#r@_MspU5-#y!w64Mosp1T3s~GEuD*WD zLf>_~A?it`=z%U-Xx5pdYRAuIyMH4!)|sGD?W94I>aiA@$0KnpX?|6ZDS> zkjs(ipDm6J_k=r(+xP9B=Ey4IoOEzY@J(fW9=hXOC^?6so6i)s2RgR~#N}B;Pta(A z$pM5*4mvZh2+2^)70yOO^mWQ(ePzUcm4u+$U$f4+pyM+Q<-KV~tP<0AWGpZ@T^y`& zB|E%HishtL3TieeT)>d5YH-Ke})1FdzhJ@|dvH;`ezzut-0Ao?L(OB+zaP zd+(9FiuBUOFC%o>!FPss^U@`nZD~X295x(=8iyX0COh+%cbbXIE?T%WF*c``u3w7} z)~^bE4jAo2ugDjfQtvwePm@#W?-EWwPe61q!CnQFXA&b-zX~xmB7^6f=rv90+bl2@ zV^QZbv8oACR0wYKPblMP8++WC<}1ET#@x|6xol)X?_A+vEWXr`fT)}O%(w%`C5%Vt z!3n!1aeC|9I0TQULa{EN@P4bv?9TVgs!m@-x+j<{P@4u89qT82}=<*{$dSjRV^;L6i z2-w&x#e*p1!y1tFHO`5$LbK~(+bcTWo7k*sTr&Q=6l5z5_8Q;$J@akJq#>f5iL?2& z(w4(M_5?@jt5;!S#xmq~S$>kqho|k!+io>}e&o;*+V|@p@39l3amSzE^g}?J;k#e>1SM2=q)` z0Rv9QGtD_{4JwS2knR1>@!-^RKGwD*3TzDR=p{Gq)!ikv_ovs_Pw3_u#@c}z9*idq zuYq>YT_<7xUK6yLC84jWOaz%VeA~yQQ7YrCK?BXlABy4gRAW4?$WkG?zJ+yCi0H z{#-$w2@of>FGu+%8_3a|*?!~p$t^U$R&udT?lDyIa4lhS=uo3o`%W5;&1X-s=?j3O zG9l5{25NcwW=N-K(28$fNh6ZD22X*4dT2fb^!Uf^yt?Qz6$=_4V=y$Q!ZW8uo*K$*GCKBl!$DcJ{(-u}Pz@h}>a1 z=8U*qiFq)no*1jPamaaJ6&a#`24;IdHO)9Bb+GP?P2)+dPyhIuA_y~^Xe&>84~yT} zbo-W~kHI0RW*0ozy{R8gk|?~=A+RX>T5M|z0g6koAK|RgOqG>}&9>~=EWer@8sEXe zFISx(_q8-xwV%F&El8}-n&HNxYDeAYj}Z`tTdDJA6Q`95^+|?FgO!~*N4@M;?vBQ7 zW7s$p;4evoA;WR|N2UQr^%XI$Xn!}tj$Jrm0q*s=szJ7fIQ>y zLV%%NCm0-NRde5pi{=yIvLj}0Jcr=OSDA!SDT72GpfZb7V<_lNfX5M}w*FL6YQ&{b z03EN=T>Y%0_#<5ypgUrY&u87=Fg)Vq9sEd9Siqfsga(LvHo^_1R}xBzpd50}_ez=v z3I+^2UmQ{u={X42-v*U`;20#oAtMEsEvq+1b3c@@11`5OJc9Kb+RG;oi#fIUlP)=J zqTDM*SZ(5J_7^YRnnwv1$TY%COBy)H=om^rf>S^$0}%A3-oOTFPH3ud4te@Olpv}&{Ru2z2bFebhz66lD$ zXqU%MpCz?Vri&RQme%uHz2|^c7Wr#mN7FNRvM!+Od ztY5edN#ZCwOx!0%hHxj9svtauYcygUSYBtVl_=<>sUhTFLsXz3y0mX%&fWI;HF>{x zB4MK5q})%TgvAIheYk7*pbaFeqlG{+NV)#>DyZLaL5OPJBIcsTiW_dDps&iJL8Vg* z(dUTDVjC`#9Kph#_?}xaHhpwDSchl@XBKQ*R_KNuKqYfWaG&c5=C>YAQ0V@yi;&3L zBE3SHfv72^0^(x1lC{EKlRq)t2DGjh=`5MB0$6szK&9NZJBIp4ANtHAF<3z}p09f6Kz1A?e{(uXM!)KV~W&x>YbEb8>(X^r&F8(Og zbGJn#^Qj=4fgy-((Zf3mq@We%?Ss}f6=o{0T8A#0uh)@%;<~A|>gwxIp3>TFg&N6mBRZ zh`koRK%GsoX+DcLA4U zo!tR8QWg^}2ELAe6-YJ-Vj3BH@d|UHNRsgqaY=aZZGq=b=aUjmiKrZKuJK5^_ZAWW zTSppF9pNzu*Ix#ezv~!;xB-Ss$W};{pnWV#HbzIEA3Sow5AFR8vCk8TUn!K_cXn`x zxhQw;4x%!Chp>tM*QNkw$=NzS6;!pFeK2&6VL3yY(J3!L&nc<_9;-xFAx8Lho2i5o z#&y~zFg*VBZC$L%4B=Trcpa7gAtuLZw z=^>sa+$&b!Dy-5r{ShDn<}19UabJTP>0?Q#QfhHop1`d^Q^QXl!4B@Oa?$H=G;2GL z114j-(fRb-nOc;Z%MeSh%j}ukl4$v8u!M0ClR&*j`VHvyJ`_b2KozOr&3wZqQJF(w zRxyhv@+S;cyR}r?&O_RsypGdhfxO*uTt6zLI+p_dF_gf9QxP9uE5pMQG@WGz_|O9s zK`~vVO4|BZ*li8w_1(fsC`)G9Gqe#i$;LoiG&s|I<%z(i zd(W6$y$`9m3s0c($Qx}oS)eqfk;MI(muBmbn3l9C9Kh0=)G!JA`p5GAbF%+k>Njp? z{kPYp|MT?!Nf7y#R1M8wE&xY*<%MNqEEPk5vjN+a6Tl>wEJP7JwbhTtP>#~9Tn76@ z7QrKeu@Tr4#y85$aI;^U>$-WJO!s8?e7icL`C}X5k6;(zRbbtAD%Hwx**5Ee6IiPQ zS7Yvh*&QBd+Jm~LKe^S~X3j;E`O3v@b37#kO47g>H;u4Hs@qIh&tB zf4?2UeU?0(&YM19NY~w=oV&~_r!W0-@LowFKIVpGV3cmQOU-x%$`LufW?|zt6B(gV*;XZ$Q@{LaiZ!GFiZD8C9{MHIX8>I&Sj9 zn;XKV!8F~Z$T$XCJM4{hoabm&{~0Vp#DS+!md(@jx&ocsI`lkc;9&G)fZ|^wrH@Y8 zN64zWE`FSi_jCRI*!Dp5&%=i?uO+aC1rn`Uc?p`NQK?A7I!ba7H_OF?t=VMj`t&FG z*!u7lIy&aSaf%}HxMeb2vg}W)TWp9y()JkBCEawcO-8U^(Jq<+_-FTPXtM;G@_qQJ z|LuqWFI&aTxNR#0UZkP!pKHJxVS{pwl}cx7sx?%|mokX*`g{eC0RFS>x~U14Nt;Ga zCUV(B9M&B(0^zd*px3z(#yYbC?)=X64E4rdN9lLQUf)*TfTHI)x_G@cm}C6Gxc1I? zSS(mD{djq+-@u&7HqH(4gJ6#n-b@aAlU8N}lHgR;R81%wGANS`G3&%PVt$w>$+!ERIzQ_wr!(g+qU1>sU#KKtk||~yh+7Y#mUb1&Dm@B z+}%C*>eao@#>x1NlY9K1>$!C)nXqAEJ1-YlHa8s6p=7j-*ZS&_eq=O64c6{F2aQYd zwUJ-s6`ubY>^nNyN)$wXkmD?6{7vcD*7NBwoUAsk{80hBD$ki%?eS?Z9JbrdtcFJw zyb29M^x%UpMl2k|oAf0H+&963J(nODURGqgg7&Ry7Qevrm}g>nU-gOQ##rZxlPJ}- z#@H^@Y_f>W5l}&3^y%-zq$C=oM_3RshGjPuKPe#j;|tzgig?%VQ~~Cu9~ut(R~%cLa~QXDku8HY>5#2rnG@OGryp3 zJ}Y00j^E!YnapQPdB)EJDfizhx&O*d`JY~qSt`ADe_3EB6}qBuHG~wSQYx+mtf|^Y zD(@H!kU@r{B1fqI@Y<-D1=#}500HSk`4=$KQL;^{_N%2+7xioNmO}p22VdwbQD6&eHlH3 zG0}G=&F}}!&=XPADouV^ItTJE#n1LHiofI^il6OM@k{)N;y3@lQT!6OSHGU8gDDvq zAd_}~xOV!@V%k3}3}V|MWus0F6K5`IF1cdBXjTR}3=i^cP%Mz`#mJNCQ&!y6w|do` zg|vsPIc8dw>46i$EObEg)qWFlcu^{JiDQt>NB)Lz=pn6(>(s~GW8ME}U?~vKlz)kA z1>O2}Q8a=tckMlT|Au4ZG2EvTNN&GRguWsiN>RJDCGZjo{@i+v*1YbmUpu>H?0%~P zu+f}-S6Z$&(Gl!Y>kGEo>~n*lWirJVZheFKOYxJsLa+X%`1${TkCT6TQf8^hsmv>) z^2I^SrF>DQf?i;#Txk#%qVh}5*K{dnfrQEA{^bp4Z;{4on3$~OA4%hGqjMA;bQCRv z@s8{t>ZP9)M6#Lel9=(}G}Zc$?f!E6uzVSAfUTf<$2h@t;g)^rR6u_Nn780;l9>G! z0?fGa9kg7ct-G*;(y-y%Yd;Qx4kc>rfAHu!&QSMjJ$Rz$c)ekY%A2mq(DO?9t0V2?5}GmW z6Fu9gM1P&H-5S0KGs=pEqc=~t-a3)8()NM_6bdY;t0AH^I_3iR!_s$T7n6)cA@qCf zlpQi}Q zH8XjG{XWFb2!&8T5dGy&cI3LGR9H_*TJn9CTfV~ad599;FZd60g^7US5#pgh zLwvuJu*e3aSVWZcz*qVX1f;z*NF=Gd8H8{t(Tgvs>+v+h@mL@uiR5IzVX9Mwk0vpI z;wN|uBmAgElaqo7t>C-VsP~do?jgASYy63c?7ksf5Xet~dPSlY?XdPAuhNZVM?TyS zim#9%X=2C-8wo8DwMltrL@B>or|%MZ2AsYqjHp0^e>+MMME5!A-CL@U{*j^_A4BQ? zx02(G-omW-i<|#;4D-Lj&3{^a{wp`(p;QexM4C^@htJB2tkeS5e=$)cwUx zoWGRZ|Aw2myPtl>z=S!B&s52~sGAR4Ryn63j@TSW-o1XQ3+`wFd|^s24wE$=Pbs1v z23-4dfqfymxMg4d&k(88@GFmhaFc?-h$VsiZWUpH#u9Mz$<6a~1o}aq*$7deS*#d_ zpP|4X+0dk)+#GWHtihQe{t~$(&X*ROgr?$#jGltzxuRcpi3$>m4SEj`N zAKYAUA#b2tuP}t8flm*i_?w%3oUGGO|G~|Vi9v2VjlebC#d?<1cPLp*634)306SH*i1wU%2^ZvpFRHFWe*^b!7eT;pRWhM6(hv z?LVs?!`%|A(3(R4S^EXOFn^%!y0>mTtgUFJSf09A#cMIllya@TTn0I6-hdu z0_U9Csd;bhX~bJCh48F*Z`>pvo)n<(Q}+E)Y|DOYz!{C_`9(+C-*MKSphdE|6x|00 zaCuos^(E2`Biffna>5FMr6H@he`qnYq2O=DxdRia-hbZRcbGu~ex;DZTZQ?3KhuMI zFmIsASR2B-e=~Bg`xKI=pU#HmTr!*4`bC`r6f`PX<9An4M?>NwYi+bJghpNd9(FKa z0r}!Al+UQHKz{ZQa?`sOe~U}^xREl$P9_IDF@TJUokC{$?GojOB5V+f;SM^xWH?W3 zIC1@yVoobQTt%6vJ+|gB9$@m8_-VUPM;5>}jKYh%TwuIIFFj_bOB)?~LI-8hV%{Sj zN+c6850206QZn%!@T_k-(hzKT6n}9($E)$v*_8MqS7)CFeNE z8Li_PQuVj&BUvE#(EITz`{qgn*;l0vym_~VgX`vgvpPM&{dJu0R$aC+|F_7#e|n^T z9_RM|D*FgR8~(!AH4-Tay^vrbYl4MZ#GYBFl@6C%gC5DF2B8v~V*m-V05p@evtTDz z``pyZ%faNt`sTKO*M}h1%Zi&KF>mC(rNl%?W@&76$vmg@3Lr0$y!O3<6EDoF(6{J^ zKc!jK;oq6we)^9ioTAVOHp5xjph8zc4_->?wR_0L0)>R1lqiya-X3F^Meb)2)!p5` znePVwrTfmKhs^(1-AC|urWfsBbl*QSy?^OGv45-k{x#Ek>h+e-v~>{?#kN7nOP3iZ z##vTZdHQLns|gNFiQ;LIDU}(*$&&6;RNueQ>C|-VvlTw4ly6k6362N1(gW}}{EP0> zcIGXjhvziJ+G#ZOHahKzWhOX9wuxeUx5^*DSG4sXbb7+6_7&$}a>#1FL4>i%>qF7B zzwG{-Uygwp=bg?r4G$}w4`d?jl@=eRr&`SPgxl1HEZUcQLjS_Auq~^Xf&UiW_fIp{ z|ImG?|7YC?6BJoQiJo-~+Xqq-d#2ZqgH0}%Mryi{vpa@|gTY-u$h|ig+C8A3x3yfj zBgw&*_4}YR)A^$FaP$4~ejn%4H>oZXAD}h7IeN=yw;;CV@VRQ{59Rk1Mjw@~8t%z- zGWHEyVB~p;4?|}uabNt}{tNH+og7WK@~uxQj^9(r;LPE&9D^?5QzQL-6l~q3Mw329 zmnEa9oPNuOyAEJBy2~xS5%~gzU)ik*yniO$GV0!}fPBL|lT{6tal&Rl6wli8eO9VUS^NOodYgmB|n)*G?p$o`F@TpH#}RA2B;M z+dS=ZEg@eoAzy=SqX$*QKX*fVh;gy(SG~3}p`0_ag9dGsA?@w5O{Tn2MGd9VTT5tV zq$MCho)OM-rdHhMdX7S}SY*m?!cctB7BH|%v``zs18bG#eM$$#{flmtFv<%~#-X`U zZP5WC>eutjhqNY@bK{ zEnIYM1NJVyUGP&j>Qe2;CKzi92rADN$1#ly5^vAqP|cpu_h)PisMtbr=S=aT3Vb0l zix>cPC$%F!Gokbj*|)hs>HHmAi`;{9lPui(wT&zuJjd&*^q$tZu?W?KWbE&CrY7m+ zP*tDk%=@>>PyWA9B>P{B&Hvg2+o}4GCfIp;UCJmQ$jETzA}j4e@DOD*B`WapB2gLH z8I06($y6KnjPsP9npqBgpP2#ZSy6ns&w>a~dnht8eq_YD&E-Uv^Cg$_!_@2h?Hk1_ z=5RSIL4TyFJ=sEJ`411_`Z3e-%0xEUYOXd+hVPAX!8NO5cDK9b-=T8cOz`X~Vok^6 zF}<1=@z@MY57dopoim(9AQ|skx6%u6B1l;Kzid|_1~_Soy=7IG(G!4+a6DD-?JM3vygciL7Jn@%)aXZnO{zL5ZomuWo2PP=Shmn< zNNG)?zz4ibvbwiHf~Cq>ErLFh%r3(!uc<9$&C6xi{NQNqtVRwEk_Y4Iafl!+jzTbV zW7BhV9cdXuv_faGN3;4)WqifVk!73~Z4En1PHp@1`(zW8)33Q<2XGQdC8mQh#g5RBAgT>(D_JHV3*EgZFIpTv{mjzg!XW%R2+MD(ivg44OYo_VIfjL+qFT}o zMcCjHu8-H|FvMigOkom}a`W%aAIrsJNuq*TeDmDK>R>OQb=bm;o20`;0$=C%69Ki_ zkp1EyEr<$J@Q*DpEbe{q3NvdTDUKs`Ois9%D6`xb8te28`T2d#eHRt@Y*#cHq7w>% zPTRZNh#BZ6~bSBzHBk1e{ zQtJ6P#GO&R9)VE6msKL}T;kv0NRjc;7;{gcA~-KCj*|1Upc_OifAl=UM!g>x$rW7( zLh;ayy(r)rbxUSBNCh}bKlkJa{jgHp-{=HU_%vcwE}}dRt}o>UJbpbe#%Un!tTLt@ z3V(&^Fb9jndC|+A@cT8o!f#4Yq4L`S52a50prB{SM=3n}Cb=fwi6I9;>)`_{I|+>< zYnEbKs_XBvqfjcL)5qtp7xC@i^$&6X7k)i?dz1fT#gdw(`@A@6C(5{^ktmTi45@8j ziigymAc!GN0~lps{0wIyTV50~LX%)ZG-0KtqO5Hxc>e!lZ_QD)h=1pFZ(I_8!%MBIY-0#_o;64 zK+}E&toC@i_L8NO6idZ`0SoMAo7st)%B{yW@1*>T3|0aP*+tf8+YJj_(v}TOq)x5v zQthLTt7|Avl##d?2wqn1WK#Tir`8%}f1RpzMy3=)*^#I+(!N|n^z&FQdA9i`eKl-m3`gd+EOll{S;v#OvaV?4pEckh67iNWASt(tX(}ffjYP!fU`tGs9`P+o zi)#X`AFkezka`m$aPAEy4z$lAW`+QL7@40KSmd8XLA&>5Emc6K=RfrUBenkI*hK1KyNf&OK^m|a5 z@WZTY<|~Q8{5R70c1c*nQ&sX8zTL6CGyQM@VctKSFBH3}g%Ptk4(ULwDPGZ>Xz39y z0?#|0skVUVSrm@ib{9f3#?EXt=?W<_AG_?3qA1(iS$B4_2iPp41Wl&xzCUqASL zqDJ%Q3L@)Ptkbvn`>$EQi!0-@A!y-frt7?dPUA;RzAY)i zTH-EqV9F{anq0ch)gGSNg^aIm@26mrQ~>Pc3x7i~gWx@XMsr?Ae@yh|yv^0qvG z8c*?05BT@L3DagUP!>F~ogo^lhcjWbU?bRIUT!gNDZ1Ha89q^tujQPKqyp?1vl0XPMrYsXmq};w=72`rem(5B~TMna%1r1pduFN>N(;lQ7qpgI*Cwu*w~MH%$zo$j3rRfZ+{9AySHg!GH@?vP z)FI?KOBE}*FdMCIqy(6g=Oj$dbOwYIN4o;JAtua>K~^!4Q4m}@71p%8KH9X&+{X4sF?q{vaWCj;$U z%nmj%ZO*70WYiu&5Z>>!_;FH!EU#E7sbqrZP2Z^Q=O z?f=dl_4`&Cvd{hq3Fts-IffW{$=7W+ASwCH2Qj|$MUsP>`VDU4E7U}Smf?uT{)qlTFa+zf~5#&kc6^hrw#(v z_?*LBgYxwTc_j&wjG;QBU?{^+JhmLz=X_{=BBKaLl46wmaq6?NyeYyH+q;Clxt5^J z@4y)HdoZgO^rrY(eKjC@OQe~;3J@Y8*1g;zDQ&Z;?}w3l4)iiiYy)&N^csiiV^FTI zOz8UH**f(Gtw(o(u;>JQg~R8j$s}#i>mRDFOz91danKqtO2euxaYl-Z&82j3`de5O z1CD6;0ZEUpl6E~Bn1BIg8tG{$H01cgRVp<6QAddGYJ~M2rb=Dk9LFdg5u&!B`kg{h z{7`%}fDjg1?Pb}O@8ef$=z%>iRM5TZ^ACv1Qwii7^!Q4OvnvuGkp(c&SqoaVdcB$m zBQiB0)gu%H8yX7iV^`TZ0|4fc>F0etzuMqTbQnH@!a6YZk-O^nNY)8_733tq$^(1x zia2(<D`wBkUTbRA$g1u6$sNm4w)GtZSaLHo&$=%S--x4-&$IA67MbHDcwQrV zL&$-@O{i05tU=gpv#udK3+}Ps-O9?cB!NB^3aGcdPA_8D({7JAdan_#Y(NV+D-lku zV6@?{_I>lzXXvBv?z}3@KA}@dvr#3GL-}Q2@J$W6^@GIv1f>MD*N%y-Biwf{JeRP(eFplfb+7%Q??v7!lPS|2xlSNnphqjZ4n(djK}P6a=< z_9Lj*c_gl_)PmrLIOEw+b_zxf!Ym9?!yqzm_fkuSZ+c9wuSi0`1^bmwJJcePmJD>$ zrLX0d^a-I!dz}25g{{Vat$z#lT`D&~8&YLi`7|v6=f{Gv*6aXZ)zolE^&S2gCkho{ zp_?%_UP*-?J!Y`ADWCoNaNJZ2tYK?3%tuiD8MV0U+e`h65?Ls(5+3Da!ytqsm7N_< z#%J5e+0Q9V>E>*bq+43Dnlz{CQ@S@4SJ+ zcIwU`h9jYv!ln|aJ=Jd(8_!w0FSM=&R1c1(CEXhVaLZ)HjiAd#zDrgFuZZ(rl-1X0 zJ%=k(S4iDTKDhJ}XO&N!%CRetyDeX?3k+eahj+^{hpk?v6?&c^8yX-b!eqQ5$*DFK zy~E#KLLa#Y>R&ON1Fw5nBOHNJSh0IL5{7MaGcfx;P9SCtZEc3J`tfjGt)5Q@I6k)t zH3^SX_b|VD-SIPX!tC>Un-QPTk@S=FNaa9hOyBU5LCT% zTH3BS8(6976*wv#sUc32VJl!zU&E*y>xT2xZoIvEhvst4z%YGQhGe>!UGQ5Kl!hAc z;@c-{RWGUqgDG92(hzL*IGXa5r21VZ%W@M__8g9Jt$#GaNM}Ye!0nY+whQfR_p;79 zAX}+sN?#tA@CsjBSlJgH0hQ}Ei#EUEMC}BK8fa4>9q#a(md`i#ZG!eI6??;u>Gk?Q zWc#h#W|Aiwwu-Ku8uM3SoWV|h7lwzr7sMjCridKy`fg*V+8}O?4dD7APV?!i^m83l zB+CeE&Hb5;_xq5C548+mk|M%ScIDGRY7K_u#EvS9yo0_`v@kNzt`D+)i=RazNH+C_ z*9#uu3Rvb{+ye3mEz_8sXFSYW`lR(;5(fO{M;(3!6Y8MOB148+uow0v1bej{W{h0y zOqTOzpziZO9f?5QZ+|)pfx62KVX$1&BifbU4T4o`Jl2d2Vhpszp`Z>r%vA-WB95Uc z3iQ*?evOE$6NWk$>($9$}g?{aT6v7Kkylr_irzOjCM}VcGKY zv2Bi#w0@=csl5e|6;?#le8@pc37e;LaTEUg01z^@7Oxmf#4`bKaeT*X1)QffqF^j;CUqI3L4D~F zmdZh~igh@%7sx0#9T?#pjUQ$V?l%)EE_bw!cmj%6j*(0qa(2k|FD|*^f+WuX!>_g9 zy(&e~4<2X_i-2@;q*Ibw$$(amB7WiSiyz({DF)z;QH3H^c`QS$NxGmEsY4!4brYH6 z$6MfJuXhh6hH|k6fS?R!MCJ>>u5Hll_mecOEUCdpF`LT!sd>}KLGKxdao?Y!+{7rB z-3K!D=gg#WScZ)I(+f73mgaFX6S7=J0SHjR!?%Nab)`E|e8dZukZBK7qYe?Ot9yOD z$uN|u3Qq?jt(IcM7gOoP$Y0QSje6j-2BF~pfM2rZ?95=vJB;`Qb^0ne^pLvupx};i z^$K|g$@-Wt= z8~#+drrLJMx#2W@e$lK^&Sm>zm@dx4Qz7jxRFnbc(wa56*x~Wx`X0V{{`(}0BRMnT zl4U=P46H~dyPOTzz(kKUl3hsAc!aOQ3bCVv~8wB+Yw-}xhbXldJ58P4v?MZ1p5e(=do0)gMG z^RGiC@5C*dej-a_H9+u3woDI@q2}xW3GMd02S{H2Vjw23*0sp1E3DrdoPfZ-7bdwY zQh6J}2?oT8MhPt5bWgpq1h`dhn0?)NP>rJTM=S43q~(XFhtP!vP?9~RCAL3m&Cz32 zvLh8(7!o}&K!Q|My;N`&>9pE;75UYR4HTP1sK55{H8!9I<;oTGvFB%iE%^?P=8%|n zKH-_%loQ5t0`#-|O~YI*G2A*EuUwQilKt*&MZ3WXl*jy)&LF|8F|H%*yYjV0zps5x z`4*g=QD13=kEl|?M#$NmMdy5xAh#<1KLS8~PweW58%uT&-w$H@QrZ=Xy93_%G2r&d_%l$S8N1f+@nI^zwLUGq z{Q=l8u#P0+ap9>B@Ecy{Q(=8@92$8`fjDt&K&k!pBc$cJB!g;&d^TI<`WA6^WioR9 z$^_dB>Y#4qLaa==&EOZ6`i}|m-V>BkYEup!L0MEPej}pnd5yBg{RTIduwhFv(bReA zo-E1!q)w7MD(d1bu*Fg90oqFvCtI2RZu!8O$W6?Rv05?x3G z9AgY4LDR8s$L)#(nLcD~T0@6pNbCmz17IsFxUxlOn>P7U?4rk@QP}3;k@eSHY0#^D zXzi>v;|MaU6cwXFKgRRT+x*>D+#qIXAdZr3`T}xY0l;Mg;~(3UHg@?CC*17UuzH-t z2GQ?vv9JT&4i36>M}MT~Po-p4CX&=;6TJ6hbD+Dwf>CZ9eLoSpivbap(YJPv|N4l_VRQ=^;Qfk8T`p~lnqB~%Avt7Sp z1Jq{!hM7@<+AEEF*njkoT};6^FTkMBS;RWBe|O3KPmD2$*}2-9IvKiH+S~nW(%v;m zPGMaT5wI=yMZ`!L>MOLZ;W36hNXVQr!NAU<$OI{4Y}RSiDv1F@ck!Fm-C- z2IW@AqquTzYg}YP&0prrw-XcX?e+d2Z_mM;#neyryHB@&-rUFHa5S$M%sVPQx*0_;nR_T8wwLnz1XeR$@S3 z)~KeL*h^Sj zg{9DE(24fxAbrI4SWDiNt34?okP2=ZlRRTfA(mj_w3A{1!~N7R~C_mg7o#x6^c9Xxr8~$xM}8R#7K&Oa6ICmF9~{nV5(SpGZ^2Yp3LF zbDWuo3D&CU1;tzmrpY73y&_t)=mh2L3Y35 z0vEGYF`&c)x&N@{=nc-8Ba24}NSirvQG6(WwR)IG^eTLCp6(who1sBXAI%5FO;HqDL9b!D)EZO!EA+R@&|)O}*a&0sAh) z!GHVx+h1(~SQFcS{_1K%`nR<$$^U)UN6f>;)Xv1zMA6CK!PLpc($tyse?BUk8h*}G z{v#2TrSdsQsf73rUqwqdtT?`ildrnj1Owh{jT8timDH4v2|1K%>TR+7S=HLC3e4$C zitE@7mdTH}UL`1+S_P4#WN1NPah{s+xy|~y`d6obD42>zRc@H!prbWcXBm!b0!yZN ze;wak3K{Hn@}HAzhO_e0>UMdRmM*Fe)nOlsyK)CKQLG{Us(RPK9&*A%Ref>4ylX^9WSsVR&A(DjV|pe>sPw-)k@+%uG5He%0B- z6pGGMm`n0-Jh@^VcJ;&}3lPWUU@G207un@y9p=11EG0Wj*GCYFVt!>G=95kAFFn2Z zr66d%b}js^Q<)B(!6FxS z+G)ZdCGvEVyqCoSgUDUCaXmSeZUYfEcw<>_ousJ++`T-?zQtoP_HRR@J=R1+LtZn;rcW(EM`ZCes)=qR zsK`4zcmKO#S|_W@THtLrB6+wN7~#+4LP?rAW_kk0qVp6GJosY#UGzDB@yq-^?a#O-_+EvWt^V$A z$&^(k_MZ8IS_g1@CU@aeEGaFo`8aC)qzZdVYMsHq0>%O=7$f2Y@MRfd5|+ zemcTUVDlN_&i}TLRp$R=gsa+Ho7!1={m&r(N9k4sMte!9(5K>2tBBw;#;1uXi-v}b zq7lOfQj74`7SC*XL(E zqzQx1CP$Ip+X}6A!&GZx?LQ~33J|Ee8p%Hj9zuP|OvF^PpY%i?$B=|}x83Hw=?ZV< zA0hH#lWNX5+?vX8Iok7lB-B4ru%4Hpi*~&n>#s72^q>Q)=_+gu=mD6Z^_UPhqUAPa zO*YL`n9r({P{_`(FhwXZlSt=7+GSS4T&7mK^}(*w7A%pS|63(N3y$-0`pW=!$KGWmOmAQ)!jDB$DkHpW_Ml1s(VzuX`*!>p2l4u%@cd6;IB^fih^!8g~Es32&D^DOq z)fcX;aVy(i>_B(5f$C7Y9J2AI2=J&;_= zTS$T$b`BeJqm-s6>1X8qd%yjCHs~Xp?o79h(=Ldcadfudb>UG;o~163gIj@YZ@)Z# zx3D7bWfj)9L4h(zQ@wUre+z_!tz@3a(G=)+Nc{*G59q=Uz;~L9;^)2(qX2cRN}9rb zj+luhPhJw@hEp;@^_~w4_lNx|8>i9UAy?%xPqEGTyo+cq^G%cV_me9P|6<>dhqN(G zq>50JhB=VI)^pj78Q>RQV?5gl7noZDzmJKA+LgX@1=~cZ4a+21XvQ6Bwoqx?V7o%(;}_&=~+qzU7Ly0|Dn zvAVfx13?5OR15)$O>}0Kmro1`1Ce4x1R=wOT{|JiN?e?@+sG2jrLJmJv-CA;99`Z8 zUC$MRvvON3eJoA*Zf(8z{Nww}!guWo-|kAE!;My!jL9kFyYb7^te>B*s}HZ!PdU!h z6SoBX&tRy+hytp)Ux0<09oBlK91F8m)2HG0cLVuQZQ{gUVMqrr&s6~Y^97#eLE}!Z z4aid{a2-ff3_w%J0a=WL$(B~0Xfu*k+!3TS=Ngif+nlat5@L8rzV7Y!Xb;Y{M##Jt z)Ba!gI8)oTZmz!d7?Ft3<@`~MhT!MMA^GCgl!=8!V)v7-DHC8|9k9LYW%lr7B;p{z z-^Fn@jOS--xMnXM=XoJr^d>Iz)x2~04}e`F67-TohkPb%_P#txkM=F8bvt22hPh_4 z6teU_sNk@%4CdU_!M!|N-rm|iC6Ty?A!4H7KWS=NFut)#96B^cXJrv`z|yVEGt1>Y zoRuhQ)gD$b1<^RSy1dXuXKY_a&{&mRWWza4G3Zabbknn=o8JeMUOJ)FoC&IQ@F>5E zgw-k#%=)0HRr_&oT!>e*5pN3f+v;X}Ww$(=pxFj6u0p)LM;js8B*14I43X?H6@f_( z$XGK)IL5pUO>e@HI!jJmze!T2_No-H>I?c4Gw~GEfvlR8n5$*>y6r!|9$;@;w7CUB zM;S29_J=o0y31C(xeUpc7WLHeAfc=J!%|OKid`+*pU-%QhJ%b(=|B%3uvIsjt5OD! ziUrgPhs2B=k!-W29~TAT@bb1M0#N=iGA&RsHWbhx!zgVOk6CU}uVt`G3M1Udhd@{4 zVf9|}UKY+vwAU!@s6dVj{6Z;bZa%$NEWy{v1s8H&S<5uT=6EsSv)O5nfrKL%zGY`s zDeI|)|Bgnut*+&4E`c(-wWXPP)5*VvbV^!VAgl~7XEW4F?E^T@PmEZCU)NkM`RPLB z)MvD56$XPi02=8iFL|Cp9zYzyl+cK5fWpus8495} zaUEWU_$@KZgx=~ba%lG%y4=GvoG3-VQn*a2xDZ;~vo$W#aYNDu7H5;zAp%6TP;FcU z&X8V7t#<6&I#8M6ELWK;6=hEuObT;`O=`ILbF>oM?^T`|#AbpeU}-1w-MVV%=SxHcI+HGo8egd@G3Dc4yzHVTB@(L}S?oM)YQznp zi30JXd5uzgBd)rE1kv2_OS7eQO!({*nw_F*+;Q}7(@|FPqyMViTYhtIMng{jTJzQfN0LB}Oncpu0B*?UAQ(q;;1XHzdPjR6zBy zxir`iWh{S)Ws=2grfRkpy`O$MRQQtjzSkoniIPRB!w%&C&mt~ zGrAWirTt|lEHY?NUBGfKmS;dQ%#gW;+kX=$${S3cP^P8-ceZ`eUSC}HpEKOK3KsxM zXTl6S+PDKVnOroCfu{<(JsC@s19S?thmG51N6hzUd#t({$I%j*)qQo0KQ7If@dOm(Ez}c`bdjLQkX;;b{ygmsu8JP4 z>J?UZI=Pve%PNSPYokR9-Y7=6Zkr3|Hzt*C97ga@!lVPFk5f*GqHa zrbl|v-I}Y9xCn_-6%DEu`lYnfd)&<*Wa6OXgE5PV(qy&vxhV7aqCAVDRYNuMK3ye( zC1rw;h2iNb98Av*?dw24`F=0?MPjYgl!#gGB+KGEr1oefxdCD{jooq*C8vhkey=|U zBq-Nl4D39&G~<4^x+b2q;u7+zgN>5*UmGQ+zENfVKwQGK@0K5g)45!5b5`_$zA~g~ zqLhU5mztsmUmux+O+L_+`Bk8eexnq~n>r>&j}J}QTwI`XfGdwx;yxhf%+Az4b;xdu zf>MSiP+-I(Tck2JgOWmkDHcxt6XvdoYrZ!^S=p}4h~t53P`r}LEdu|LKkJ$1>}FSN zH~>+kqN$2rm!VC(Bu{GTv*{ojM9_$8z*>Jl|C}B9bOv##gfW?Au`Hnf0_1LuDQaV$(07FTVN!RpO*l}~R892fUjX2v$>Z)(%DgU7(R_og?V3RKyPLJ zC`kctNi{rko`R$@0X2l?7|hr8G-{F_^mcU6fvyM8o(_J=@av95*cA~4LdKYYG>wH( z`3Uy9pohwdWbQUb(&l;aja`2qyp{%%-1Q6QI24ngj^&$)kfM)COhTX`?9A^etCWuP zS;jKXl&JckON7H@cv1#8^oD)A=7IL(h)SQsq$q_mffMo#%wuO<2!7;yHY^ozDK1tt zGv42;q)$QB55wzSDtkokVzv`8JsA|?k`*1>LZ6X5p|&^*ppUQ9EO zKsn%Pi3V&N^ti%4BECoaVP4f_PK&E##I%H@hte&$N85F(AD+tai+`)^qg&un=D8*B zW}HoU<1wQ1pUBRr?J|2Q-SUr|2G+^%4h@=5D;SM$l4&Wu1sJvlW_C?x6vycqCw zmF()bc%iCXO6`mIuTE8Ddn``poAgooRY>N%jaem5HR2-_m$uOi5>KG7MH zHTN=Rl|ICIXgG_KGVXp?s@T7>{bDwk68c3EY}c7$Q!PMPV=eUprblLaupnFQSpb53 zt~2U7(mJ9eWy~5&7G1;Zu=v!{MZ%ZUa^}bqfse|ilkEyO5QkP%xwb)7uGhsl5XO45 zpRt|}uHK3dv{v&LY)seaA}A8|QH9anI5&S`e0u(#{i=U1h%f9CzlcjvK)Llmsy9(+r(0PQ+8l9)1spcSwC_$C zn<}?r_!2v)?M*nb1Nt8MJCyEm6~e}QSgu`8rd`0GlUHJ<8{ZdmxUp4nO*Shg8uxGb zA@#JI6?s&{k<8E-Fx2l~7W*2Dk7VC}@v5U9s;EXCaf4@Ai|?TH*H%voz@Dyyuvv2Q zz#Xz81hg-q`M{H#7tc9lbKQzFf*&rou`U;qQCaBk(7Rs(4%sveTeTl$YVIwnotmR` zHYOFMEj3k?5zj#*H?v4*ctF}I8C{Y<3J|LMzSk7Tn>Q62XcHvE_Wxm*lj=8Z-1=I& zj2i26yl?rKNyVIMLzI}_$@+5h`57b9EvR69gLdIXc*(gfLg!iB3KIS zIGuem17NM<@b(4ug$;pWjm_b4;QO-QO=_5jCvHQpk5?~Ua7O67eW13fY`IjBb3va1 z>(B1u11`#fsuyv={U|Oou^aIgsp_^s;vP?jBF#lyA84~Xp+&~K=GOVz3_j`XP8H|H znHquIR^_Xz7*GfJ(ffy9re2D?9CL`=Jn>52&I745CGPkj`%AzMhSy8m6HTwpX9=%tB(-flV|9W zp!Gsh+`=I#qfa*V7LvtM*oq&RLloa$X(Uv5AKf#VE@8mAO3e{je8sx>rRWahK<##h zxeJcjI6SHbzQ?m8meF=+)KBk6&^DvL!g9wSd9f7boP#83U*$3d8fLa<*_e)#X2`d& z9HMXUvF{%}=urtjQc|~ygiX9G`8|8YmbHEt3RGbQ7+d29c1QAMy!8qyE_D0Pt@wMq zX)iq=om2r0eyhV*q@9i2vdya2&_9dm>q~y(trY~k z^!%>8MrrUM{IGUm`CkYGOjFKWlyFT8^yJ_t)A}z8; z4_M)Pq`uO8w|-^I6h|;Wr zc#}-NsKjB#2?DbuuV4Jho6G0?=A#&11rZ&uklS@bt_N1s14i)`SgRFgMdgh)pnha2 zptkLMioqR0yc<}p_*z~9n#~c|r+-E;YKA9Orhr9M7U`fJInxDQwV4;4h1qO6Yqs7g zwayNHKvdAaT|(0VQ(-bqJ5jDD^f;O)tS6g7s}X^SSh~!uQ@SHmIo8mcO~F$%MFmFG zc2UZ?IeyDr%>Km=iaTzXma`Umc2J2ljC~TCZz}J%5D^OJuP#boZQ#@QV}?ha2UW9Q zBGzP%Thh{9b#{V!`-Tn0`8DXrTN2Z{f=G*C$Zv&Y>?93A!3)Gz%3DWP+?j`}2kLQ; z>$ph_76Y?F0M6G=8TclRsr`Hw%BIDkvdL}<*lxNdco70>{$5OfZ&9p8Brtty{8_F6tlP_PFHR*tOcG>Ro{)Mb(xe@vc7@@4v58 z&v|?;Gcj#CDk(hLXKryE$6KM^2&|gJqZpYuE_JP=pZqZ-e>;E%?^rKV9PK#r+}lAv z`It=^iB16oRRo~d`4F_*)o*;+i}@)O87c5fNVCSOji2} zSwg_R`PIjhU%;P#cv|}kM&56$*Y6$q?{BkHwTaDL2(M4`$O>G>`|-!J)mF@Vs8!Kq zI2gaR^L6{zOkH2fzy2b*JEcA1z~dWq+ttX*y)-(~C;3r1f!@i^aHmUtr;ByePI}jM zovWWp;N=g0SJTfo2bdU#aXfAE{qx$VWLhvoi{tXRZ3uPNgl6(`K|k&eDskDq`NwR2 zAE;?{Vnv>I5$P+mWH!2+-7&Rp&24W#dx16W>Avs2)$E+<&aibD?%N&ed$d(B zjjyny*Yb+#tOi)4UC@$ukufN|>+@YXAfC9I$|4`8T zhOY$N+ZX=JWae+{<#Ug|%A;d8vn98}0v5soX@P!IB*b^z=MeFd)*ifasC&#V7!)j2AI|J?{!!Z>tLu%iiv>*k zHB?0LF!l1Q$km;nH?W+H>L zJ#g85E$|DurXbv3@Zsg?SwG+(TUKlo#BfuPzkH#i{dYCJ|HKAwaYJVpAtxt8&;RMI z@9Gddr3)VL;8SIF_BA z&!cYnNOWGsqWAoH=HM(6n0_w+dK|FHw5I3cq0LnxsPEJ%^`SwUox6P^>es90pwFG; zTp~l`YzK^HNp*!gIywOaO%^KKl$KuCM_|plpreP=(y#oIx3hd)*dY7mN$a>Ih>A_K zWpBXaMj1Y3e#>RFg04`RdYPvQi@6f%m;DpEX}APL(Oi>sh?ob>Vt_w;lA3Xk?n0im z-~gu%rd{h*2s{{Wz@Ux@-Ft*%-WA$UHT>N0Z14UJf_6pJlQU`DLqdeo+-qb%B+%~e ziq>?8|L)pGQ)twBLSsKpUEj(&) z?G2qeRR@X|8|E#wsj<&{C#g7A##~h^Lvp5#(lAqE7wFKSfdTF?8m10|O18E`hfkn! zvSjl(+aF31imT+<5-PUSNuyCc+(8wHY@kjB*8?=24|>k*bt`*}x-6&!C+xiBDQ8h` z4a+t}wiv>X&0i{+DIPf`1ByVWSvm0Jgur>u{we>2d^xM}{8Fk^6^N-_+$yv5DLZ@T zrpeh=J>Kaie=VU8FC@@upp4Cf7&=MPovdANr<2t+y?J2EVO@_|E3LMVm+4}=l|h6I zX^?4oAZ=DTRiNQcV*FcVkmmg8{nHLub#0X@)c0Q9QT^ijHtG)lK=U^pNipzEqj`p! zM9P}+cWRBSZZEM)WpJ@b-1WCWa|X&a{XvduP#eAGmT^^gjBIkhh1X3{eNq9vws;-YQZth*ao_E(RA9?j!&;7&TkSL{4w zAjyk6nWmQ3@0$o4j4Y({N)M8faT^Y{)#?wc)|fp6r{sHaQI|ZUu72D~CtS2Ej~ewS zs7)uzuntrr%&fy>hxBQ@N4|XYiTvoD*`!i9PR@;)B5Y9d(=023`;$r)t+8a27*+)P-lA|2*4bgF z_8c(%uf+R34*+T(X540)HieWcSMc_ZWrT@P-iWYyC?Z=ZVNz0LeSS%R=38R?F68Y& zmdP)oBu&Hk0P!w*ggcI9R7N~u$S+dum%xh}=+2QJUz@mPZhzVOJvb+0Z9^?FiFK=G zQ7TP{w@BQsJ4B#_RH0KuOS)l-Ht*Iv=a#y`+liZ-W(sTJM@#cuu5E;L&yTdPfzM(R zQYSPNorOq1QG7hDyjIT;U!k^KoUsXocu2EKTm_vHaB8q~`x0+*PFze!o^rW{qb2LT zn_f7->PU-Q6vgqlyHy*`t$rFxi6WM70+Xts=c0VJ#*;&vo;Gv2o57AIro8zG_{oy< z=OO$8%N>Sp79MPFjku!$jZ4y#p{5}@jcpJKq@QMw0C1iva*}x>nJ>M`dN_a?1fp|R zP+&@JjelzG;nX8W>dBFOZAYGUhQI?qIhZ#?#@V2J6&2QA8|st`O+p0jP@Gj{ z%QH=#p1qCjdN-XK7wvws(nFcKAl!&noL?1NyO=#f*PKt8E+n_g{lbrWQ#05t+xlQM zpvqh~_Y#)sX1uUv;NKvfkNLh^`NI49n~UJK5A!`m2>=lNUCjUc z2^9MO8L9oNkc%5QnSaYS{|mf|Qqgci5`+I7(!BVy1Xk1ALny=^8S6?iVDbZx;LzT_ zMy5r20%ggt7L;mKybk!M#HZ+OpHg1Paj!CHD|Q)>0G#qc@jd|`fyC3LxVa5VPU+l) ztDNtLjGNrF-q+_RxS;rMSTHLflU|C{DzvM|rbOZ0sx_}#!KzE9Ge!RyL%VvLKH3r4 z1t@Gd|FV$hs4Ptqqpf5(sG!E@7I&>I3vmuNJ^-MD5`Vgrq|v4tIcl-pf%Rt>QH=v( zyi*ZseZA~X8qXOgCv$@v|27gM#nQLD>*R9-Kl=rzYp+ns5<>787TeiMxJ?#gHqii0 zZOimvqmxsqR6X1Yy-=p}F)ohI@nK?aJ{lM3!j3ep(yMe1*OG8{>2NU@BxhMZaAwD= z^027&?jo+AIA=E1YO3~4-kov|S<|M@dr`Fav60@}3Higvd{etP8TYo8A<%_vm9o3X zVlI*EqJ<~6ICDXN;2;*#z{1ZC^L7!~5C~d+m0<+zLI@P5Ee>7dAtLb|`Zb&-2OzRh zsiJ-4bHyyeW|nOe?XeI-^Z^H0Awc`x9HT&?^8F05LI_zS_5LH|$_EI{DS1+$f!C?K zRp$&NkiHViGZ(MkJXge@fCf7$(R2>6&(jXnuUbLQouP22nXcW@0oe1^^o2Wh zJw=ULF4`hwC<`4r8F6B*eF&Ijn8fKvnhOk3`H>C*tft{d_0S}SeElzQeo(63``izL zj%(9nIEL*t;?{Ca`fm#FE?xniFeXTx0#R*M(af%O$Gl-svaH?09k|q`Jg3l6)D(>PD)>#6zYGfg!5D8* zmP${v{St5u=28A40I-pNew>xuIg@mPvp6oB@eS;1Ge>0(ncS+$1^R^S;#1s^0kB~% zH@ydCl95dV7RG4j-X3L}oCC=xv#h4B z58qHZZ%k?x*oKG2%d+hXtFb&Gmc2tWk-J2}&|IL9Y(d^GUZJ3LmMG-IDx_;Hc)WfgH^tSRtF4 z8JNl9*(vCvSp(;e!OOte&uG#1f}PyN+R5XRavs906b2qzKC1h~d%+j!`v@Nl$y28* zxwD4@ea&hz%ki^$$w|q+cYb;=G#xxr1Wa4rBV!D#e8{U56)$f)c7oLpq{@+wkZ3Bu zp1|?rO9l3xxx<#H9gUBTeD%igZ`X*DMPuUh)S(SK9ph$7Kf?A!01Mi>HN29A_Fl=( zwK~PpLdh6UWbI3tBQN;*f-?7I(U!3aVU+rSG>ei285kN3ts>{q*Bk$754}?t#0W5Y z{;S23d(jO|kMzV$YO{j>0(x*dXmiF7Z@M4g5t}ojtcIbl69?;NYt(fqeH% zk4`l9y|;+!8#LCwKsLUTG|?2e;#U!5XEr*j2=7$pUq<(gSxH^d%#;-_oM8SOIOeHJ z9#NanyI@YIO%oP&dltuJ@ID%@DO4k={<5aQ$FK}~gv>&SuRfbKqf+U>`$^g9=FsWK zP`KccP;=y>qx;2G&4~(IP?CV=6MqJzS}`DU@u{}=MS zvZIN~f93f^RV_6nHRR7=X+-=zP-F+;N;PTHFn7?_5|N-KDD^?ZUMZYDfLVfGV}HZ5 z!ph3dr`E3Lg~QyRJ&l&y3yozga8--hb0MFBO`g-zf~3;DhZTt&PLHcwn{R7x=S;ru zA7^&g_~BO{C5So1N=P)P4VdW*-@WhBQe#3HIh|!g(Tt-`%RlVNa}7Q&f8Z4OH&k3i zZAQ@@ItO)8w^Mh&SiB>IGl2#ifZ*{XA+F`jMXO&9A%l-~xU;b5K`Kro$Qt}67D|#h zi=$7|K={h6@by7U3nC~D?TML*d$8tNSWF0EB(D30v6jWvLqwHQq~Uk}=#Sirs39TI z6pK|W(q}dzI|l@EF5F2c)gYvUJh$zJwKxd(yy~aE1&k)-MmYfF=4vv|5a)t5a(fE( zQC1wTssc6&uQa47Mj3|#3YtI+OU21TuGI$ETq47Vk{|_R$`#02)B|DqM{K}EiLV6V zU%?@O4t@xgWf7S6B@q+mXiA}%t_nnzlsc&wkubJm(R4V#iInI}mw5d74Ghv;6XhR2 z6V7VLiql<~8kq&7&-bHlQvfpan2^drsD4lDsK#+l_X=hkg7cmI6o3qm*x5;PAkcLl zVw-*QelPIX>mY>By&@P+^u_Vc3US9I1aBFpA=NM34w4;YI+gi22?)9_A_IVL)j7z+ zyw#|=K`Cr=zONwSb0gX5oeI1wNOhf7mA;<~iUhJ{CxBeYl>MhS?v#_Z66m5tOssvr zAH=y)@!Bhhw7F4!boEU|(Wzo2_gkMT%2|O_@)*tu_j@NPeH#+mClgI;=lr54FZI*B4TA#8AM)Mek=P?mt)q}Z##6=jVoEpR>wmQWi z$#_I(021Q;+uj&|lIM!zm({$ZF@x)MLU7+z8x5bbtanLuYueebC z+(t)WlBGOuC}>zY1)tHguP^0VnNoOmnE)MUKBS$Lv2K33dG|6gbyYuChyCf(XN(WG z=yb@8UOcS>YfG=KNlXg?=SLB?)n`U(-J7isBVI5&=Hs_>xko-eQSs>=!+s{SzpEX5 z0Ff7w%bvRjp~72pw6tq_N9+y1KR12Ao2h_#>MS_wi<#Hv4t+H0rp zj@lSC+0}*|3O7C#z;y=TahD!;9Jx_@Z2^M`al2;545Qo^%pk=e%g{*=HC<-=Gx?w# zLG(9rR!Aau(|#=t_wWXar@8v|0<+CCYhDD=s;wV5^;g;v_9bfww9|gY$ucS?Dujz7 zRzW8J%5WxX=z!)9cS6R6)(wy1h=_EGsCB+UZ(wpjm}-x(jzI|p9mbrlnYgEp&>yvX z5q4?##(S8c#O!Spr=6|ZFM^IN?Pt)(C#?}TqC0ls<_^e}&(K2FXYN91V2zBZslAk6 zXvZh;CJwk{pw8|;=fse*&pm@C5mvc=yOm!G}OzC!T1m{6bj&=CH^wNqn(Ei{8ft9a3iq4Coi zzCS1fMHx#6&0!6z%_Hdtr7D8*1WQS+B9jxDJNFU3d&j;MNAHb^>?Dg>QdO&|gdXW4 zB$;?0O5i0I);^R&AI@7KXdb!pA@pS8ZyEMDv9kW^5#H0P`}?kAtP-6-6*pWDR1a!LGEz$IFo!X$8ZFJABwCx5!|V zE78&zx^y-~`-wWVvYMmB&Oo-c9VKHr@S}RiD`qw;G>|n#a{zGrgkY2MM&*mk6LU9I z(RM3?nMAt)XG9RZR2|fjaKhf^BTDpc8zxyipvR~oez&CZM^BVRpXtUwC%}fIIhR~k z=UrA&Hq<)XlOTOhUtk9mylNnZnm02t)!YGQDXPaG4iZOxmGu!5w_*bE5wgz|UC!hf z)y4OXLKgF96y8cj_cYH&NA3Soe_Vp`)K>kLaR2#_Mn+8k#@ocg+S$bM|C|{}RI-u# zRzmf;)FpQo(eH6bFfI{awwYk_!pa-aH)I5dlqB4eY&9U!X?Moy%?9%Aq4SCnCKe~$ z`hfdHd06*o1|o%UYx`apf zSN5P@Rojqle`2*w_S~TipgSfPP`_Ll%wc4O!&u>t_>kx^$rPua_4J@H2glo{vGYTnB&$yi@HVbe)C0HjXV=cN|b~7#G zROLcjqCw2W1d3|9;3jA}QWAJ4oCiw+dmO$$LItDG?Kl$EWD2foS*Rz9gs8P*QD3Te zkV?+c`zr)TbF4K6yv!_=g(C;EkRKz14M9BoTwFVZnuD3Yh}vv_5Uo6X0o+nA3v-Rr zl~NxB3C3uU!KH4-${;FMv#kwg=L`&5D^TLgk6*5)jn`O=@#~Gjr@Lq^PLqLdpVy`< zbAEP)Wpj|aXD>DY2!LE4jP&R5SmavpX&fy{~ z61GEd(C-r`OU^^bUM)6b^Nvz9My|%tn`w`5x87nG{Nf!L6#h*@C-&l>jM~9N3~B`z zhE%|dz4Ka%z#~j2u$OIe7$vV^{9|Nd3P~E??N*u5JT7jQjAuYXzl_2jd>&CYjz7>a zB$j7jK_HZDaGLA}RL}_7EUJ1W={VN+4f5oi0Se|o`xCt$;XH461kZ3iG5J2LN{(Glu&ebjTEC*6%>Z9FSq0U zZ~bTjT|2DOZ>FinKTZt%8%$HtzfZznz4rgtX;86I!ZbtXfy2kI!0b&PC_q)pulW_z zP}*2@B4w$l>EATa@Ta-r8kr5aeWH&2v3P)QhR(;_)G(8oY4Yhah@@>`^yji)?64~zoir_%70GP@~uODUW-QOY-ZK^Hmx-L?9Fn1UsU5F zg@hADiH#6~0eM_e*QVPwe=~%5GL$a>42Yt z8KqL8<_f{^97f>)#IPM^PuMNzbR#;QW7W4GC^~!~PW31xLD>+3@`1D8*&~MdE``8Z zt~&lXtgh@vvbk|MN^DFwUW|UQ#w)3|(xvU9$u^~CfRu_C z0(}PoL6DWPYDhZDbTzujrg5m!RMOsWkkKi3slK?8l!C}g-aFwXSVrM`^P;&_fqudf z#)6799VHu7N{>dZwJq~o)Me@EAG7M4h?1u!`^1q3+V*I~!tf|+Y$P2-^hk}QYLPw% zc3P#(E#_-Tc+K;h@inw_ajJiE-k(Mx*+zc?^?}))fOCicM!)4Hs_VDNeu;s(B@g%f ztS?--US$-A9oKW?a5O#&S{CYq=*!!BQ!buYBg^h`Pn|G=)XR~kjZgaQ%ycTYimGL6 z!p%n;JwoIi47P6|B#4s6)-#~;r|ggPO$xM`VHA1sn>*JO^nS8oi?+Ka_s0po7g>w3 zM_CR8@Hkboq1cjWvE6zTD4Ar?mVvVpOR>iY@3~;Gh8g_8(>i%jS!@@Lnl}=toOYB}p_5kYG{-!)(QVY|395$+)-9%?BT+U?)r z6rQ+zI|Yp_Bqu9h@Lb6#VrS;-5+1puQ#?{2#44DRH(q->UTf||4QIb#6V1}=FueEN zvnQ?y*^3ZM(=hIs{0Td~Zj|MT_t^4u10TY7(mR9u%zW3gc!MD+%Ps&a99EOT(;IN4 z%1yB8DC@N}i;=tvX*=4BG|`@uz?NwP6m(2I+P!0t+Qo|Z$El6Dt=Wtok^2+0^jykI z;w*K%dte!myFV}k%|u9<)mggN4kP;Wh06V0zT)jn9f=cF2S@7YIHlQTz3FKGb znVZlV+1c3G**blHTU(nL{WYfNME6%q@Y`wnUoF9)7zx>adi0>|_&NT#Ilo-wHa}3y z{utn2F*y*mp*Oex9`!Br)s&A%gGGV>Nk6=Ue?xS=k>qFRwpvz|Apd z&|UN0k8c^CMEf4{@I(6o%M$veyji;UM~@@nV3E-uk7|x~W6c;lclWdvj8{_g@uPFy z&qI7X`f{58@B|BzVL}8uF2fDFpx%pkjlU_b(AStNI*#{zihg~>CZTUK7uiF1ivWZjm~Gk<0|`!F5=D2cjQ#~|Rr$QHhX`^x*A!5qpY3}&@l zlLR%JZMl{(uaF95z5)S6QSt;1k!Z5qdFSj(8*tf?Z^$WR=^ucWQ8>DYE=iOsG=^$B zJ(8NQdkdwvUM!*g^;jRyF=!?JmIGb={`~h%*?(hV@;{UO|28@Kubr?_7?`JorYthI&L5!Ofv zRA$GgyA$*rjt;$xc(2jqPM7e%A>c;4ApjI~hjXtpw!68%DW?m%HSf_dI|!e{v9Vec z6o^?sQUQ_6s{1m_H*L82xmml?N-?6td%w#`<-)}DM|9rIms^Tin7S>Mx+EQ=DHCZG9^v};GXA_KZ3>rn0 z-#h}KA_;`S3n?l1y6*Uowr!a`aTm0!8;IV>-hg%w!2zVazvOnXp21G}*6J!_TF|)e zroD=NO?}=!UvVTRc53}V2(Dh%P+G|M9`wvstUzG-<&ebjQJp zVbDYF@!YpvjX$Lk;@fA%=r-zbX%i9O1+kHWF%W-WNc%X_iAHDcAeCNxy3IBoPT_|b zto8k4Uf7~~kZJ7+)jIbMNo7~OX_(j|B!K4wYwO2=m_{6c#+`&L+5rt1eO2@1mjP)Z zwHLPwtXW;&seqOp0`$*E^qFpthED%nVp4%!h#pH(S@Oz_JmNXibk$lO5!*s1G&uiJ zqp{OV_1Y2vz6(t4+Or0U)&D&aEYMC;^NZOa=i)XFvJb}(u;Agms;6?wT4Eazw+_%u z&n@F?zx0fIoV2@@!2e~=>MhB`lFMr=_1R(4it>tA!LzH*xFjvbB%b)5t;g%}=+Aap zFo;^uEgMW1kMQBo6Lh1%Nx6|poIOGV5|xRfXa^2IIQsF`1whkg_aoAsz3l9R>Dc`o z+kC2)0aglJXw4e;P(e8crAu+#9Birga1zSe0cI&;_X%VvG4+LRPq7wXf2~jlj-it* zQKNFl696hL9f`T=HfWrKSm!&Ka-Xm!B=xAz-!(ZP-CgCL({Yv^xe^c`Xsx1%U7_El#)>phGfkm z`GIKT_`1&E>02$e*gS3BzI|7>8Fs_^x~tu+d!MlnCQRrKVZ=UxhFUp9u0jshNV_>ogx?O(Nds`^fxn0DG{@;8vJJ|B*DfK+nm`w9x$2@5DB@t&}@ zYE59oUFde4e`K~60owZ{Kik{Uj2?MQxRuX%S?LpGGy8=qF_nYnT$%rP3!&{Y|$M8BgH@gFDdsQ!)Isi^W_4eTi8HP7RU@jWq5<|?$c88yG8TDS0t?{%rIbHE1}uPfDA$DY45dWlr2d$7<=N?Q?+1aa zL&urmJ_CIEC4UNUiBCrsXlvH@SdE%7n`L`X@tTSHe%uXbhZ=&lQxd|c*_g4}HAMcw zonAgSo&WZmjRLFwS)`7}c9|5J^zDiAg*OBB)iqg(SzV2BnFSNhq}^t=&URarski#n zVuS&Em#bi7A8b6o!j^tvI_M>CSJ4A+)5sINDyBcHT3+sJMR!zku!n7*rk2zB=Fc^eO4`bO9icnT!s+DD+d5QD+%b-9C zXB7v5qrw20A{aM>?cyzilUSn}ao`~?7?&7?vT_GSn{-L%vNA3DOkyb_l{OLjxg}Wb z1``1xV@I=je*>6|MH|V_p&PT-MMVge6Vi&qHLCqG_RM1&7zz<<|g8u zqR6TL0m;n|+Y2|vN@PeKK7zvIg`Sy z-1tA0M3`MY$;@dy{WMCdKfhTwm(v)p$NNcBnS|xL?sPhby?}WeJdGpiavhN6uUs+AZnrblCBBAkVFt% z3W-09n39hJUuc6ZUeiSFGnX9des&NTjDv*7XD&M7bWC1z1-}ng z9`^y#&U-`~$U<66%TbiB5ZKy$p_}X({r;UDcn}NQL)Xe?Ay%S04%vu9EfRwS z8$+du%t_9W@PnRVqZdqwgKfUIct4HcX982TvsTFmm#1oKpyYFHe3?L zQEWnv53%bDroXPqBTQtljoH@d744K3L@7z&2q$b}SC zf+Jmk4)z7~L+oUX6H7!31D!yYP{bL6ejMM3TUQw8l2(Wed04~SpJ)b~bxsdW2)$Gx zUB`60%0!e&N^j52VQaRaLZ*XSszyq&SL?e<4>LCHQUIY;#;OZ%QPuP|D{A!GKNv&_M zG|Pz)!<_6$eLUTd zx}Y)E4jz{{EI^bi5s{*bFG*xfc~r!pF-M8X!@TfUkkMD-Z8>|c;T+`}6>s3L4=f)c zF3!v5F|7;@K^tw5C8VWw2!anqtcR94FV+E)ky6>Q!dTwc9Q%UbI6AD)JgQG$9`i|) z)8m4^7~oBF-Nf6|%y|5hh1d+9Z(jL0k4lS~=zs%ePDlJqKxX($gga9N+YkYmIu8zf zQU)pf%civ=sOI`eg?Qn`snw224E z7tty;M3w}%(-sA+xT7VF>L}1x@AAMJJ9z96AQA^sDau^U{3D%e!!-1C%M{C_R})zM zqUY`%9%?DX)bgVeJ2i948?Z4^j7?->XCvsDx~djnOvC+j{9+tDkba zqRUPQjvTrQVB`(|?Es!%?jW*U(qcnR52LYX`~m4D+=l~dLpVFqf^?^xXy~kt*6gp5<_MVX@c3( zabM#$9-AzS^l-c(N{GCA-y$3&3{~mg4`{X0#ak_L5Lgb1dEgusbTitxN_#?@f)~Y5 zqIOj^$ifYzMuC*+WzrP}t=MrlDC=^?{x`k)`b>JT>E|4i(I>o+dgJ#tKN}l(I5^9O zc-()X^|Rg3j1@3)ln#l40F`^8?;|zP_p@m~(++C;n(!#`C=b{#Ic5!C?rLV)rH8lX_+pdv`+f5ve|YzuR{t*<*Mg z(#FD3AQ5OUtJ0^z3>Zot%4hVM)+1RT4@`ty4B*>!L;O^pK|?>J<(7?n==a*vzUtGn z$XuS68`|RdQH%gCcEg78)z?iSf=Sm0+f;urXk)zp%M|;;>iEXGD7j5kE{T&M49c(aB}9|?Pj##+OBRbGWE?0h zVllfF83j^hzrvZ+C{qr}UcaSVpjM7cs@=BEgm@(s2~f@#ZWdSD8WbCGi}`?zT)Kj& zFMpyhM&jp?h;pKV?1Z1M?Y9JEJM?Jy&nc4jha??4eT*u8C@d!c&NZ4I{8X-EOwyiD z?j99C&+SZtbqn{SW1n%DvgB?$Njyx z^;@@27%!{wN5f`_wb?dF*|6tC9ls*Np2A!0?E%#gb8}W)=eKkNQZxY~+}RME2G%~J zppTDX*P)B`^JL>2oNOU8#mHafF?ldFoY$-UFPUb&122v4{g{84%{W(7`{Odt1_a_7 z-$yfNWeUs_WQlND&xVJoLR8XwFh_}l$$&pncIA_DN*oOLDbG8@891l@ z+SSyzcdlH5b<9p(P7b0ePFc_IVeg7c+MwYAH4Q;Ix{HpQ%$6SV!2^7uF zKrA!wj8J{ca(5^k^eHDV?F?50j-SXni9Keiy*+{(G&9%nD@Ge9R_BjurXbHB@uQs! zxLH4IW}Rny#1ak+!?eYnJNvtTRlg=*1H8O=7(s1SeaJ$=6<>EE`eL!wZ?ja0E zx$VUA%L=)p2J}V-n}#eKl;n8Ko$q_9D(+O$t6D^Do!zU>Nb2;^nOYF-|1{2p!=mj( z*rypX4Pk^?&k`%Qz6NikXX)m<5z-}W>5Tgq( z`m2PRBTiZ<`wi*7Qm*5g-=j9fm{cg6ah~qj$Tz2Z#u-n;5nw)*vHyI}X-UKLqVZ`K z@2kTd6mMOfDj$9IFr8vm@#Y!FR}bG{e;h=* zgZa#;mE@a3QP!bQ9j6L^5!anXMgS7L$N>ga2+oR^o?mQa8HCA=$lZvKMV$@MMP$l7 zE#n!T!Ld_`Nr5Bsw?#ms=a+9)RJd0O_H*Z*1+pa`y@mcDq%{a7Fvf~v3a)ZLg9Z0g z5a#OBen%;D>(sC-lmy%0Ej#HQBmJ3bvmw!73)#|Z|7nw7B(1bbTarX$h`!vv@Yw@lo1U7_O{@ zlCjbNkZ{&EgWD;C!|b-S1!f`w9X675KlLtT*M3ViMDyT-CXDxRg;zQOl_4kzW9)|C8BG+9;#D)Wyx?C(Ex`m&hJl3L=;EK@ zM^i92v=41?E~E<-#&DuTE4%dZbU+ygqogrs0RJ-xx% zXIC5T`F;LU?mzzl^vNUWHFdq0&gbn(`_x}_Xf<$AyyB^B^6SD$<2R~eR!UIOPmW>3 zZB#U+7;KFC_Lh`eW8`@m1mcq5!G!cry0+T=R7v0yL{SL=tU-LW>qfUv*rW}oC~ceK zmWfKDa23Yt8T-Dw?I~Xm`TimI88*^$Lc#~|_Mr6j^BFjxGt}3BY9Eig=A+5n{X|Km zGt;hp$_T|KJGfpb#49ctQKYr`h65mi7xN4fYmQL}Vd%Y|NXZTkz_drL`}{bGO26cE zw(%1$@>f!^(X0A7K~FGN&J^R1{}=DWSNs{t zCGj>&#e!fn%6TOWYL>oEQj0-6 ztV4XihC2Wpi7W`#{Dc>;UGSIQ)i4r~H3M2G1l88Q;-chMr9z&;QF2TDJSYWh74f|tLc0jAx(?5yw9yz~9}?-%}WKm+oQCdL*<2G0NC zw!`&cx6BJ>3Z?@l>k39H3KsRA=ln6?Kd>LE{IUPOzW&}}h@TlBpQarLX$X#7SY%8} zmQ+y3R71}QVf-zkbb3U5Sa|kEW&*fK&uCweL~@t_ghJ04YWbWqu4N_4z-SM8l#EJJ z+-7nJfO69-vj9wCs${GW!U+z7?uS~#SmUP-bIuBYaTy8gcNgo<3Z=GLR#{l0ne30txDQB#Wg^#)>1N zaP^Qsus!*}3Uq-#$ywCJRn*7(!^ce+1FZu!17eH4fdWPKeH`UQ+E61-d1HYm(piYU zHvPw|LyjLYqhEibhf<=-MP8e)1_N1)l@ujJFDTx@vvbxjNMYhQ+5)oxi)PHZ4DY(sH9 z&O{?B=L#7C3InlDRoI}0ykV6EYbnGVy|hlA(k2yeH{h&p?zj#-efNJiM58%ToX)@h zN9}(^3jeMD($4+of5L_Tff35D%J#{_^Yp8dtDqvtI|z6KXukrY>q$#XL!_CzUsrC! zCM7H-2wrD@TcDA=Zi7E747IAG63JXnbY?Og{R<=narmVJ3fR}R*W|J{WxfH`dEne0 zy|HJlk#~@K>$Ahz|HdTO5`5GGB^YQtjE>%BvSRbmv1*Xv4?)25y7nY3g_jSh;N&>D z@CjT7^38Eu9GoEnkvgyvJRWF82o#=d5b4~qfqEJ<*A(n0L=1G-a#wn^F6I8M3~C@C z1Y?P9P>?c@3u!!bjd7*|D>Wj%&PcEuUd04YL#Vpso zu3ttp&)R7On?6$BaY5tnadN+r#LhyaD*mN$mTN2!OXBa<=LMvQv@PxkAMM~{!hvMg zcpJXYH5Ujz@_QftjzOa@|M$+%LnBp4Io{yrb0bAwQth9j2GX_Bu-zG^5r9*%W1G-W zdykW00}UUrgBCxHcDI{#5)b&0*RX+CUj9~=Qz3$1`wJs1`bUhA^?T$02l)M44%Gec z(c1rWYhB{jWd9P({c;hP&M3r&f(**aDQraQp|~ejcqmdV6h{!D-1X-o(*PwJ7HvW* zyjqA*Jr%gmgPRHY*30E$onepbJWI9vO#P_${rr550&>094CWM!NheegI5m+54vl7L>O;Eet!`e&oR z!IErq`Nhc$piuAW1G?({qs$HPUZBBY<}wn@oy{6bNWXyC^RVjokV`YY+)fun^^^8| zREH`i`XT$+3?;c?tN>5FzYxO@3$P9LgO(_hR1Jd?`NI)3qBSfq>_+x3$@vz9E^Z4) z7tLsv3aLw4Aq_{GX0oAJ*N8n{+>v!5#{)u?%}8k6S?zdz<$+q1JvnsAE_8Pygp&;W zV|wE}*)2Z^j;6i&bNiAMnt4bWN0OG4v9>I;@cWkgA=is*nqgj;DB4jcu#0@Q`}W<= z3;Cl{-(~}~GJ}9WD903Y`6HhIhvsrW=Gz7JSi-3qR8RS8W?BZ~{HtU5NGD~#<@+L4 zWdxH;7`Rq3rskzXK66f_0}9QyrdZ6` zm_ljYfoMnt2VdEk$?CcLb>nm;nI#{F+?dG@-cGPJUgSDP<~&bQ99l`|mx*=fw0g_` zmgyYJuBQS14l%BOgj4>FLi=}^{a2xlid(gvm;a8g_(qxaB3NQr`J}oAiS?z5LXyIU zKth5sLX-o4u3>BvT3!DO;Xt!pAY#-YXxv{Rf)k^L^M+Cbw;WTc(@bBHUwYlX@50zt zD{@3bHHKU?A{Ql^=~QVpX-x-nw&>b-&NuIKwOdcwrJ2l#Fiv8Yaw;&3mK1bpVu1y* zhA9|Xt~?v^5XPbDhLbqhTvZIjECJ;|2FDY@gz{{=cYx+;K0B;fTkj-oFtr6SmF9CQ z5Q}0*3B$03RO@Nv7HOU+u9%R=z{!FZD62^(i0Gb`?r#I_N<@<#QAJ}3`;nWui+x9U zf?pgD=%SpJ0JBWQZ`^bi?MbK!vvd72$#!UN{y3^X`2Hr=9w3Re3JY&iY34ai zPV*()fvO6hVF_-yyiCWb=8Kevqau$G4+7~p5G)4ySzwVEBby9j9Srd-Cvhe(Ty~a_ zsd#|_Ce-D%E2M&nXuJDu5RY_ZKYuw3!6v$~UPyOzig&DUwb0LF=wUcUD|E6VeAX3J za?5%N?GbWpvoY6+1KB5X~MTx6o%n zldtC1pgrfIRMZGFO1J?oh4jHjozx`F1kEjk^f|=qMgWN>jP!M70MDeOpEix0?%ecf zZQM2cg)-e5T(Pl&Z9N$!GU$5&7HUPDJWKR?OuqxM<4SX8GMo8 zC8d+b!4w+#^j*ZpRecm-mHpx>BSP+vI~}iC$KQPPA83b3omx@y&MoMVNsp>ba@E!+9KCas=W+qggAlqIxhV)Gg+ZUuEYBZH z=}FF0ip#)VLanV??hz9d1U-Nl>gOw%CzV)2n(Qg|=<}2^b*Z|guHGvWJo$6M=FvYKT``)9J=IFN3>$}2ssM*|N)~8f`C5=&yW)_)0PjW~u#B5GH7{8IiQ;I3ltHgYe#c`6EMY8~h=-n-w zdPw8+2woP!pbt6{wQoir^g@{;jINl!Zn%a12XgY1KIT=dv`=X6z8#ECuEt#v%RTZk z?;u2-2k-7-WB_&c@0ARK%Xb9ja8MINfkuct0T)SOP^)cCn2BZ5m9oX|nLJ(rB1M&j zq2Wl5SLPUzQjoOy8{A8|R6+sgeYU@vE_GGqL3H0SsrP?9CK>+~lbK52+#UsFonjj4 zH5f;+1HwEM&v+pJ5fKC`ag=>Pr2xC)c_dC_&cRfQ+OFqsG`HhA2NE?uj5qEXlJ}Y7 zly{zj(!y|znCWd|)vDV2>+xzv>23KsZN=TjNP#~<|Mriqz0$gTtkS}a3w3R$IWkq4N?CzsqCMg6CE_n`A@h1e zPSBlWOd)x-Kufb_M}sP!MK zQ^Q&1?7yKCxR;p?+FjNyHnl1=B1Y;?)DvImUuTQ;e-SJa`-Kx|=lP`U7WUISiGC4i z59RnHP~N0MC~J!ZhBwn>P_vCG?`OU4zv~>(x3=c(whc5PKGv3ulq;a{gfd04T1pco z`3xxkDbh8}wQn&9i4{}?WU1U^&d3#E0x33l6f@F5K}tygVJkIl`jl*0#z2{GA*nV) zN8Zq-z2rnu6Eb3m;3&<_g|j4?-)XZbS5KH)JN>eqLKJ4=bO|mU9TO<7d2gvU#E@dK z)V!$^eS^n__$&QVSit0?sXf}5=3WnqFhu@GWx$*wLep@39DNun|kIJds%JH(0m zE-((Fn0l$mB8k=+L(?pkUq#XFPVSqI$dE}Hs4!{w-+7!XHxzFA`^<3uBY6A&Cyz7z z=b8DJ=DjSPwN^8}8j8F;)uUv@uRIZiR`J3fAy~)`o91EHQP+reEyQ=SS8%T#KqMMn z#6dKPZ_*LRnyT`vBI|0V)1lYhBpZ|2cP4*Fu_eBi_Kz^gGenIatIA7qSFB7JN9iXl zKhthxshzq>RCQi=7%i(j8GY$6Ne{O?YMGodNM@!=Al$T0 zAFu%PwcVJ{D~FC@z&C>Ehq=r{pI0A`&T;^?hYdg!MQ@u9O|s84 zc-0n)aX=zKlnDv9oi(v6H0AoGu%2UU#ma`#Zpa7|_+_hGv?C`KND#v!2qEu)X!Z@A!w-cdG%LOF^P zZ9SIK*Koa6IBsE4-Lf||lG5wF)D~>vvztQaiSjDRW>Rw}^ zoze>9bsH&E>jUe6KpmcYGG>B5t-5k0@LILUS z?k;HrMG#3rK#*>vLojF%Q2))1PY$Bs{l|6I-Rmy)^Gv)m^Umxy@SU~&9B5xfC2)Y8 z<~zJ@3JG&DI7xOFu}9b#caSc-+Qh8Oq=uVN9i$!4IKJFD`LeO2*3J?p0WFKPD8X&3 zNlE{#t5@6pLBm?yok^~@ZqV5ko9PHH4iAC!aJEcZ`7e1p9rb9V@BlXyot_#-YFk0g zDKc2-UZiwE%`JqdUpmun?)wbk>pgZ!HjZ*(Y-q)&2yEKLqe}QjPfiwdmuVJc*5~-y zJ7_eXAS8qu6uN;`Ze2XL85sYO^ONAyQLAz>?@7o26qtA#RS8u-O~}g7W(PPnq&$LP za--tZI3qOX1Om-rAesVa4u4rLY$HMMd}%}<1iyT-l6iuTiIh0B>m-7Pt8TNzyqku0 z*PXo(dLa7I_8vCuTAt6%fKTqOPphk1bcoH3X+9~p(7LjF#*`2!vM47ZeMpWd!OM3k zQC{fd6Qde=J&VUSmw_d&cD>Ct-AKHXfT&Y>It!^lWtwbDyAuKiT27WYY%WA!4_lVa z$;=EJ^F^5$YE1*u zhq+5PA;H^MnL(tq+lV}j%Vu`gqcgs3DQZeM!zaZSQ@w@0b?_1&lMr(&t>~7^qVnOi zn1Z2?h5$3+doc<&PI}Geev7zj3<@YoY}1JB_Wf-5+7L&I7_VrGo3<#TUYc$F-#Jsh z((u1GdR^sPvxQRa6!i_o?QN5n?+c=PE+D~qj5gFvg_!*TrcH>_oX?DdBEkk^dbWv3 z!qroVTbgt=ga&j*%9S*fd(g$yxA7t(mF*demfatc^~Z`f-EqfOsx`@DC1%@IqRmOt zU4&zY;cq9le-rZVRX7sortjxLzf!MvZD~RxtO0He!pF#`Q)HgXfvz5yBKp5|ppy6x zQ$*eY$g%=52ESiPSJtr|lES(bdp(UHF(+MpHFDI)7!1o4D@{Rw`wasKX?4pXnOK~r_(E{ z!%dkp56=eHps`tN+C0bylOxreG!tF(<5T7-@~-fKPCrW4`(VDj4eMU_)y>zEnLEi5*aul}_O`ud;%C;A|~0{XAp zG+)@X>DfLcAafHmHM5M^B0!=lk3F0~8+692fr(scN4yiqa7-&^!c~OcnH{nb`n>Kr zLo4*l5AaY>{jkEz_;}uO_JZCpc4)_(M22-II{tX$P+}k;VmzKCe)Y7y_%N;2$a(|Y zG5=KY;`Im%7JLK`D*bWWiFjRNEY37T78gGjTxFv|g>7-A!|L5ubjJ9;W^AVni!aLnc%L&`Smp8R$Y1S*){y z2-}07X|`6d64iF^bGOXsgdo_>G+R&K>|k5--1w*+qxscA zU4@T6>4k$v9&>cO-&OPFacaLcmK)1CNXS#XZ_LvDlDSnQ@^*BVUfaF5q_9-)Z^~NY z&M4izF&rPq7jNviPBidLq=;Tj{sF7_fyeIskQ}@T-!BJvo{><-5f7WUgtGF#i&O2m zz>3zeBtUrPGGfhvnDyUM$uZU1o6yTM@h5uKqVQ*4FEdi-{Z2MbQLh#Xtsf3z+B)i#>8+Y$Hc%xLdP#pHvDAhlsSoxnHl`Q^nEow z5mha`o+lz8xsG@`Pw!^S@pA$ueR99u%C3+Q`}|h+&nBh@4>gt4RumtDS8bX}C(+Ic*^dBKGHlMPvasOm=pOXdf{wW`*fwfT(d<9I`KqrRi> z3LC9I7BiML+P*)?bbHe9{P50PqT9~9hu@D~zk95|3M7%dnNSoAgMhV;(bedznuz_* zbj%+!Jw4bp#FD`za7e+;7MRmd7Y+Cw{NpFbjGgf}X=SEu_tc$P>0dr82fg(aMaH5J zbChcs8cqvWzLWP%y2+#TQ=KHORT{M0o&*M z>n9m^^U7T7dqbRe92KStI?|E173_!lUl=`TurdpJ-k4pSUuMw5DVwVK44dSB5p}@_ z3s17>xOJJ}SV&Y^)iVkPw%SMP`-i=e_-*fCnXrRcCp zTFt4Xokx;e$A@-_WO^{k z6na4=7mMUn$<%8)0#orJ&CdvL7(h|X1$D~1QA=`Je8xE#PnKNsgO}CkI|;N6=M??7 z4XO;*a*6}`%6CNqcP+M2sTa&cMW0Rxr1JStKd#`aA|do+^x*7kFNzYxl7~ZbM9>_#R72k00-)F5XbG<#=3Kk{ZOx%;+V_ zW(J=S65zB|g68me2*jw_IM`0#&$O>=l+y>TIXorHglRB_k4~ZxF3UPPk=Lv*&*Cp5 zUX_`aZ;bjh<1&W)Np`rh-7FF+DZ)rLrlVah`>7dkN;Yh!*8M}@ffg`5DWB9JecurcM zIvMLGn)y40d${aM)+7tJFbr|HiQuMmP{y0B5mdy=i&w%6qw_W z1Tmkm-ZtF1ww1W}g`A47Qms#LDIwR!g&i_GdIPZT!Gh#{o*Hv!L!XAE3bn?mP>YX? zx_&WQS@o%RLnHr?$g}N^;LkJDGXn?$h^eH)V9f`c0_Hua^ zu47<{jLdzM_?UNY;wj6EAKJb9RpB+`=@x?N64Gw94x7n3QMc`n7M)-v@hN{(jP7ek zd9`?duuJl}X$Vmyp2dq+5bpY$1mkwO$>@9g37ITQezCBjDc?i&v*NtiU$qGkGB@$D zL>$Ar9S2V*u70Gp7vi-Q@;@$4N|=#fCGAvSO?RXpyW#ReCn%|B2J-L_MuxEYUG4j{O-g8nb^fXx*f}$B|<;;BQ8CnozE9M~P?*D(sof2blpDrEX}X0$gY-z$!(=x8I7|{qyhu)HnchT>I_+&-etdrMJ$mV-YwP&)~g(Nr>2ungcJ|0?~ ziV&~F`-I*j`T@&J)iDlBn&Xhi*)oFCR8Ks{wpE@y?xjbNW147p>}g_9p9mDBRwXgp zDa!KYMJwb-)|3kxucc{nMRYt;P--s-+4FexV(xi{a{!60O^(oVq5dAyYmY3#VgkbAJFEt}SDu>>o!6N;|Qdz%!>(BrLP%z;q(r!=2F(S{3Wg&3^hP zrZXO&G?+8J{PkAzCx%cu-F4ziD3eJxIvt^3?~Q5o;z`T*s8? z)*?KWIscb*Qvx{a+vy}9l>9}W5%@m05QwI96~$B@c#AQEF9uI{9LJm~iftYes{R}! zJj4J?#iJXK!q}F}AHfM>uNdRbzm`twpTsF0s;RZ_y4vW*ZhNwE5Sh8Ti8Up- zf|o&mD|kUbu0Y_fassW!JsG78JcFj&qH>BhaSx5^BEkm+Es)A`4|yU6)#Y-&ZlT+I zykV~?u`(AY_-e#HEQFwg2ea>OpsQkRh*FO5f$eap4sRRNr%^X^yjE>Jik$(~Z>f!q z(D5r5N#P54QpC_3k7%kFD)x`Ypgl_2t|yWsj}*xiJfMAB$MJv~{%u(sRlRy{mo6Ob zo1Vve$1tk>=7#9VQ!8BADW>a5$8~L$9usTn4BY~1lbdZ{r;jKb5$B<&jo`lH>>qj4 zKo-l`DWHW3L7UvwnCAk)P8hE3esg4FOBrplq@EPFgLdL#T+43j$17H(KB<*5H=nWm z{xP|%9S47Vt=K5S2FNoRou*i-;0Z75KASZp8xm%C>m*_ncRW;~`r{mRJOrBhA$vk! zr2|V_nIm60s_6ZYy?%ZP%hi&S>E@J@52{cQ;p|o;ZTr4T2PV;q0LJG801aS$7;H=7wB=ZlWRpbw}i>JQHa5D(!h#0ou z1V@Ta+Ygf62y*%VwF=9a}yxtu-qiPKB)3? zpMRj-o!&(+sQm$DK&@$Z$Z327rq97p^Vi8f@Y}jSP`1&J$c~XvT88b@;1%=K8`QM< zKDC{c?RvvUne7ejTX_pDB)JDv64w>hi2}M~yItT5m`9{#Rci@`))1x!U=6j*jK4r>;gOZRRq~Q!-d_89Zqj z%p4@W!L8ko?;rezr!j|Jmp?*H_lSLX$L78mltB$kS3_DF;4v+*n#O%{bnv$6Mi@l~ z4IC>)sGJ}uE^L}WemTTnbbx8dTti?rWx=hyZe4J$#3g)Nvx5e>WaS$TXCw#V-xuU; zcp(>opoyouQ;I!Sqqy`st8_#ZZ*mBk6q)^Xen{*p()_q^f(QX~x!t_Uj`E{$t$Hrd_Wc`_z+jZ`73I7g99X|{W7*xL6tsl>+Kw-dZ;olO6838Vv%Smp|=6IDzloWJ#GRr`sxF`pRvlc!eq9@z?|Xz*WOcl9JUa3IB4M`WMN!@^Sl4q?E zabghlVvK6^?|XkJ$T#SYy^6;cj2o3f`Itxk>r9Jqbx04ASPV)0<2syH$6eGe1vkv6-;>9orK2}xb)nt&C~R;pH^q7jB3T?={e z67lQme1p@G`O;zJIMQ0gNdEIRYumn!U*J&~B>0hl=W|28Pl70i>BY#p3H#y`RWMarUF6G8LWV?|n|#=&`7s@@Mo-0zT(VT+zPG;hVn(3@?;{>%Yk$4WR`5`xYVj=+YkM3{ z$wEQYuakTg&)EA6#r^ucD@u`YlQpeT*f4YN;+g+K|k3Z z92-F8Uz1<8Ou>W&Ng->NqG++6cMmr(4_W-Fo>hLem2qUA z`@Ovp-)!>p*v&OF-}n$q$;~5JlM?-I$l_qi_F$?|=-byVQ>mm!#W$L>R6ZCgR;+)) zkYAx+c6jx8z#>K9GoE3ly;U2X3DGUD+um>bpA>tQQ_IfKQB|yRbxDihiZxks(sdyL z;Wjuvz2}W(zivquk%NMEmeMu|v^aX$LGURFFS?wkI6*2D_Do?rt|~1Xf;p+Q(nNGmLug;z=`B+b ze>q%G#;kmIZ5!s=j>E|Fk_BrSxE_vt8i(80^A`edi@xHod)?nFtGklG?loSOf8_Q? zp~9l$)~9N@;yOQQgO@UfJn>Ze4+tAMZsy@-Eg+QF_G)b45wQj1yksUxRMBoO9cL^) zL_-{gkJXYW#OlBkyk`ek@CfhbA9cVKc7Up6KH(zu*j;}>$4Dp%Lt3or z@E#On@ZkGrRSx7D+!=X#^T?g;ICvv$(L@?gR^ZAG;uXuIfHchM80GS%0)aR!}*I~!6^=J1&mQO+R}CW zceLpF^KNj_l;%JptmhCe)#Vz8e5^`iB@@6zq_bDh*n|+kT97e>uEkQRQ<4 z^W7djIr*AT2JcjOL@^|~~md|LGG)jPbYwyE5qC`9fw9m;F*_yN+? zYYyJ;-ra-3FQRTX)PI>3GVEOPK_S#$Qe9DHkARwX30r)jv^>HW*`7Od2#eUh0M7)>I2}{JSt7$fA^0UX%Pa54I zYtxGHRtQOY;SE=(CGdB!K90K7Xnw3v=j~4BI)JwN+jzD=v=M#~*r_6Zdw{vZZl&yC zVB=_F>tGFX_ANbv8Iwik@rX6Xojnai}yxuH`IrXkwGH*>kfczZ9yp* zm;!CU@7I&$3in0-YbN;T{dmPLxkcc|3ei5X+pN3diABl)Q zRf06g?=Ra8c17{?Y!#LjUq0BYaHPEDq@RPD%wQQ_sk-Q!ptL4ou{Yk17NBCV2tzec zVHBe8q30bnu?@+5BqoI&H_2f#9A~1zLUNaV`ysW)%nH4!u00OiRHlRb#-k{Hgw$%f z`vRG`+@pIfqbdjtc9FD?$_iFGqx)Ey=rCD! z#_{c&Ccd#jrVlqixO=kCK6~=bYv+K#p228HIIMCG7Nj;Tz7^;c>Y2Zwwm}pRn9vSw z#0q!oC~!sHVA#_?SWY%8+PpWciG9asBzIvPRaC=b;H#fDY6`FDY%=b!SZfi8G%XZy zo=$b!3#e8n>wY^Ap<4g={1| zJgP7!OqXvw)`nQLqF&M`Pfn60VaQ7h#BXu1W;+Jx-Y&Km4UxZx=?(Yw5sSUNO+{>1 zYEpY#d6J2vmhK4RGkE(RLC!6lCzC^I-Yy@WX_eXf5$8v>r3FJjTDgK}| zvj}z5@|N|ST-WGK+HK_ryJcK?%i5*YX*BWoh3oVrr|Fi@Sm0;P^)i8r-cjHi(lB&S5g|WrX8j4K4o451)c1x0%W$bC z`~-v!DM>EnQOBe0$I|Le{CULD>{6BXH->KFrmDXPWRh6p@gL1IB504oRt1i7}yset^i0Oy~73L3;$k<&+631tz+J93i1 znc(y_EC@K@-|1`l*m@o@z#kj|KdjTg{9mC4p8ofmtcctlNeLxoCRxe95iTYMHvWIg zDe*DzeCq%8yElMzA7|bm1{!z9W9)Y?V*dLc#3_{|_>2EWdi@;$DHy=1H`^KJe*w;h ziv1nfX-K!f%V}+DE(Ze$>|095kS zck@Sy2So2G6yW>Sd3^B^h8ki3|1r=6<{#j|lQh!R@Xwr6&x7lvMUD{w{WAyrXu!Z< z0df2&I*z>6Fn?mfy0HOp??b92EAB7Vb!pl%W1~!0q+P@w?=dmLo+G3{w+^>Lf zAb5A|pR8Y!(0@HH$ozvkI`UzWt=*rmt82X>Dcc=0p#woVQPuS2T zSH|YJcr>4lMlXOa6vJ1*dUr)Ji@WMU`xOru4u8XnN^tV+m?h|qHD`RtC zj6DwD3OdCW`>DULQ(hUH=VEN@xfk9&0CqF5Qh`tVcB(65^InYooH{!`5Wpq?uuuI= zev}Ph-MZpf%DMpy%b9P3=Y^lz^hFF+$~%JE@oxx=lB3`M=^dQb<_aIh~7IaGtM{mjFW^*fo6t+W`(RzDeQB zTLR8^@jxJ|KVsDaWGEJ}Sv|EN|4~BkUdnJ*PZ9fDXEC$_{qqE9FBelr(J1Z40&6}I z&@ka2e87{2+<&12h{Vhc%xx}aE1cHyas!5}>8BynRQe+}MbLeagX5*GTVqh=d=7Nz z7r67S6H~dAPt4iD(bmBL=tLQF8%vP!X_Rz|zyIgOtt+M^e)Jt^9VIZAzy;Dmmj*b_=*lh#z7MyQF>%a4zDts671Kpe5Nqjfqs+pOgGTJr_y5;qVS6bHEoh%4e5SoVls`eTQwl<|DNNSR8?+KnkqGxau!wadiUO7@vNIw6y~{ zIGKYSDSkXEf(!r$%ZuB_CyxBW8ek0rSf#;O@f!bstje~QpwmyIzaX}fmmo^OfPi2G z&PL#i(zmAnKzwoQT$Yev%mLw#0EoafkS~Lml1LgjI{kIo_-k$IY)WVru-sKT=?fKu& znzMPnz)#r|pDrai?fqX~m!3^B1wQN5HZMi~x6)^3|HTq|Hfa#kk0Ah_IJPfkIqjY^ zSr^U^z}ZwU;L_i{dpY*cNr=wlpG_V?4_0@(gUj*Hq>nidd^Q3zBN(tJ@WJMiH675j zf72&t1EZdXaQ;zZu3x(p`lo=-=WBj8{3v+MRpGA&4^;nRNjV$y6I@c{5iW&37tQp1 zwa>=D1eX*}#4BL`6hrhpzRHa1-t_@euX>k0&5 zHrnU==&T(gxOxZ4b2;{TTj%rWXYJI$FZvt=E=T{pW#f6Sv&LfJEvXc|l54cxFnK{`yZW09 z{6l8%X#Q`C>%S@fTIer@m5IIWzsdf-5bD3n3{4CjoJ}2_{!Rb)Ws(0~Z)R!pA^$IG zq<>di+Bvv5{}=K9SlZsj`M;~t{(Wg@M?*U&GkeE>eo}NW=#S^$zgdire~=Q9mlZVn zSesPP#o5B%k>1$G(8)L>TY=8l|kY`hwyNnfchSYOxRi3Y(F^&pM zZt01jpCQz?_16rDON&FXpB7BV^lkU zc@P|w2E*k&1}_5F>>KqGtQs>51D3vmG!(Sr`PQbuCor&`kJn#6+yA@==>KC6B<;-X z|G5J}Y90<~rs(gs8P4n{O^FK8MfrjebV+Q~*=6}fg&H#2g#gOz3=_*H(sp3|Cs+da zJvw)g&oUgKflA>9%e(`B7<-7{ITI*0?9~B@|Bkx7UU(-p?E1WAzx~kV=6&_x^3ebN zq0`T30VE4^MykWG3kkz6y+Ur-9@tLGLuFVJm_iCKu|i@f(RW5ni(-k=6j~y}L$`;G z@=BZyxXBDX673+|6GdqkImfsu$4t`LAC$px(oor^261&^qK#RTJ>8T< zt5&BmnV&I;gAJoIM%+g{C6oe0Gh(tE1TfhNs|>N(B-dpP^3q-gk%RaulYsp6v2|Z~ znFs`GBB4BXiFAlThNVmdhBqAa$#n_ModbKOI+P%Q4yo~vuTXW0Lj+>NwD-pKKP($> z`#VoPSz{HVvIU%kWJ_=%RHEx#MLZizd3!f3wcBQe53&0XBdaJrS2dZHHCZ0K%2rU! z;4&xpDF{hhL55IOXLZlTS%W7o2dB`TSXhUrVz2x(p!~4Cm7UqIM+v({jUXoUueaHj%Hf)=a4O=;@Ow`}>Je0zEF4wt;UW<7T zzaWR<QfD_kZ?T;15R+-WAPI(~m-)fKyj^$`oK~RbrAkvP z)2MY9C`MCH{C=W#y>BP=(X$4JSf}f)|9B-HwJsZS=V{$mbq+PV~1ifv+ zrs;`f_&1xMEa8MVXeDEU<^(F#y^4vWwpw;+RFgk%$7y8d5fMsgA}UVU=I8JT9L(=F z=zgWBfH!Zg;;r)l-7ff?}o-Q zSw5E91@zu%*m50TC+&^1FpQIxV~i~s1kw`koM&N`vTqfZ@0L8+lYt@mAkKIpf3_334ABdXCKx-j_2}fSIhi~^&U!lX z>)5)o@OwMRD?w#X)o%EiqdJ<_5o&0$2c|8|Dt_TmquPu}00%$trB&PSb(fso#jXxA{JkBM)5!pw+-B3;sw zA)`xv({-876i>S047t0~sgLO#HwaBT+BSo3Eoj^G>WfJ382o#xe*)RBnfZDc(0A3n zgSIUW-2Mo5L)}oI?Bsrf_zt7`s9oC2-zW5kC{vPEPZq#0_%(O{(xlFhN|o z(XRNCI*4l{`s}#go&3W0v$|qTeUQ~yOAuEU%|tK$zPdkT-scwwGLh3VSg%oX#X`3m zN;Z@=p*OcZ9Ik|_#9dY$IEKZtJ&Zj&s>RjdVFylAh>!PLbOqrRK<1?aJV?M{e)?l& zGb+6hWJ=t9ye)MdXHfq82fm=7Yr~bAqaeY+TH*d1&i*>y{Od^ZPm;N)ZmQ#oqQA>R zpPSVy;pB!lO7U0b1&P_dQW_-9W8j=OgQJg><8z~bcCpKO(R@1iMo=(hJa-sB(vF2{_qf?yW z&o~M|rufQS#V$Gv*Ts<1!dm_7I9sz0qW!7}%PbugySxa?2v{6O22cTEfqq%;nY&@o zY4S{XrW_c8=<~UTkn;_;giWvf!IL6fSRI{VKt7qMh-~0p9rvkGq2;RndUsTGMm0=s z)NuP##?5mqrPHKws6F0ksUvAb+m($mwV9_zKG!zEjh2^!`Hk(N<%*hH`chZbZB+ef zpq4>*+)W3TWuTq>OD2XzG{tl#4lcF?H(7VgCKPBrrIg#p&AZ)=`^Lo5Rqa>)#qZ;U z%!8n3zhYlgn)kpTx$nh(@i|U9pE@^gBs#BinMoib1xs3v%WbA8HY4ZZur==_m13a# z?<+|R5Z9ZWzaWr#kevO7ZK!-eQo*#?a!3lX=ZJR5{#>`eq^P1N?Rd-KC~BPuScy|< z!lMJs&1Kcjc}R71>NGo|nwMGRNTsOd#T?ZXxN5&v*^~h(l8&JIvm%pn8gvH7RhF2B zvf?x1gu|njxWW?#)aocNu;V8k>j~BYq79BAMdK<(#iwS4DL~cSMu7ra4Ql!Ige2cw z7KCxltx_FAD-8&tVD#TEs*>4rrOLjGxP?t!DJn-x%&nuU)qYb-uk+1m?Z;2?OJTOl z3HP4$=_(=z{YAv30#c+l+7M0Wxj%z<&{;8B!HA)3vo*91a4GV0lu5-3YP^&69FoyG4_2fO#b5`2Rbyhadn_p1bN^j{kiu2}i4i#&zO1~CP*4>QU1 z>8oM#8nm5Jyao%$Lh!dIqT*$P;w6JZwb^W~-u@$X;P+qGy3SGFF<-1#(oWw{Ley^r zDuEFA`&Y$g5Fu*U8e{|!3W=ZFt-sK4NJwmjSY4#bVQ_x!fO_T;zcMI4BDjb9<8NW# z!j+YK!qw+iSHrbkU~};VF!RXfUQsU!re5F`iLyL9n=g!k_I|orK7(6cnpMc4Agga? z>(?@Jhhu#EK2ZFViB}tZWd#Md9fn~J?H-aVb_i(VfXJMhZ-K-4tSc0EZw&*XLv+uy z)u(=kP{tdiV~jS9%ilc6;#b?! zOU@2O|w ze(39d32UeO(hMv!eJJ73Tx-LPyiM$tol9?_H?P0h+v_APPIw=QMewes*z32wxtVW5 zN~C%qlMa8rfhHw6d~OY0-H~s(QtlA$!VuU$o2y4KjB~8HZ81u=5+rh!osY8G(+|$6F5FodfK~P~5{$x7} zv%+uv*wzs&Q{0pv#kE1Ci(`?v;qZ$&x2Qq%2A$fZ5i(8KkCocYT^Fo^xm05km*!6d z{){x#wSuFcPbPYLd{h7-1syDGR0isG*jWnJ8Zw`98l)|ib8&AXG>sl>AZvGLpbqub zu?6e9=Xn4S7o&3>e(P$qvuBk;Mdxc2=xzVHVckrBt9ii*t#rLfJXh zfb=PL?WM$Nlkrz6Pr8`*f?X#??4vSM-I|Q6gg<5xjFz)Lw-Df`jX}NY2J_jIaj=J7 zA?u|Hccuy#Vs_IXV=`6D!k}J1EK6V@{&)l+-b3FEOEbA+iadWrqFTrI6BRmC?RS<7Us)eVC0PEIJmXx@;&;M zq>|aPdcsJMsu}pRw=1WFZ%y_rR@Stw)>)L&R>SXG@oJbgA@n3m!z71-NMvLEe?*_F z373U);GBD=Vk8JS1=P=_9zIZ7t+U~=i39ICHtgTYpqu0$_L)+IM($S;4x%)rqKFX^ zm^@@XjD?&FjTy+=d|TrIe_A&i2lG0f-~`uS8I_bwpl`)sH67XzG6l}$mY~TD$wNuS zCq~m)ef<3mpzR{s)gkuMRaNZnZygsX^%xiNhvW3|;{WvBn@em{+`Z>j!P^~kkxz}Xk_$N|uhXR~DHAhEmWE+cBaC3p3jyw5*caaSOTX~s zVyyIHGr;nW>4j&u(CmCt<&^{5u5982QbJT{#MdeUGpUjlgGO#okHR7geB<-PsRMQh z^wfHnHccoCD@@0qCJzRmPWg27WOPsxSOG%nJC4iuFT^r)_^0~EJM^Vq%4b3j*(!tH z4@LY|@G+G=hAqVU>u)p5=d1{1c}*@725}J?TpDJ|1qCkmSXqH3D3kbH)U+;*79l7n zkn_h^N82>dqfXhL&4!lLK=*GHrX8n;-8z+N;T!OY$`q$S9d2&~GoSLfiSO&|C9Z-| zQ;lbx23~l3$LpqG^b39nsloOyqrFkl_7rz}n_CfXXxot|c+S*6v{lHg?{@u~!pob< zZDu($5>B#bM_HT;wrg-I_2nwRMpM?Q+yl9@TWtskXlsjbYY9)O$pzfj3?S5$tr9Mi z2A+6cl7D|BIZ)6JO6Y&UzyB5gQtHU zp`z4Il+n!bd@(-bCMQWL2!!JR7z0W0FaR-9oLX9;;*=P+((I$3BS!7oR&($8Y+uT< zPFUwHUltiI;Ppyf)_hNnW!_8Wa@^R32tS#wY`?T`ZU5%W@Ogi|is@E}mh(Osrt#(Q z)wuzsM^-Q;n{<$Xbg{2S-Svl{nD`QJ;v!>Ay@^4}*f~@RGv&FTL(o--3UeWCRY?td z8`X`uxxi0U6vF6t@lb;8Al7G;qqOc|tK|h*5#dsf0#_JDP#~zIVULWd^@gYfvoTFH z2DP!2@(h(k@hBj$RpWX>!yyb?B0mAB;L9aIEwE@5DjNRd(7)L9R1D$hX-0_k6o3fE zsHZ} zXO`hwnP(QeyE;@(!;&(d1vaugw*4Ts%8}Bzxfr<3JcPE0jG<$#TRdiF&XC3vEzbyq zVIhdD%rJ&yn4`xcBUSA>slHx?8+55CYjZ08CYP?jH%peHj5M9GV;Q#J&VuYwwI_vg zDbU_!rR#lfwmxiwlA`3!=37!sA{_gW`Xl07T>7L99&trSnjU@M5RMYTZ=H_?v}+Ik zDA*)BU_&Dg)kjy6;eB@eR%VK~d5QXo3nPH;ZVoewwwDw6{N(fmE!}W(w|MLFatr$1 z3lXY42I1}w=?)(-RGM6@*zj$hd7c-oL`kTh99v_4M#aX=M#JBJMCuf^2|?3rX;#Ku zO8S73hD06BQ>+6|6J|ORx0qnE2-L<~HmJ<9TnWWjr-HieZ7a27_b#Tp;3!s=nWi%- zSt3xz-fCH)3?HctL&sXQ8eGb#Z;|_GLe@}C#cEHzDsfYI-0~3CjVr5ds28Tm$(rF)G#Gn{(v>B8F5@WXq_S~=MWnG#zC2(S%a)eIwDE4+mhLb z`b)O$w4qc@NOKM)A5wM8sG|eq%Mu?i1T4yt< zXY?BqO$FyL-zCkjDT2x+jLL;KTS=G*6|P5o#qLL1;7-DiVTSQ^X+PKLbT+G2?U3J^ z_7%3;u3fc#+q*7tDAY3O z__T7E?V$=gO{i-L}|C8{cPP|V9 zs{ZP*K4;qRW#vGaWkb^U3Kr27d@Qi>mJi2AL(jG$N1bBFI`~iUL!G^1$W`r^?E)13 zTx@<~iB#On>Djs$F+P+aZ93!JY$ha}wi@N4Di0=F0 z`?UgfOLP-|;KmJf7jEW6{p{3_=?4nxl5zX|H==Th8exRQ?f$6~?b4VkgY6&oDK%Mq zW6mB>2gz{DyX_7EiWRB0shS<-{UXHI+>Pu{8%93OVdLB#jN6Cs>c?IQTMys-w>PE` zy%sB7*}^%eWE@+kVd9v?j)!>|b*5fFxjObHAA>V>oCmCp?)GB#s2%*%{;m56)BJI z4ixc&qJw3FQ;aBRL>H_>fI(5qCCnEPt?(CXpeh|^gg_9YbQcW;!8YxvLTCepY~*2^ zT_IdT%a4b#i9CZiYK%}ZRY_;b1~>s!9c9E(%POfHMZ^*8DmuN|)U-E={g!}wj*2~! zj_N&{ycbAb)DB=Xl0iNg2 z?JkpSDohk2B{atjNk!VYD{~1{$vBtG7naPuGnYLrp(|rVroJ&Nez!g@RB*Ot(_JHuYjP-L z#p67QX%N?z7tto!a}bcebqKCcv&agSk(mqdXcsd=>)fO*9+x>rJ#CwinOb7H4^2)# z=&Ez{g~{-u9dGz!Hk8A}#Ko=Pc?j}cGUMcg`R${EI8jXDVyzJy&7rm*8CV4nTc{Ol zMosdxC!1oi5%^^QaqPwH!CW0?(Vxy*v~C@6<+)Yb;d3V)Wsyvj&(P>Rv)c~FQVFOV z4I1CccLIrB4e}is@MXasH9R>~I^Fr39o#jFQZYI$g`b%t#7*<^xccQFSZ4lCRF3)@ z1zQ74QE6K5NiOKtG%;%vjpm`PPal9rNi8;CrkWLzLuzKE#A&JJ&xy(dJ|RhFi1t-I z>a0aOi#_77OMm*Hfy#4{3-=R=@l7k%_;`s6$xej9N4T9iYnpC@))@%T+z`wltra2~ zV9nE9eeW~GqTD8?`^xnr*+*KF%y8UuLP|w69T=R%k4z@0zCw|A@ZBM18x)l)Uda5c zQ*$degnbY8ggWqJtLF3&raRq!iXp>w)jI z>|B4;T1ft>K3x>`+w=8eWi}196fGMkthJ@h?|aXVjr)e)FEO_CF~bSVN@D)BP2ykS`g;&KK>YvIA`bs zRD`uZvc7W}s=nE3NqGihBJFTfH~Fp7$qailsYq`aea9mzCs*_WvFMNa7 z7?(f04rVsxFLqhkyVU;pGK-@hweN)K5b7gln)Ao~$7w*{4Fd~bA7hReO4RJBDOiUc z+hqlPkA9D|URYMd8QV@6~g%-{7t97+SbUL2kRMf3eyTl2mRbvk`|JgZnh^0v?#O<@2HM})j)Sj5x%w?WU1iLM9~hF_Hdi@5G7 zBHZE;*fIiU2uGZ~(i=#5Q2MnP?ADe;=8r!JkWvoMsMBf=6y#C+I@@n-*}0LE%mw=RP?e!BPffND3|!2`}xTMkNOKDva4@C0B-QL;JoKo zq|$5I%toOPgc{#J@?}R;kJ7e~)wiUN@2d$E}bO)KK{Qb_A(yI-#k4G*H)_ z+1C^2uCYZZ$tsY9X@E`uN8K7d=5rGQzYPCAqxfQy2pL>eejt`TGhu&&h})H+8Q@1$M=bs-}fcOxUg z-Y7r|A0zF;@Zj`O;lb}Vq?!h~Ytf1WzeD2?KpVn`2#xIi2xP5`_LH;~lSXHu$vLL8 z7$k1Au4uqsW~|~_#4T&e@-}jf$sSo%4&&2iki||OuX@%Pt_^gbaAUp@>1Ne+Jh8M; zh7z+oYvNZ!IeJ_v%xj05s#I~QRFPak(M~h2>aVOY9X3H)p2^YN)ek$y0znMP!Q)&8 zW|24x+lUad60p$C^OE-R;H_`XV(_kJV6(%Cm0!$e&r>`{Bi-*eSS~y4eYRYd(N4q| ziqvGWrCD6U@0O>0W=XkkPZ-?{GjStst)Xk>UwjoP=cZztUqff77~QmZuyAy?(brBC z^a^1vc=eIVU!KB7P4}{`IJQdWt^`QwREQrr8?Twh5|8VUpuy06DK;&XRyGc1E{p;k zH&mOw9_#n^p{&zmrHk5HBQ&ksFBaK8r0V{3ls=iE)Tzkc)uL-Yc|S%%T4__mTEbH{ z(dQFtU$*wI3_Q$fN-gE%im1@W+BgOFuV|TdTv_P(TBk1|`x@kxA zs1Z)PwVU!xZS{rpDo1HmvWCsFDOK{^c@2OzjCYLgm{ ziPUr8_juUQ#pZjZC!H=Ui@rMZ*QsNjRjF4}p=I!?*u&Uj*p;YeYaSTJI#x_`LC}1< zvPsAwW*NT{6C7thXOl)-)p&7rfu?A(9W`GA2O2`IoR!l&1rL_m5R+Nw9{WoI6W;h) z&G-R=dS$uHb7u}%R*3Dvn7HnetqHDYSuFx+(H2YB!_spoTt?F^g#nSqv!s3SrP;(N zyjUvnwgR!aY3X+Y^7Zk)qPNy~){>HmVflu3847zYN7aegbmd{_Hvj44y!oMq9L;pb zsa&eFnwfW&pRKnvJDB$r`z|yjQC>_1S9G{LDW@6X8~TkMeH9J|h(>yKT-Co|fU(x; zlbg>)E5FR@G1b>$;8?8vj}&0v7m&0J&2FaIF<10%mO4r&j{|XgSu{g3wVv@hT@ zN?(ATSE7Z2_ToH8F?3{!V-v-JYcn<{3HIfg3S3C4!!nB*%cIe|O z!i9O#luCXQ1_aznQE@{KJ?n8Kjv^CA{D#U>VU#H;Q)zo8P}kT_kEpVb{%PKm)A8ef zs9XKpzs0zEM^Iusb~+tAQNM-zNqP3?qe`;`e6t;2Z4eef0UXRLl4 zg&I-loZ^HwAt1VZGP3J~@MJ;tU=80$3e$~YHj(O8G%9bfCsMDdi*A`lUN$ba`}!by z$xf3h>Gm`MO--5;UhPo2>s2|nq%Wu~W)qhr@uQq|_4&+V%1*Bb3wK(uU);G^*t~&bbbqVWheMM}Hm+jp6#r0hTk1gnIKj2(n+i z0dmnmHNr5>Uwq;i<|kg+=iNP56SwC>M;^9%CJ+pS(>Jsgr#obx9es<|?g0DicUfCcU0c_F?MIlaJ@bwbevY>=q-&(DVFWWW&wc!ExdQ?eX8aiU=3Vl*5D$Ok zxBKVf?5DSb-?Cro-!{)Oz;0ioGz&eNX!-icYQ%MhFgpigT;3w|V41o#Yf@CqTv0Jw z*9Uai9QY@p*~fGjbqXrvJb4ISkp8M0;|58mtUubLc<}!XU;jDwlmE#4Y)sV{|BkRE zHSLes56c%rh>c#5B@~&Km6{rQKey4URt>yCMGg?2uc{M|0N!u6VFM=LXf=JmUuM;L zY-)cRX=~n7Hg9FWmZo<%)jfZ5YuiUedd!mMUGmW+y!Fm_xcdJ66@SoT=nE!d%gj|@ zJ3V}Btm`f_CZF4G8yvf-PW(+* z3qouu)Iz=t+{^A7bo;AXxEO#?a8Rfn0Y{=Dj)5R$=N6!Rrca0+3_%XcE&kc%FVQFoPoep$T6rO$k8nv~_;YYI z&_xM>RKzmL5`lRZM3=JuTAi5_`_9#vW=HZADEq)YfLMO09X z1X#sct$_pSn7zj*`MO35te`%xCM@mqc0y_b1?J$sRq2FLh!^b(CqrGo(JN`rewS+=Vxb|3BgCh;v|=hdQKTo%|79X%Yu4-T z5~)7y?t%?%%U~iDsGzl`oZ7ODtKFZjSejdMLG-*Rgmgv};t24CuSu+*yVN;8` zC^~%qJgSt`2bgtpuxkYa+d&URoZ>L#5>5*D`1zZDj!IvM2Bs?o#db=Sev-7K&0)=W zrT9XN)|mP-C{R^eGu0_^m+*$}kJ)G#m%J=Y)O$dxwGIbM0ODlbMFVe)77)d*d6zI&+bLA8>3{8S0ZRv=s+Mzx47FuIO>*d1qP;n3C zkpsya)Qc#?FBu6^V4~+zka4ukZ8AjQkinPgLB>t=PA6ze85Lk%ZhzhDVW^EqsHiQ6#WE{TGQ>4za(v8(^IAiZZVd_Bo~d zeaC1_Bi;CuY?`n#bdT85yKS4jk$=nWovUp#XQy;V|NGLA=CXg+Pz2kr(k}5A=a#PZ)ETRa_dg-&YsWi7&sqYZ zGP{ROJ-hrvTEe>>5Z)ay1Tst1G1%Y&HFSHt*gB?R)cw;qV8-yD8G8Cz(L@x`5&wiX0v1a^nb>hkOwdM7ryCckN3BSimhoGtK=F|eraH+tevvdx)nhH>AYtsUqmLRx6ii*QH${;( zCf;-)Tx@o972@1noJm;p21*UO;Knq=6f8Z}T7q_Upu4Of)jcKUupR`fh3bxwf}b{g zkp)^m9|XW%x0kDfsL37{>IG0K*p4QAjL~n%*Z~?q-@@qsfd;(e&I1*qN!BsVo`~S! z%gKOp(U>{*1~}`uVua;%L~_t_^2fuxgzoV@$y#_k2b?OKhtZaV%c$t=K0?j#Gu$>Z zl?C=YnR3g;ugW0MTXbr=Op~NW3dzOSj0GXHZ1)+K{2O3+h2wxQS}-&(TR}{9hu6_wnqt3#Q^EhEFzHZ)#jP2JI%QeCX>+cqTXolAH za^6KCa*7*&?1f>j)1zBx`*aNp{kHWC+xp3+f}v!Na*r9CGXmGVP?slaB(u0(k%s1( zS{(rnIDg5%DSZkKEPMT}jmzUA&IL&_n~HIFhigSyjL__S|Iie&7+8kQw_8DVQC5(g z98F%}$#ZOZ-v}#MVl`JxhHP>3k$w7gW(!!?ddSyu5+c4VP!Y(XCe0qs_8hP1$>V=< zgGY*Xb(5-fIX09P(hMPxPq*5@Q!}QzRCmJ;wsXI0p}>f;o=`bShp~i7P)tA_^P)VL zmW{F;iY3H@Q;kJOUBc)w7OYAKz^fqEJic+?DT43U;MU`G>(+#e&@?=(CePdS~bC+kQw|V z=`zH>;%g(o8oxGIS*~UP9fz}^EGEH?1t_b;;lX65U}46I{|9Y|^9K8M0!0o+1J@?} zZ%(mlqHj)_khSzi0+I7r8lUzb-*(y~r`$=!orPDx?4M6-M)x!ZgJqyyP!;0fqFg}W2p7~=F$gk>=x+CAE9d) zh}=yc=jix;4G{zCZ_rhCwwH*bRrf<&x3a_zET#Z>Xx^9 zT4OfBDl2s8XhFyy71f;vcNdWtdUKOLjmT`*=O4uJ@NXnuY0~`G@*OclN3?#0_JcS< z_J|+E$@~X#MhTGqB94^Z>=QoU44tbLdznj$=R@t6hh0!d>ha}yK}sG0q}a)C_oisr z?^Jgt@k!b9DFGDIx~}BwN2YCp8Ox1h_qbBx;opar`0K(!NDggyF?FWaSZYnl)`sF~^C~H`(Ay*GhbD&9*v>Je?w_q=4z$u-0$DywVbd zLB=^Vw$76+a8`&4nvKpS3q5TB4=hd!D>> zijQdALn|KPmamb_KMiDg0O{&9pTWjC{(s_Qu^^)>-kHT zOqM02X&h+{2Xwy_Zd#LxbH9Inip{5O^mTeF(7DVgjA5aoS6|BHcFP&&eaPfx|EO$y zU-8)rF;5|3AL8MdC8qjkS=0jIoL@e;#AI;e&65z$ko_LcgBw|%t82!q%Gg*R>f@N!g-(DszyZj${g-Rm91dhw>H z9>Gfh-ek4*Gc>&ytf*Uce!lh_p$AG@YvJx>E8ZWaLDRF=i}@laYpTlpeD7sp`lPGW zidrzD?4%WA#ph_P;_Phlj!t-jG{z_o7wR&_`T(5%OvI_L5fC6T>J??J?)ut4rGdI# zU1PE4PGNy&bL2ZTr_LlRDO3Bj<*clWoOOmX!d+tx6~!BhgV%H8KI-KTGwRrNS|~AZ zA)9TJY^u!WVN)u-463xvY_(-%@iMF&xth#knRypoFeqhW4W0Li*-KUPsB`AtP+FaI znC%5Hyk(*t{l!FV981hBGXQnwWHU&SkpibJ3@uA1Pc`;A6nhS2M7Ton#^VJ7*hVPf zU4!F7_5~D}oX|jFASaKE&#BNd;{InB;P9bCI2R)3kU}{y{*V0 zG8I&Jr^&ncUYjg_FP3RqG{5Gpznc)nXd_Lg+FtxKxooIX)l8MOf|T%GtNbQywbJ-D zUF4x7@pxZNjCECC>}zZM>`&3$2_xlC-=y&^YnM{`>?V&@IOvR9e@$_+mJLfP{4$rz z)Dng{A6Ccbjt=B(I_>K}4@%TY!|gKmg zSkMoyHVd-Muc%eK?i&~G(VZT6dVNhLuM9hQ-~A>*wjSr>1qYm3n7hE`{ko75Uqp{b zj5<(^kVa6qY>{Zp_1Y)z;Ug$w;zyD#O9G{L-m2_t>R%*?APR7f@PYJ*h!oU{5G2Wt z@lwU9bG$5X_&fB3q&FiT3Rdap?H!!E^$jMc=;w>+S{f;duoYfcZS4i)=5B$_7F!hV zf*@N_Jc5w+rJP|uiK-H{Un{p913qFVF@Kz6uLXA>DbjOxQir<&4?~Sx!R)x%FM<2J zlg7>3dsBn^NsF-mXo{u6)3-m-oE|dNWUTy#cxyr*5~uks-6M>BQ~<1jQ8P)Woe7&V zVxX_@BJb;nak(~HqN+9-+2z5&0#QE$5io)HXf2-r>}8!nFL+;f*wkABhFc=cTSD|X z!q@ao#Wlv2E(Wy`uh6;L0&7r=#Sn+yBUe{ie7TutR}#LhK7ti2xG=qF>JZOP&F?Ys z{g}X`uMI%U)E8ms>fzv3Y1ng;nF9gKx|@E!l|zjAKK^5b4MzBS=C7`p+<)zgQU1qP zjE1SBv8mJlV)p9VZfMKco5s@Fb+L@_2DG0=SYhKBmqrwzM_R#}EH@s7>dpu)&Z3Lr z=wi(hXGc;S$SgD1sB9Br;b2$_AINQqAm-L8f36iW_(PCy@{CSA^F2?K$)b0)ZEZke^&kRdX>8{!<3Sm$AnC72D^BCl>Pu)_z zQ|zzJw3P^y9QwE<12u;L*!=M~(I4Y)TS+&@*!*!fH2<7{t1S;lTE(?&1fv4IK-0<7L=v75c737=JpxK0^M=~*RS0@Z zUw6@s!1;HOx^MSm20ZeS2RwetM%)XLfVlao(dmyS*b#j~=o?-}_(te1{TL3;YGc|* zAtv5uNuxT3TbuwbZ4vGIQCJ{f5O7vapJ~aln>YGp>e1dyuW0n+=WyB^yraUPe_-Wo)@1?A@Hf9}g@c3%?NCkr=5^|km5X@{|bh3uYOU1()7H#3dVr`Z+Otz0G>gF6mG7Lq|w3-x{Yx+QNO$kV(f{leqPn1!|)*3?aw*uE*4> zw~J!DxolSDvToS1Tab;|Y)4gz^g=SH_m#UU;v0@NTID1SV zi!@dhXOipD?UR!M)doa4^Wo3_Y{16>#!Y&h#njJeYGH5DW}+=iVNS)&<{Yc&*Im&Zj#u%OVRFGvxn&y7dB4C^-G zC<_%8X--|P2C2o%%~}b2A3c;}B)f3n7e90RJrb>3|B_9Hw#zaT-_@RImP?mbK*rqg zFmlCzeUdR+vT_c;|4B%$FWR%nKNZl9Wqj3cEWD8=B)yRMJ93fj`p`;I_Dt;5{P9|5 zw(fUgJ(C*2#7m@Sqmo+SOmyPU)&|36q1BaRwrgbiZ3tFqZuL!6Rn0BeX*d!8?Mc+5 z`dX0 zRh~@>O&RKA5`ftj{E4?q{81qJSkVa665lWqp!+S6UF9l+uh)l)+ks}uL>7xh&oOqN zG(_G}T|Ei?|7>eO)}d7uEY!A~I=*_o0jBg`PPqe4?P;LttZ?VS4OctDG(zC~wyQkgF`&p)s>c~kN;;n;k zVu&gw(MlBUOSlX7^yXhZzJmM9C$c)QTZu7gq=4w1_?|vrylB&|Znas7DG%#ct8Bw< zL0!0}y>6bDHQXk6O-yskblidecYof(`~*kZd+d9y>_Ph4%;{Www&#|uX?mHSUSuh( z1E_uDbD#KLM!i0( zyNA0KD(WPe-Bg?Gm9Hl<7*|>RbW{#sv>qU9tq|R_+JkwYglytS6a15)VZ(Ojd$@~n znC2&KbC#jgh^(7wF?g!n^b4ZeB;SVo(n%romMXh2&@3OnFJvM-Mx&jRe!5RyW$PQu zGJOB?#yaTFKeNL|bqa@IC@?UZk304L|GU!vK4wAjpV=-e!}5=t`~H14JxTq{32hnh zUPb4zEHqU6qYfH*kaA#1gXR`C`4-G(p5rFKXjyP(NmrUiTVzYsO?}AnSt`BDA|n{w z0@^a6E1r#rE_TUmtUcQl#yld_ld$GpYHZOhT0sl~;W>{|H#$;+-Q{-@Kg^*e!Jj;a*wn6qAowkp#PD zw1pVtf~{`aK?E9R@+AhzV%v|pYY%ZV`I3Q_|Kfdiq&1PvZ~@UdI%)W@(8`Zt;T2+u zc0ycWVcLGF1_7E0VIV%14LLUIehXm^tl%ITQG+2zAR-U85V(BM^$$X7F>q`IL);;u z79^07hfwOXGqg64DUwzW?w6*Z8Te@64M4-t8{Zs!w%?sV9~uPF`w~pZ0Q(ES_l2Gh zZRp_}_RzzPGZw!9S7ge-c?bt!s3H{+RFVn{dhlr*val2+P`n~(eSE|n^tG|&v22iirf4|_PIW-qNDKuNOGV_6VqmHiQ zJN(y+%Sv9w&H1~@Ul=`@^I1!pHXCE_9rr5QUmM7x!hbtjVYkWf3|kSq0ew$@9#Vw&qnGwAaK*4 zU+9JowG3*EaB_~zhe06I94-|`xt$)`|2wvoUfdX zJP#dM#A?1Mqs{jRz?=4rVWDb4(#`{2=CkH*MXQ&QR+~)4>6p`}(;)ld5$KAe{H1H6 z1D8;khQn`}gL$b0hD{bBf&-&mPG{Ssg(RZwMgZWb}w zTuIn$n3WCmI{(1Cn&*aVvs5|B!npj2tDFV{+5bb>I|No5bxot)vD2|_+qP}nwv&#N z6LoAmIZ4O1ZQHh;+wb@D4(@j+&t#9D$*#SsYE_w}E+Y{Cb8lcw&n~GZR@ix1XT0V5&&k;X{2xkf)=@{?*VG;;Nc7FqbKrvxtf;Q_ z%Kh|$oNToxDvt~q5;GQ4u8*#?#ECUmo~Amn>Tew$0_V#eKj|6_!EXlK z6aaKnQ1Ds~16qBDYAQ)qb+74fKy_Q8D?n@wTqIOUy@vJvB0>u>NZC&JVGF6`C)K%q z6@`qbhqD0z?4nan-7J*u%j#S^Q-@`xE$UdR(&c`l#|#k;X}7cnc04cSU?9FVlf6H? zf3{lh6sjUIFjjZN-Ihj_Y7U+a0@Qx9be&1M=vv{D#rE=zuekNIuq&(`Fi|+gvR*j! zT-Tgn?fb;FhumS}aX6|zZwOyM#;>m=oay%kn(;muNl`?|xzRSgYBwBsBH!xM0>LPE zGbNLGbqm02pYzsaF=QnDL*7FR;mg-8F{YmAc6W6=O|i1A`;nhuo^exVx}!J!e;Iu_ z(1X`P63uzMdgW%>uzum-pI|TT@?EvXqHpwwv_x_aFA5^2#BK%2`{EcBE&5W$;knf!&l_S$K(Q5jH!M{{mhLqN4osJ^!0N!_6=6se& zs*wJ=vE3M&T3|NLagSS5UXu09fX>HyVnb=nm{omd#-}ZZAR|g8aVG82B8W;!f83jvgWEWFX%a;eJwf017fVq zZA893aA24Q80)(-P|VZ>CoyV*0aNXGU2p%j04tDi9_juM$|3$+D98N2p3Z0|f z$)i7isq(3skGJBt_PX>UIvOH7C3S-ua7o7+v7FABuc9%$tTFu3r#^9Y)SPpt*`e$C z$mjaA`?>SE%i->!6j30IRW(u@d|L|i(}XxpQg$w_h-K6;VN}$-fN|7#Ptma|C>)g+ zX!tj%6!k;B_Zk&f`NjwQFV#z8kO%6AR&OaFtsp{I?0|~c04W)uNx2_T_nS6^mQ<@~ zlvocPt8OGIlonPDU8~M<#5jRgRZBKyP*n?c#5m)h$KE)M7RF5JKoE@;vI3=OJ1`W} zF%KdbfmXODa1hGW2%7z79X1^dj}u%(Rv3umo(I;CkhDh(Ifmq9__ILP7(w-)YN>5& z>XVsf>;9*lj<+pMBK77(8Q(8QPA^65;!w8Q(771YUia`fq=6xUMtwO$-B4Ra8mY4?Ut#j@`YlY-{_8k z{JR&vVr0mrVuZ-S7(GXA(Dp+Tjea8^fb2{@}Ns{KT<$_hcd?z=b3}JUifmv`sVK?^)BD`wzqwS2h z$+*fOUace{tKc38aySX-BF*oG=<`WqC}+%J6Q)Hn#SvuR5O-((ZagNH^;iDk zg}eJ%NK^dE3zo__1;lyU-6NGVDDm)?x_mp+w7fkMTbP7*P)ABDMcN83+&k9{1+!&X z)m;&J#w_yvVUHB<;l?L2tVd>OozMM|oA%h(zY_Zz5C z)s)$kZjT@hN88v*aTC)o_z)4d>QGqp<(i^dg2L8DHnzq^wx|jWdY47o>PkK3<`Y%_ zQK&QBi)J4q4>^x%WsP(}8^4i5g8ECCm_S!Mm;s1>5~kE`Hr&}a&`iC~uRs5cJ@!tI zmenhHN7i=d_EiRp3$<-s`Bdc;jAp#bffr#z-Ufaiozu%#daI{41AUD7^`kOvC66KfLX!lOFypl}#(IUQS06~PJOWaXL}XAB5tha%@ed*CzgYu4JilNh z8Xy9aw#*(91q1G8g^6Z!!;GhXqq88rBSVW7BuBDgC6dRRURVo)7rUSzCrZuO){f41 zn%|ZUG=_+PLeQXOMnqdjM{{ylU08Pxp=in)S@0~%qf4p3lW-&Z*-jjU0`rR@-$1nu z`h>_MUGYL8!hFnT2=HW8TT%1)WMFIZJ8Bbdn$jDo8TZr7NEJOVhzoded{*<7oWMXa zD6IRFX$!*g1hDPkhco&~^7*62na@$Bkuv6(n0awy|M@2yI+CoQ-?_?{;QOs zI`*OlI&D;!lYSr!@)#pQE9HQRXDq+=)4c_A9TRAGFA6yW(sx;?0?8K!I)C;H1)VR% zEhMck`K>_x4fCx);|8Zk7U*WNBpY(QiQEOZaS`p1l@HQVnWz(vC)-Tuo+Nwb1p&JLc=v4tJC)hKGlZ{EI zT_xRJK%QXmu80bfkEl*kX?C&&Sp}YjcWfzmnk0Yk`%j|6oV!vlI0Yi2J*3q`RUx@-YV)%wRCl7m4T z!le-CnmJ$ZZ(|=zwS6Wu<+`8Y@UnkVN=QOZ;rm=ykn@aD6lx<&R|Zsog*!j+hGHN9 zzx5${RA+@bv7ZV{4iSnxyaw!Dy*XhyWhhK?*jSZ0NJkaA@i|Ypw9W=mPlXSpgz%&T zjTnE53F9NoMyw(9Zd$kSg&W=gPp>$&b$B8F?B~y}KG;N>=%xCkwmMQU$O47JEG1G- z1OrbRJk#wxM+I}zA~8n2>Aw#LZk)qvTcq%x5k{;UY96vnc4cE@4;nG+OHvcZ07Tv4 zIB+J5+zQnjhy^^0vR%co%oE&iu=d4TK;QPR*B)=>t{yI)*lBx_c>bK?xcbN1s3D#B z_%4;>5*_o&h6!r<3F-A#4A|xPqJAw#K${rqm3Bn@2> zbowxMOE(<44%dG<5U%;80$5`A9Uwoi2m?G4y4&STYVYcHtl=e+ZPsP*%CY2xgr>#qh>Y7}!O{$-ev~Pg&@7dai<)X9e=EZN!b-Rbw zAIgv8c8>x~p9W?R9onD*&7I6~Dg(Dz)c2ib`o~y`p zC)(49I<2(K@>iQ+Zw)>YI{2$e;!o%~F@nAq?C{;O+J>?UE=Q=xoHk-RIyD=rEfGJa zd@Zgh)h}EyZiTX2xhf9HhG@lK>1=@3pZ5lzfa`vTyAIp*JX#Ok*=|Foi%4o&o!a-h z4{`YavZrY8dm%G#R%`Q$x*L*C5zF(E3o;fXhS z;)(4+ZJKTM=z6P1G}j1r*hLD*L{^D+Tg?n+1Bi2+F~={;=JzO_mTih;t?Donlas@#-WA-!-ID=z9&zq;QQ6Cf46h%q4C%MoTsb{2`lClpQ(Sp96Qvg(Qj>)qmL zqRZl^P{r3oGFed*ZWyzE?^uQ2E!Wfe+kf3?;ywueV=T#d^ltV0XDac-{qNYwe~14k zEaQKVFtS!IuK#0p2n`*T_fuK;M@-lcDJao+ z(}WIE(8P33Scr{^LA+wu+CA+Cx~5_}N?Fm0yr!9oD(zHsyGDDrUV8%pn@5}C?)RJV)_)A-b(YUH@8c>-TrWTww;7~{duCs7B`^YX9rq;z)WBm02f=qf zkO$YZC-8dx)`cf_#c3hdVC7bZC#P=TiYKRbU&H-lE!N`Fb1L@u@}(0mpk|+qN56SL z&b?zd1QLTYK3to^xppE_sg80XikquuBNC)jlPD_LS-O)JJBw1dFsn`)p~kUL%D>v( z7;K4?33pOHdOix)%qgCBiJJ)@gU1PC>Cli?`(RC73(T1j!fw^J(L$vXfvaL{TAr#w zM*cLR%6=6_TIu}o7^2lS_+p)~5r&Hin+U^xu(+;87Tq9zkdFT2hsMa>IQ_>jjkX$` zOf#n#Sb-rq`isQG=Y4C8w||?%;ZBjTkiT4Zk!)Re^K3s+p)v52tAz6!Yw*x4OA2Wp0)n-$ zf+YW!L{R((!sRqr$AQq` z>C~j@o|S{>`dyU5Pn-GUXs6Azy=cm_3JXju>5k|PI{GPAreI$9qkNU}#}2qpEVi+e zBH(MUBcndmOlOVf9P9PL+gaF@VMMPDJrI6qZ~jpGTm0HoUXcUBM6|e%$K-9b&cumu z>Xc=C+#)4;nmSYKDqBfkiNARdxazDJWU%}17bh&K9IWIb(U{j%QCnA5GcZ`(m{WAwMJ8{|a139gNYu8sV+1add9N*4n&i<9h+WA7 zadVfna-oKU`OXr$+#59t7e;MlxjpBgG|^%p*rk4(W{k+nmb6TyPwU}WA%&Hya*x8;>CGksG$mdLjNfNJB)5DKdm2kM1=3l{w6jN~8!}lelGF zS;vV`E=es7JS>Px_c~SbjxbZBB*p3Mv`*t&wfe%D->PbIVB|<7Q0|vS7PP=d z`8uRurN1@WC~o5tL=vaUCupv}h*;Aw%Cw_Vu`EoZU23A7S zL~3>u(Hngf?`qAT%W7c3B9-|%U}#zt-$92S2eG!lXr(`f!%h1-GAWUSy9wLB4Roed}lL8=!#>xBL!)G21+j z?XPk~cSj>l#DAlK67{Jbnz0*0f0>tp8Yh<#ul4OlvuW!arqnlv=ZY12d|nW2dIxo4 z24%R``_`y1-ld;RjHLSdte*rRZLwdaE9AH;!HLW zWFHBJTDT3Y1db+^c*n9a-G7BnUIG1O`44C)YL>zTq8eQFcNJ^nHR^qI!5n6vB`l zVEWY+KU3XF8TBX&Dx!|9hzB3x_M*;@;BJm^Nlhe+Q&W+AcKK<(Fn+idOE4-=rEdEZ zdmRxqq2mq$gLwYzk4qcB(aZ8h=<4Mqg1{!+w9=s-%Ixtru|=XZnt^ZF0?4@||0T2C zWKT-`QOlkdEt<`HWNxfv_7;?c0;9pAJx6+NW z7^(imj^^LgMH#Xqk6vfZqfKft2UicvYX#QkD=pT#=LIpwI6CS4NJD670;?-V3wCc3`^@{w|9wiMD+_)D_lC{G0|TglA`T$BRVXobt@n=P2rPAIS37fx%}Vw^M}0Zo3!-QH zvn=}Mbc?4GHMb3aRVN@nkW$u?3Y8SM@=3i6zC$aGMFydAr%Ndk=ME&M>hK!3!s~hS)%L`Vubb5hxL;=GpR@SVA;Nh;;;-@ zPN2}svHa~S&DUbD-!y`+thGI-MOhIUI^*{5TV)m+cdau_Z}J*N8cG+>#G|}Br87s% zRV(Oy87sek<*HJ>v#D!z#u$2mbql6W@)hG4r8Z@q%kg-2E`(Ms7$60p8ykbz8WU$3 zGY>_uFbT=-I#2_&QX{Nb$0Q1+8D)};swpY#EDX!jBF$|7B5gJN`WK2aW82arK1{Gr zWM!1M#@4KpeiX%u36y=3hlfc2^UPG^hPn1ihNoQ=p0@7s%WD$+Gfhy$s&=PUdbRe;hj z>Y=SY&GJ0bFSB+j)}((FX`K)1+~{}6uV5Hed+mculsP-1H(fp7UpT}a9%)tmaYG4_ zYs<`%trkyKsfG6RL9356=1$15tzW=a$2)dK2e_d$|KPQf8mx?~4m&B9N@X-IaE!w2 zAeK);PNQcx&Tm0oy!eZeYPGa*&Yix*nz6)+y|hx3g(Z)#+*-B-Rm`|m^2h$!#g>}y zlUkylF?;q2M#sI{D}f@&{*jzyX-E@Y@l(r<)?9+B*kTnG-IA7OxwFfBuyo?HZ^*OaI(2F> zEEBcLPpUrIcxWA6g-ZuQCI`|3jz4J}EGf;#fi0m_hw8vz>vPEJomNVnLJO_3Yr_p8 z#ftCeaF;%CW8QO=Hk+3;Nfb%Un0@W#J$$AYogt1C`wv~LOWqUkd?mSj2}X)jINms^@)5~qNh0kG{E9b>yGxPcPy_@4zJI@?@yM&s5BD&J+xypps7zXXPDa_ zT0^A9ERB9Y+Mb&&lEaSrtvR;lx?D|DrlB1N!lYYA{@L?9jVBI&Nj9PI7oWqQ!ZlCt zn1$YitOXZkK;jySw6Cz4fLPOu$C`_6(JQVG0h5SfHj!gT4nAL4i_gP6W#s*Hi=K~s zie0Ty5gF_&xnWrSwYb3;(7gHthdyI{Ht8!2gaC6cH6t75ZPH zfp#i5YN-D9P_`?yRA81gbeM!yMEP=g)-u|curmN<0BO*JSeq1j9qVYxD8%~PoWPEU zo4AAp?j@&+1b5R+EsNbSBKQ6ar0d5&-qO_-cY1TvR(NIVLFDS+EOf{<&G&5U|8@Ny zZrS&<2L)G=Igub7a@7l$tOV?@N($DB_h_+kJ^yIZ>geVklA;vyc%nVIaAp zcN+!&ASAIh0I!Y7>qMo@w^VTC1!j!|S(P*i{HYm4uWY3BpS!Tt27)GQg~aB$mY zR9Gx9-DNAm%}Np!sEUiS#^Qsv%XL3v2f3??4>vk=m0OF=wz{%$yH%0_&{fLPG^J|x z2d#!DL!fXM$cKa&QPM>HGg(t3++>UKQ`Dz4Ve$nTZZ6!VXd_Kzg(uG3GO&l%VpGXj z9W(%aKXSOLhRkG{A?-XjjD8ZgqrL)_P`gMc(tz4tIFBIK#M;x()Ng~D# zf-pVm>GR0x2X5Dl)G|pHTvr6S zBY0k-mzm!L46I{=6L(c`TX-@wj^9==rJ(#lYZSZMJ>x8erptT1XYAx%+3gKHbT1__ zK6j@Jr8O=)$|7JO7V?Hp{6nrk^TZpqE6QKs9k3^UmH&y2U4#1!{Lnir_2VWSg zAM8~qRC{~P+MOJ^H^(7mwgW9#$Q-f%fPYsZG2ibtR~#$F9xI@cD*7xP5G z38BEV?m#$W88F}575qKva)QYh^ISLnvm=xGNw$9x=HqZlBhoVBo3K#eyjs2HuX^6q zV;EBUm#+5IRx`I)1bz<3MQPhP;$I$)=m;lsiF1;Go^Y^B62J%3&o8jem!zCsiv>#l zzcwI5I6@=VApU*ob|A}k>I@0&3T<)S-%lu+H}9JdS8}oKpOfZ@Wke@LeLW{}T=#RZ zNi&mcGyT2~WrN%>?-%cx9JB`S|HYEgol!Rp{qy59{kQ8^|7r92KRDoEXJ=;rKl!m3 zb-jO4NSOZe*lkvIrxI^ORp201Go-~<076tSQoGuWCc&Cw!lg^|dHYpUk-AgHtrLQt z*;@b)oA2!lp4z2wh$cTtt3a4zJ!owGD_qWvNB{CqmW;Sg`o^~zL9%`0lcW< zG!QLrjBr>Cj;D+sTysH;VSN#Vz3>eo@ds_Fh&U-u=)*70(nGZJBWe9kSgDM}`|zfw zy8TL6*h6NhOjIUlrDhv_GR$zYqm(3*GptEz<|o+F2TMtAWOkH?$qyTM8711KIE!AD z6{#8_YryKFWf*g+Y&IFPs)^3_&NFD0D%ekztHdz!g%IB9V0RFTY8G7lwa5#diJNL% zhJ`4xD(^QfFTeI%r=lQ**AtJz-CD3N(9z~{djSdK!;wFT{auGX`8keP=PSPA4ChN) z5RV@-g2eouWSIezJ{=xi1%$LfSK(zf%4J|v?LW!0FDk}IZ2HXR8Nxc!dVk2o54JGA~*tR+n) zhB`#x?mI!aC$_0jqgCk|T54#pJ*Lzk%Pg$nFEWm!l9tD&biig5msP^$2MLm8ySGY!&PUG)q7;Xm<8H+${$>u~*-8txvY z2Z7q!Mt89lYP8%6#Cg4w(Dn|d8TrHC#!O%nW-yiqDfuRl_4*vWH2wSeoB3wNLe)cK`bHL=)&?z)cBw3J6Y+^nwY7B2akP44LTmNxfL0Tc zvJc=kBm8y^WhgjhMcs|N@Q)eysnf5IY`h+P$p^iYelOWTBG^B%8?Ugb2ZRBL^Y~7lAT8r=c1*2N-qD*> z8kFgNOIw0hC^V`(a$XUmrNXtV4|U@Zm(wS>*W(sndPO^4@dv?DJ<+`>;~b#=_;zQ5 zP5WG6)dc&AUTi?q*C3&VqrIx{TBna_+x#0o4<%JX=V1;dKE9f#DAVU;`2w5_L@CDINh;CcXsDNCd9Ua%Q4wSbefN2HiT!@aNC~C*?JZxDG4o0dhjyo>Rik)55~| z^G~5V{p0O2PxNFy*I1(f&q@2>FP2DCvAZMOr_wHw=e-F9OP`1nV`_BVE#YI5*qZI& zUxmWI4Nm^9{bhaYo^}1QCmGDfrC08537%B#hmrcgPTF))9LZ#1yZJ>IrE?Mi&OZD2 z%Z_x|^2_IxYDsjQ9D!9oM4&8EAo8U90NX7rF;_d&a57`=8E~sj#Uv1Z6SY34}y^EOK*Bb0`+xl09fKdtLle$!dzcH+{kC@sX0rZ??&1$%lyw zZ?L*De#q0OUFl>9_J~~153Qx$K3&&aKHhh)1Ox#ffe0Pv{rUv>H@iXvPp>y+i2M8} z`n;EeEc(3XgIo+b_j_av`cHdk4Em3IYy#?e{fGihueAUBfX1ba+WP)ve`zMSGcg_*woh@td zC;YUDa6fF;2lsSWAQ8L+amB8ktd%DuBx+f&I{2ax4_Y)aPTYgg@)n@~~)Y+0~kwCcxvmVTuOo52|S_3)dMhoiH znmIFaV@!j6=^Sfqld19Vn<#Rtd?WB2#iV7MynLuPMcc86^`r$|Y>(89Y(BR!$<&Dy zojf+wPa4xzHSBS7Ww*=xZV63w1(DW=Su;lErU2ObB>6?wPzdGI$PrayHoQ{>ttO*Y z+14oVj(v2O&=V>asWnl2M+nI4sqYv0B!dd8L<m#8QH38SxB6W*D5NoHQ9N< zj51kn7~Z=?tRiemQ*@SnAI8_4*WQ#lvuQpi?|dY1K$YEuXY7oHC2UY$xB1Pp4v<9> zdjmtgR}K^#dx>tvGCu3rp_fraftUmmuT#tx&~lKej36lnrfvxNW&A-+oRLj89K#WP zqd)%v)}pJAT=>DHpW&z$XLiwm-@KU(q^ZYq_1t(WB#WYFTI8%+zm?jujR(lp${|m_ zIls|pek1Bg(Crd1!@xEluoR9KG38T8eRaAxnGCV3pvTj6&o+Qswek@6^X!bKS)BHo zC}a%eCqQml_dR^S(=1&2J*P3dRxpqBx8N2j~|lYD-{It@J1I;+aO7N_Rgt zKu%eI27Ew=G21NDRO`Y?iu&~dEfL%|7)BUusDHVp>ytY}ts}h2@t&CdN!ijSk1u?^ zk7T)Kie-u|9>b8q5j-A8lg%0QD_;AW_>A)U377q_rb(ShBu=go-`UyHK=iW|9DiMt z{t*(W8c@_0ARP6^(p1)M$TN7Q956`#$Z??&Fzj@vP_fOEbyY%LKEzw<#4BY?9s5iy zkK~MZo0Ff`BL!&B=_4>4y{|!S8_HkmU(j}5xe@B36^QwTuL=MVW7*uvERB%SoQ8w- zS2k=vSf$<=%(J9&QhSSDqpgYcb%#v`;s#~or!8l-uBL9ix zYS3$Y1y@kRAl87bw)n6v|4j_5mKCNkQJ_CzRLB{u?u2f)C)J?RA;BB9xrd7YcqRTR zac?V5hJ!Xtih~$-8$zPPmw~6m$NG&5LE29*Y}l)@EjS5??#|wwKxYYDdJWut! zQZamop12NVszFqU3*8k>D>`2BazXIlP{LBKaJELY(Dzv-%CZMF-L0BGoa8L#VJzsh(P(ctrc@LwRSTNwtH)rslg~63n!(+WG_p z_3p-g5>J;N)G=#rz|l%X;rRlZ**&EfTW$na+cXzQgsUUaX!p=U?hTW{jyj6kIz-u!hFk}7X#d$if7mC(ZbW&8cF8z<3zrvM;b=ZjXS>~VBm=- z2(X+$7LDQDgom+_3fcA+aFJJt;4TV|g_t6djL;j~m`2^`o;YI!g>YVFbQ2NYq>RU^ z62AEI15%88a{t3Vr3P3(Ec^?7IEDZ3V3O|tA10;#HKH21{;z7$Yz-UNe`5XD)kfk3 zX?n;nVG#MApTwqNAyCS8_`gXD5a54Ci;|$Xrnf?)kh{#MLqi*@f#o&=UWl>5m1NaK z6%)$JW193ni545*K9;NbH3%y8^eXi#zqQ}8c`Wdu3!BWCd~(~TyN>mh{lR2QwzW*L(@nGb*ZR})8gEefvHXK%DOrs;4743GDOrf z+Ja8msF_7A`rO-u8eO%&2B9QVCzXB0rkX})(YdTsjVpD{G8^nt_sC!E!%;b8YDL;y z#}u~q#09SY5MK;+p1AB2%5q$ZC<6HGafSclgco}%zVSte;KWJZ!fzZ76`r{7XSQs{ z4A+du4A-v5kSOCO(<}5jnyAL=|Jf639dokcAsV!Ly~>1Yb%Nm8X4}x5Lt-FoQyBnwBtVSFVB>E#Ci&_?8(y^uMm$b=*{*^@1c!mQ{03pi} zqCg`12Qx09IORd3H)kv3uqn0ISc1zP=uc}Bqd`{7=ndtEIiQk8Meq$vE=OJxU z(t+b{m^#ElFbpfv2%$xm;Z@#x#o&+98vMOw>afK?-<|OKizd@OObva-6zqeg<;aL` z;-~{uY@xtaUAYTdGGrx+ha1{+meD=B`4QQeNQ%X#^qk@PFEA*xpKrfr^Mpe47@uUz z9>Jw8qR@`X#b5=yC>(uBk=BLQR#ba&uJ|lHTyl)nV#z6g_b!_3S7chJcoB&a>4aRr zkP9KSmsU!+Y<5*}WECGB90}_59d&j#^~T9YvLyFqWUnZva&BfR(2a(mntgLJUA#Z3yckn^NtX^))LZ?i$mGHIU*JYyIO zmZWy;G(phQ2TFN(HNsb>tM19Nr(4ofdNPP65QQQ`>cJ@;6iIS#(U=H817;yaa zcvt5YzXA_aD7pKbS3PPI`OHhaCp;NNlR1n`rR*Z3Z=<^ILyEQ}=G%s%#ug+dvBh_d zp;OJW8Y^FKQXR4YNto57S`#u(GY$>+eNbGNM7t*bP235Odw_f+n$TTwn;QG#hB|?8 ze%Eam4UPpY{K8C?@+bf3Z<@$F@qEtM0;(i8xxKnmxIf6wKW?F=2TIF+2{Z`o$ahun z=Z$_*v;x`VCdOJ-0QqcxDOgCWnaOgywZGb4-?;;pZCQ^r;P2$OH?D|y|)I1l$LK!qK3KV+UqkJ-xZaQ;s}xN{ZGynx^DkBGNrUr0K= zo1W2c(4X&GVA;|ruB38`#l$C#T40-eQF-C0QtN15cg=iait4lsQq@IX$TpWZIA{j> zNxh{|(m3d*Ba^+!in=j*c8eE5Gb6f7$*dJ|Wx^ z+uU;Y?SVm*KS!lr{$3^zmR>#-dXJc`Nqc<%C4qon2a!_~m(A^YQGwQguYlAa-_PHc z!FzhipiY8h{RB)r?2&-jb4YbvpklwPkQ^ASn2qXoF%{N^!4P?42Mj=_G4KzV?U95% z=;=~*g|qqE{}LGCrpuhG$wa-7R$Vv5(;S-kW9SyEP}JL%*Te3JasR*|T&h<5e1ef$ zlN<6DmL2=L2S?N$>gIH>wG>Lg&Fen|5sNxj0P~H%0nQo$-*b z6wzi4jyoX3ZQPSNt6CU|i;k?+MTzhze%?6=@LGnBR)&_WNrs-V>}>l>ZG{$nRkKry z7sdvOea&l}925t&8(UwY-aFUWt*Wov8ltlJX)@=C<@^5i1LL(rGMX?K!wc!O0}1?j zYm}7L5!@}t(d@RBeexK`ieG_>Ux&pL`%6H)zG5VdA|-JMyYD_<^F@hV-MF=kEYuBH z;;k#TF7Bj;9$E#X&lE^bmDO)gF1CBRz*hCDI?Pm19kn>!Pp5D;_knVD<6es3pfRRg zMoUG#u3G9G8eKul;`B&oqM3N5aA*ENVTLU>XJ?f@vRRXKG<~AkR{LADAu+-Zj(nin z49CWmM_~*PxJ~$M4Jma>O4OXMbs;LaF;#6wp)jV$IEYs>V2}F?;;NWmbUnBLM?&n+ zvM`i_3IU2vU0WuSm?2C3Wzy!Rr6I8zs1a9{W|pXa zI_H9=qnlQ(qD6lutMrr`Y-jyc|4lBd+=wQD_Gq)*Wdievt6pK`&Q#Iodqdbd&-c~z z@HDqi-r>R)-2qA0EKx+GY)tam_gShdQAJ!q*^SU(+--&{@>UVjCqj9^yQ4U6U;BcJ zZw@-*j>&AQTb{loK^cZB4b~13p_PYW26!qi*G25qPuTY|*i*H@*E*-y|H@*Pv?fDllI#YB0;6@;+sPx2u46b z!4XL^f=SjH{(|qH$Yo?qmpbm7RJR+nD_-$FuKpJrF$id9R<&xh*RgBdT&uDhtnReE z+*+;PtgyQr>)QVQPERKV?e(je?)R8_o#NX5&VGKM@|jA184I80i{qV8mAUWv7NtbW zh~PzfC591&tJ}}R3%}sB9aiG$G8y)`^c;-6UcCk7(XZbRcmJ4(-Cn!(;n`~3=i}LG z-bZx*n2i-!y$!?*Xeys&XB#RRv$Y1w#nhMIva|J;=(4lTmXNP5m}X`etKetetu4rA zW|*mw$6btANEtNF%8cA4Qb0 zyEUVkKs=2^uNS{A4^j?Wz^;Di65(}=ct1VUoPi!*85>WQ3;yUh_@e=QaM9dTCxb2AW((e^TP>A`84X6;y zM|!RW!g}`Q|F%a8AlbtTubT%r?_B(FmhsoH1bzLYH&pCm2 zT`Csd)QHFp{>8QCp5jvF>N-$ldubJ!M4{2xb-=SG%0Y2bA6Ujcv*u;k14r8abz2b8 zjdCj&u1%Wa$5~?N!WQm+ey<0kuR(bQXlhT0Ps5LJ7cE0*LvC+#O%*_P1^Yip3mmJR7cdxYjYQV=y+da(o+8rv|gX(?eW@jOPP?WQhcIR^_% zdHGE#BtI@?Zfj@QIxG)5^7~jBdwcnPw{lG;AK^-&n0Rx;ZQB&?GWrP5j(|AXlk&`e zEz{pOzC?2scP`Azn`nJ7{V5cO5%Gg5oTw`9f z+~T{UoA^-8hty~}0O01@rrxPypi(SwpCarxBeGLdc!s7|BT~`_85RS45)}`V?4eem za54;LzXQ{glMophv$J6qQ}MlP*%Z1SSV??hXvbPLoX^t9uI{3Scxf7=4-_#Q7*V0g z(5YN$sd9Py*^0}X(p^TfwYXSi%)Of1OKNns@d5L%uhkV=YH9^qM+%M)7h_|qXvr?r z71p|H^~V~M*#>%4*)d=8?f?oqHM?ZH%;VM)N>5*U5=-Gp;qEU-&bHu&3xyVB9aoJR zm@XRh81ghP{?r{uERuWQ@f0f6H{xnnOZsb+VC&2?UphBst>q1M1risV$;80npz&+K z{mG6MQLtVcbi*=QOo)fl$sP1KZz89SJ}DMLdjW(;gc%p3C*k3;cyL>vVIPjd3rVEg zmt(@Ek>9R5C37%2Hn>H}tc&eUn$E6`J+Qrc5LjhZVWRx6ZlJ!awySt+dFIH*`mV8w zZP{UG&Gs=quS;c0RKkz6U>Gj^p`~voOi|Q9*4=)|gzjt7hirBfM>PeGcZCA(-1*O5y=pptbMt}X>jUT0)XH&!#H?d9ixjvi+k`+0 z*;HtoGX|3bI4mpMmB3+dGus}xg+qkqr)@L1+)TcXX}M{#dR-wt{Fzpom1!DdN~Gof zOBfXfHimym6!X>Hf%$ikq!-R+6Z=r&fH@2Vnc~W*Av72ep@5+GR?c5bpG*d%E5QGU zv3CjwXHbs`L&1nx4WR4_L|#y*dQ zT_ca`l7UszMuuKa&#A2={+wK^tfIF&s5bDnp2vl03VF<3qXt?Ddc>}TzY-ZvWgGasfrthffc4qceXjPGizzf2zhSPq?8&r zI|o+|;k}G-MoV2ZM&V?)jNKDvsB8BoM@5S?jlx(?nQ_bNV#|nQaM(E&^H=w3PTSbT z6Yw5TFe0w2i7-~us0=(59{e-#Gd*Lg-_waVIvrj>csDQ zi=%rq7HyA>z(giFRFECxi7kfxEx*3q`cP$DiF4>?exWD3l_YVK!$Fx0nSU0YrHok7 z-XCqB*3WBQ7y!bCpJmNmN%4fJpREDCEqfEte3Yaz9JuLoH7MU7cuCibp%p(MY6?th zcoJ9?Luq+g$pU2w(GTz5+(|C`67i<=_C05?rP#n4e0-=|n~-jgT3A~BFjZuYJo}n9 zJ*<7#RJs6c)I8Vy$f#@td%3$#z_Q%$ny`njr`-J&{RGlPrb_yZKi~;ylf_irj^A;D zGA7+Fc1i_WMEHzI-8-z&Oi;yy0TMK>-*Cjh+tD4?3rTYOX%Nj~lDS3dZzAv`3 zhNw_z9aa~M6Hp5_;@cSi{Bv!hvl*aICA!OFaXn&`yikkFX#aGs!xBh!KzoD z>44wLXf2pF4|@d87~K%XdL#w>1AH@VgzdsU{|ODp;Dha&LCz@+ttj9wl!Crq(Sk8G zCVmcgzcA=b3v%J0OZC(T6jN7dh+mRb%}LAbKr%I1$1AMubr?y*=uS9o$kF9uB304l z?~n+nv*EkC6q9MxZe=~vdFEwn@IPC_tyGqoR27j3$gX>L!bZQR>t)kgeBT9gt5Lpo zKXfqV3Fu}h!9`}YA{D*L@)5V>1SKGoQsvY#4EX{TLy!yTa`35g^b2K3mU=72i@Boe z0ct8+#TCPx^-!R5P_D{k6Mi=?=)F6pz>%bWTdKb~jd+!HcwBRs0yIX>ELsK9ttvmn zdklt$jko1u`U~$iP*c6AS~a40&g&?51iLWu4^8!1$R6od$6S@-Z(tH2A}9n zntoMD3v=4lsYwGcA9XGP_!l1dSmYqhMvWc9Z5!d?U2V7W-`JPwdw=qKe>s zb^+z-a=>|lv)@wTyGQ%Iasb_N0o?&M88I%O>}4DV+v=ltM;%eA?sJ;;xz?fA#A50U zp(N{P``ds1%lyIM8M{Zx7Iocob{L2mg|?;Bp4mgsj?^8Rc}-$9f1;lD2rxaMU3;+n zL>zd|xts#N@#1hhS?J@eu_|<7bd&Waf08u*&9AKylnpLN6eslnKW&-wq8z>{}>ysjH-r_fQvy&?e%rRQX(1 zD((HB&@Y<1LQxLawGL6J-1)VaPgE+iC)%}8i?}HmK6j_I&BfH4eWW!Vm~|=bHIGzE z=6<=EM>vE;VDx>~%c(urTyF@jZuSKm6Z(wAE`|>%;Gf&}U&NjnD+Pc$UuFRwS=i4BjXy!{p5ffP>w$EA?1@!PbENat$R z^2b}b>AACOkMYYIk`#E2HauBOJl9sBk?x%+y86ANAmh6HRUlxkT7JgQc5x zc{&5c_SVDClKR3XIZ5NBP5QOw1N8pJWh@8>O?m2nWyLxe{gjC5Rqs(%F9JB(bw!jj za67#a@Cr-b-RR?Vr25IM8HyVo%@*oAOJzLet&Ouue6OxvT!<1Ly@kA~S2pC??-V%p zq$b0s4NNLF96=#vp6cj62*6b%A4K|-im}DjWQFruR2a;+`)v}RD_2^bkrT5v3lcZG zG@_K=qmu7jBV!|*Q|YMu1RwMxn~@CFT`eaXxNbFYkQiD-Gyu|4U`E9wt}uUa0o0G4 z8K$b1q18Jtr|=l0L-{Q8W2T^#AqAHv<*EdmnsHRkSMs{@p=}OtTHMRA;mW z&QN3AF%w^&%t%&%d=+Dv!xerE@^0r5*iP+Xm6F~e8b93cG27H<8~M$hynkF5dZVIj z*xzcdhhyK~uItk(@6j^IS-YSgX<|+0lk5=II72UWOjb|A4u8iiph<^Y2gn}wz+hcyP2xv5VHCr! z=*kR+R6ndM-BUoZq-!8MAQ+&)1&%wh{y>sW|h-n zkhM=Grb-pw(4oPUIq^t^s-^nsKBn+s0|Nc%n#R9MyKj5deTWj2!EBK`EB48nd$^gN zDFZ@Hv_>M=tD3t8^N8r;NCv8s-N)&;_+PGH(Td?@;#reK+h4;_C%`M2V-q?89w=)0 zMAiNcu*c?^)swZ=Eu}M6?aQg62QfA%)4J zkN|!SI1PdRZ;R@`F-?VR4VB#O{->Z+k?O{;V;RzqxAbZZlk-j|KK!yjy;hoO-TXo>bPAx4>|_W%jzorHpYiIHq1MnrUY zh5#Q%T1GDDgbda9m!QE$n??>1W7eIN2QajoLp}huq9>tz(xNA){`G}I2@)1G9!@6w zQJ7yr`>Anr3XVk8#C6$e5i~@PL#MGgGt}keDx|szof?{FVMmSYx^SzI!Vqp95ud*13iY14;tSY82o&MlO>!HYTI;*%?Y=q5^H3J9 zpL(K}rj8q7eXEtpN+0RgNm-X&mSt^G$&19)6=!AL$Jtrjo@xw*XoYJVTU(e%JzG;- zp6~6hPwEi|;{?NL+H$md6Puq_=nB3f;LNkqt5M#*~^TWnw=)K%jK`yJp<^uQ^G1jn42N9 zo0dM(K?dC=#KlXNl>8mSW-9I?MjRN$si(<30uGUF%X-DH@9v8EvQgCCyC#pvP*CKKZ$k4);z z_0uXvM>3Hy9sS&iIc=K?1t@DP=q1a~=29h)r7Tpd0Gq2+Jz^8kR-)8svX&Wx)6u#S zR2M+6kSWal(v3UIYF#mfR8D};H)B|mD2sH8r$j&c3ua=?^(jG`+4AFz6tWcKE3;8m z<~UZUZM(+Ra|$a>nMJIfj69~rP9n*g?n>Di-PD^4Y5idfvot;!%j1n}vaMhfbSQjX z1b^y-z9!lqX*=?K*FL|;)DfLmx3T>y8}=EGnUm4lk^54tQMzhiQ9eFbHJK7^ zklCs~gh-PGe;^qWtbW_ClJ(+>-W2MZn7r$NrB#HoQ-x9lynBx{G0F#eM@h&lWGW7< z@DRY)@%0L>Ss@y3Wfy+s>;>MRDLDeO6s|>{`ub?8ei>#+5W0(xaozp1OK-r3U*9eY zlt5PA1@{Xc5C_tgTgWig$I|V9M3PkpGo8iR}e?~jXx3>N;pBWUGQYyT4#d-0ty zW(cMG2x`q8;h| z8XBE!?A5y+rNAceLE9N^olRGVOq@?{8zU}*Nc@1HZ}k4ym_-c-+|o{e&#i-d;SoG8 zO2&%~?tXf^%%dMT%msX5_a*j7@6E}Z_w|ujU7PdJEL9M&Y=&Enz@e~m`S4licyZa1 zaLXv9*hh`eK^_v_iS-$+%FFPa<+#8c;=u{FHk~&-nO8&>vJ?6(!~V(7{wdD>`4o>; zjdEl+f&9X(y7^47=}XS|+hng=bDPhf*a`e115h3E!&_^A5@z@nJnER}!YvwRJCw;S z80JbW(6XPL6ji#91-Q?(CAjc646+nHjB61TtjVuh;)27f*O_ypWBQjTCJArm9k_eO ztQ6E)QR*2eksi`tVMao8NLU|!bs^3wH-HB->+KkOodF>63YR{J*Boc%ozlW_a*=56 z{`o&hxyXAB+$_IrBLtZL+s=df-_jXdL+Ag}J;D^f-No}MCNOxx@X<`VmB{10zH zs-MW*j2;exNXS4i6gVN+|Iy?)9x7{6`UDSR6ay=#-LpFNSVy z%HgZ?Lmsp>B?X9UW55*5y)9)d7FGEb&Gz!(h;HVY@r^A9dvA@*c5`HWB$ah|eb~qg z0iJ}OL{TbUNwk0hz)@z2B$eH6%$RMmvQA@$C(Adf+$@W^~Q~%yz^OlRu zYu>L7oEcHk^IPozawbF%4FJ_G`d21r{>6>5P~6j@uKyWql(<~yatU5Kj<{i{T+7d3 z%wGWVYTTJCfAaelXf80a?&Xh-)dc)?%l2qzbUX}ApA1olBW1({Y^HlOyJOo^EPU#6 z_WOimAJJFO%RD&iU#;JK=ZoGckUmSD_OQqzf~69vjm3t)Ct`#dpUhlgmxyoEmcb1A zJ3ZHYp-Yy!@nIoOLRmNC{RCa#fV!PQG z#@;27F2uRM&e3n}8qCS^v9Zyy&f?nSdV8G9Ae><}vG+V+9WuiDks+=-GkUxCtplJM zgQ5&F?#Xn|FJ35`=oY*Z@d)wv96t%DE|4QN4MR2IBk7J!{4MjkaHgz)O85O<898{6 zHCH(CH8ei54o6a*-&>J*JuQrh-VrXyxnq*Pgr|h(s7E_{t>oA4XUaCG3hV=sNw#b; zf}4XgIX}=dq)Cb)e;(YS%K4}8JO;z$J;_Z$IiFNbO1va#v=HN|gt@055WS!zWvfTe z2bDiea8WMFERioPT|XCza$&*3ztuRdwVcS6D1X38(Ed035i8*|0G7{56D=>GpfsX% zRlfl%BSv4~NLQzo411Ro2`e!(XqBx;tn8CqtoKLlf;63o3_24AsX{4pKr|#O#wn;0 zCvGyE5R4QrP!f*J3?Z*jyGp+zi<=EI_^X;$xgL*Q;yz{z3B}^z?E63YRIY>?}1dxnii&=O{9FoK2TDW zAjHM6wIReACjaXNikBVnJ!gtFrTs}PYRG*xSAsVu zyHFnT>OXwGi-qC;pvEGSkdy-7T8Qf#Xa?d3NCCbrnv+e@EkwD-7T98+E&>{v@$V(J zQK*0u4Z+cD{MS|W*^#Ud1Ur8kjuGGO8LC?h4~oUupIb~q{cYUq!at9SB??rtzSWYc zBp+r-D2I;PJAPR0FO!>no#;MIVt9u&PLlepFtAmhe!RJy z;;2q2Rb{@>d}0=E*h72x5PXY%d;?O39qwF}LVa^pJ`pX4df=0RIf%ix6yQCGQG*K& zuyWt<$D&FP`x=$P6PSF}Cil{kD<`q?^cM5!BmYa0; zwzvOtOPk?0l zVvM0_e9n23$);7mrfp21@~{I2k(n*X#(QzY$wqyLi!eE`WwMu;e%*8;dNsr1D^azZ zqVc`??-*G4?Q*om*af^ah{X+PgqLh_jW`ztV^`W^52`eaBylBBLvdCPH%K(IdC#4i ztL7~c{97?1>;)|-u889-%A9};gW^P<7X|8V)3NnHBXs=3rlDt?>#sL<{>r+f@bVd!*WYK6TM(ekn8V#R)?n=>9d2=UY22cOsqdXp()&!_@;o;$Y_AVE50P)6tx;9ATvWB({p@^m zadEGcW9@$8^^%dn$>=I}4m-{LqB;GXb(Mjs^R?12;|G0y7eMtI2mR+#{niF0*;HQ` zMP{-;nMx}?2$l2J18jS@7Zckp0m#;6ml~#X$xqj1*BYjC%g>eVRt9YQsJ8?A6&Y;% zptlQV^Q5_*})tSmiym=Hz0m^LW$|Ciz#%O@4bp)Ka zmKAJVkCqmGm1o<J0Jh<+0s-EG;?%_w^XEwxFjsQWZY`t4(&>bVX!Ci4u z@gF2ZSw^?uK7E`BMwZEXEd9&BjHs*fpfmUJhE&%rsT(bhxk%ZD$k7dGq-b0-@!3YV zfHU2xKu5O(itb?}GIbEN4}-35`lvJ-3lLyS8HH@z`0XOt+0eu-z-7^t8 z`$M*Mz_xW^zP-V(c?mE_)-2PUG?jrl^sgWRKL)p|puUE;Jy74me;&{x9ruu|?Dh<- zT=XeF*MlbH?Drfpcl%kg*-(8h`du=w`e9z9AXWA2AUV^#Q1c;IdOv6`huvvDv0|!> z?eM)$`*lc~z0b#0dRpm*4FjND=#nJS zHpcW&10>P4hIb*MXiV)ulH2T9y)OGJcDYe?z<6Euyl-)7I&m+wUjI}${|oX8E#eKw zLG_8y%`p_uF~rXaSfJtR+jR#erQZpn&EE>5%{%T_Rli-SoekPCytieXa7Fw4Yfa;Y z>l5_nZ=3Q3r`Ol_>A#wl9jzd}imbU{IVH{l?+V+H8vIj8Ya6vD`-&dcW<2LsN)+%w zmIXU;12;O9zbuVIpYXa=Sb5;C^Fp3@<3i!)bXaSfwN12}JGE4soU1pm#G#l669GQ# zS_U{QLfUvlS15Ma3swzCt($19M08;#^Hg!EY8ABLfk(s5v%PwejSnC1sJH&&WsoY+ z!||#}E5(j8Y%=#U71AvQMdla7jdo|d#nL{@r6dmy5Acf`G>ny-2nBgj0rbuFO@$~Y zOc2r!W5}A+(oHG`nU%~t240cRm=`LLLFqqRRVK(KG1iRa-p{Ej8aLLs8#<8S)XX}! zXJgK$wJF4w5qw`v88cp^X{;H9`g^G@8X_aBL(OzAk##oL->l2k6T8SLmLq5aMNK3P zO~C>D9CdtbM1$jOq6SiB(#$PEUzSuT>Z#>y*6JBzTZv9o(?jutZWl!tfl$Lz7xl@^ z)XTsS3n^!5UPertw96(6_}+UQapdzAdBh-$6@#axm61VP=))^vt+JT71p|edefM%y za2rc!J52BBsmaxnBn%R(ku5sqrg)TP)R888$Bt4Ns-pc}-)4y<>jHCXMsgfYNlZ%x zwwfuO7E!*Y!H$k4Rryso3%kX9vF$0r$ou-pGQZttsQ7w}{>^l75Q8X$kJM#V+49N@ zYwN-tWkU&ICT~(IQ{u5NdGgp^Su(fshL|jcd*Uiz*%+}Obm>L|Mn#(q)7Md+s_&wZk_pVUS zwvVFAuPmTpCU5BPEP>&S%+`Yg0GxsH)`42c?)B+P+ALrQLDdR*xa3v93f6B#&?hRc-=r6^53#6zLJ zV~rBC2Jqb)DVRun@t8dS_EMdNpycq#+YrU_FkV@O-}KcjTn4VgO0?yR#U79 znVwa5H;;q9KXo786`s(!%vrDwlzGaVX8;ceTD*iVir%8ACxoa@=RSp#c*XfkL#-*D46fQ`6HMD?Sq3BQ&UCmXB@@4z|;xLnSFf=o?}HyZ3i4 z@A1tAM1z$^4)5{B7Qr*)JUYxs;VqF$juWQA2`ebE2*<`J|1m98!CTM{UA^}#YT=rd zF9Dpn9It~$XWA0FZ0*qeEKN2#y}jR?GD)%41Df?%{)@_1bT#lekLc0D=Q@1!v`}UltPRaUUcHxuVI! zsD-Z3EJCZ+7(xUEQq=c$b=AabE;V8bgSJXDJJ4+& z5!T}}{wPB+<0yeugbowdK?lxzXA9>OMa|yFjk( z#!5QlG#Otl3qSEtb9J5gV|9k@cIw?n3kFeQ@!oFtNcF zNnGk?i+ysG&9fs&eA+ezVtU3D8VeAAgKcCf9B6RYNth@$Pn%KSFm}+aM;qWs32ybz~6<3UlMR z&J8I{y|1n#d;S7YG%q=={tUKLW5(f zii$-;VS>A0FmqBExoWi7Gg0)vw;57=zlO68W{(KSVVwInus3-456**5OziKWQeE!F ztZ^m|M|}O1;s4{OInMvaBTl?gETVtj} z8X~SeSoYq3P3(iG+l&h728>bxL2~(MA_J(%2E^6CLK6VYqzYcl*_PZ?`Hprn!FL9D zIU`IlS!NZFcCv;VuuUUOS*Ht3N%fO%8S~|YZMAa&=Nsl3p>$^GOSL3NKL=_fZz+an zc%ZUm87MPlW~Cvw~e z@i#fB8f1^pb-V=b2;EJG0;cV4i`Tne1(zZ8UtommOr^`x>stkEt%oYZGIGHVNU5@%<=<&2*N_Zo zf|eeGm{LS5$iu$)+N3@(>xPzmANxW^rP6yiirB|bZt#a`6GkSIj~+$<bRRQ7SD>jFW{*=PM^t=WI&Mx*7Vt0fgT8L*gy(QrcX$e zJA}_9rmkt`uOCIJFHZ4g5X3q!F$^~F(6`KXPw5HXWyza{cQ*^n38GZ?j`Tyq znmC>N_X88Jd`=Eph>QQ&gQS^HI}a~6Oa(Z}jOv`%lMY$Y+c{e$fmwFSyYukgJ5UMc z>!b{SP)dwF+W8rhc@f)KL2V$+Jg3k}ZtTyYKsVQ%sXj?jq>Nl6^WzPm-8`e}MKG5& z5Ryd~o%jV%O*49WBeh*J%0J?D6|9@w)vBRg5^K0?60e$O zpl8dJUVLlPL2%ykD}TiGqT6;C^iIK7&vn#Y!rujxT!?eGoWQD8- zSoDgPq=?z5_{|BMA%yWAmq}c9cqz^F;l5tckKfPcujH0RH!Vu>8BHhSOws=L;GgnX zN)`dC9QyFnZC+#}oF^MM=Gb*dplusE;mG~q9tFo7`1{~tS8R!_RP+GI@hi#^;11ro ztpGT;Fd8=?Yt(4^$Xqn6!q|?i5Dvqb>aVP>=I)D##sX)!SG4$zVl5ra z1(|_jc*;9uLgZU;_Zzw`3px7E1hu|_IcecNj-RXxCK6j7%* zLbX`3lQA|rAgq6YT9C+V==Qh_cb>K%mB;ahHAyxy=nTXdqpnB(^g|Ev41h*e@xx^) zX}0rV!?wRE^Iau=_R^qZd0CJ6$(UNqXb<=`OW)Uz6vo3eLjyU8t<(WEMXWc>;rdCs zTQWM=1XQ;1d~=&g_9rQvziHw&`G+E;<^Eb_a`|A>H=dDwyriM#U-xH%K9}h3H9bx9 z+Nwk=^b7bZEu6O)oX=2AXk6P^9vf2tg|B1n1lA2`+iepjgNQ;_Q_shNcDg3;kASh5 z259mIXx?qmpTt5NQt3+ub0-|28I9@*(;@s#d0(VczyTI^2&bEZ!oF1)Ud!1ZYJbc^d=QcK9E- z_T??Rk92H_qIjb2NDfH>B(zSLnVZ4sHf6eEK*LX+Q7!3|z z1(YenXUq!M&I;EZg`1c;0&TOU;~;^S8&N7cV?<;^8Y9xzFbW8)u1$2*Mh z1Ucvvdd(cW&R&H5&CpL3=TE>0;gs^rv;}rZ4R3eG(@m7vJ(CAyhsqICs4&XWj>Q-) zBhuwA2t$`dDgv0WT1u0UtD95-QZped6C-}26iycsMo)Y^Ajms(c`YMaqC85~cVb|# zPe5l#$64Eull8XONLMHYQ?}Ywxs=N@qthN^8RHp<mo8!X

      R*zTZPpKlg4_;e@$QE9*;*rWrZiw?T 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

      oV5(C#lB+9e!O1_r66u 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�*Vt#(TN+u-gKF1{V1BLesvA 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 ?X_VpT710^WAR!xUhC&(%uq@2L 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

      wG&1( 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

      G2Lj9vU@{dFmJE`RS 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 diff --git a/xdocs/lib/xerces-1.4.4.jar b/xdocs/lib/xerces-1.4.4.jar deleted file mode 100644 index 99ee39d5be4f9700474691d8a5ed0a5058e27f7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1812019 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 Pf49Xp>5j8ZPX!_ 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 z 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 `#y8-tu>Ub2akq)XtEt~hMrp&9H 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

      Z700 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

      )7(qTlxh@$}w|-z@y*;CDNI3-G%azqJB-aRn9X zc+k2(W64e^;*9+b@JaZB6~VTVCJfO|bQIspv>!YccelZQu$I)Q@QW~aTMwjU0X}msx zuGS~g4f-Tnq+das^s8x?KA9fZucfE;>*yK%dODy_r4RHQ=~I0g9n)vhxB4vM*Jleu zpNrp3BBjq04fXk=xxPTOLs>_Cq3EnH65WvRp)VFa^_xXseJOs+#Q8`E>9>l(`fXx3 z@+0-z#VCD+7^mMQ#_KD^75XZ1y}njV*Y6f{^mSsczDwM!KP1-ckBCidGowE$o=5r; z$`0sz#GCrl;;{aVIHvzgQT4q_p1x11qradO=`Sg5^!-X_{bi+xen9Di>vQ#2lp*@7 z$|(IcWs+W9tfP3|*1@lq{s7nDG{}4RFy@o@v4sSs(j{Q6Vw^v~&hL!~BDUxOUscMr z7LSiyCBRQ*mYv zHP75c9WwK%Yi2&3f%MGGBI=8>ewmwTNM;EQ&)h;IkdDsWO5;#AK65)=o4JE-$lOUc zBAt=Bi*7>Mg3KD)fHpU0*3*v6h8oj-FgxA!4W^s91~A{SXIXd2Nv<}-n8TsW>1)JW z!KpKNT2b^@IZ0)_+uJi3&(2^ypzndzr*Pq4Od(pv6yA*~tRns{U^Ao40L;}u@@Fmp z?_)59GDFGATu22OV1&#?)Fd;4T4Y92E2M2Q7gI-+b;*pOUYW6UcIF?Lud#Gq<}%FL z7#fzjoF?PhX_>2P%)_DVJb=)&^?{B#V0U{punT3u4(I%8^8%XoF5cN1F*%YeK)C^W zjF=90?QV|XGqotXUJf4qB2S&R5m~?+#E(Kaj7J@y^)S!^FxSdw+w%SY0+@d_tLPVI zb)*fLF?~4BY2d;#Y{J|Ily}u!ucrE#>-zwk_hY^v0Bk-8*xU-(+y>a(4%qxBcuqS3 zn-$bJvkUY6Fm=v6LftaEsRz=tGLO?aC_6XvBwd(!3b46{Mj^c<^Dnv#WfL>|XiDZ; z%>8pT3+dd&y+IctIj>vJ)&EhQlyTXa==dSjx z@i|9S!!oD9d3V71Ao;mEFdnf#r)lFL`8jzZq^d83MSrmnY+SMu9+Il91ZmTsX^c@c zp+Ke?xD+7`E+em)KoK#Ka>XQ^dOmh_xAD7n7d9o9eSC)#OV&w;Ud$>J!>f6nud;&z zzs$CSD#I$;BR@5J+=lj+TrAMDVSfRk=r>2na^K zEl%A^kJV8}iOg{-UtZaIk5gK=A7p}Z2V$Vv$#^@NU?Ni!p(=%&bMS{8whS>zI05g9`pk=~E%osn_$NaRv_DsmaU5E)Oe z;<+~>SJ1nWE9qF|IyxSiLf=MipzkA7g%Y_@cq7w9C^B6bkr^U`v@X(mNE<|Eibj!H zqC;ek=o(olxSZ^ltvaR?IZtG zx~$_+R8&rI>w;4-WQcqUjt&D&DUZT@3g(41mrs+dEx->hvLA$6IBQ%mW$_~8I!7y< z*+;Y4fAcwjKnL|5cGjOP2V2DS!QJRGX}>VLLT$rdJ?HXBfaloHq4=}Dr@CaLGdId%xkMNb^OW@rSScbPN;R9;>D!IH=v<+*dgdx-l zyD1v>P+{0hCE*aY42P*hI6_^*Q929PeZmPE8%7ADaE7i6*QQzFx->6bpXP@f&|;*^ z!VT%pa3i`W+?ehQH=)f)w}zY1BjM)sbhrh*5N<_>!Y%22)H@PxOCN>H=or#3!|muq zxIO(E?jW>qcM%Nt5Yh0Nq9M{o;a;M77~GYxQUe%1(Lc61pZh9CEAcVGUCCYkxdi?L0#ZdJ#z z&&c)7+}JHVINq=k)&`0}rmu3JX3xFw{|fmhPZN(63RO%ij3|dUCNGw2H!eq-;XPvn zfPu~K`4K>cvy@+wGk})M;d+j1vG`Or;b{cT`H37Vif3Oo&pK-5ssgKh2yJ@qJ^{c+pEQU@yL=k_MRQ1mSlL@Fn zw_^uL45%;^11FP9Dv^-*m8KGfhm#t<2x=xHC=wn;vG6#`4_`(N!sDq)cmj0}Urwim zC(-HQE9ji?mDCT{1HxC)P}CV7zJ|tyC)4HOYiSbFYr@yj4Jexyz8=Ww1_b7sO1B`r zJ$xgrMA@3~bh-(qpXg2l{L8D5b-GwM*PY{k$|!%5>%eW^$U@Z zaxfBA-p4aXB5~zYJpXwlPx&rlDnBFrEn=w@NvnxSZM850hmMiDYL`eowOgdV+6QIl zMjEJtA`R7{NJmB*t79Tf)XO7H)vF`T)LW3=7HO%jM)}>5Qgu_LwYoJtq&iafdR=GR zNL{%LJ3NF%;$`V`LMsC=l8lEowKTQ|R(oo|+zNPu!*Kl4Fwi)NS!UR#j zjV-2rm1NSN9V?eS$v84_Bd(?NG4h|{{^zb+>3i30f?T(Yfa^}t z$hBNFb*&I*xb6~gN+`~9-75OHR*6Bb)nc@3jkw%(w^-&{C+={q7Z12Lh%Lx($Nimv zut!|?ilt5b|@1dcGjV8-;GY&5*woV`pvA)A1Z1o2CCA%yP>Lsh+)*`OJ|3GG3hD0<65cMZWVQM{Y8T5@m!DeyBGey_`lGTY+8km+j`81I zJB%dq{=MOY@JIA&#S{P*jYCcs>vQPm;Kt@leuZkMU!{8K*QsIpEozj0hf33jsdM^W>XCkrdZpi| z-sumhUmEJ2=_51{Wkb^+(-_nlm;RK-r;pJ!NUuwOMmMCtplRu^Xm0vzT7YzM`Ww0} z{Vgp=x-$J8ZA^bpF3q6(om0nH%Mu*eC)4NEIq)%1@PsKaK z<+!Jyg@6l|M)a!o5uGg=cBj?0Rps5jP0>a^%_@P=K zs{&>fVz_$49(Knimpyzq=89=@NG&-F z6*wH>qTx7d8mO7ae7XeR`G>p{3fIG(`nb~oZLpY~BPO__ZRK6YRpp3bY@Y@YwX+Lu zwUf8%;nsEuK%fidj`<^EFexNISKhib0zRveE&G!95^L)S3 zBHwRxi|-_@2e)Y((j9(<9`~#Cj33%8ex2UK^@n~pedhPk_kKV9<_`$n9~2&>em`7* z`@_QWM?^h8+>Q7leD~*xE`C#-?zcpDe^T`E=Zk^<0x=lrh5nQn<4=q6{*1WRUsv4d zuP5gD>x+fR-;P7mYJaiV=r0l5{IJ>ZHxWIlPQ-ndtx?1AS>sBc^=0gLrpSZZW1XrMF>)*J~F$6PL_V!mZ#f$S}ha|;$3vZ^Mp zVNwLdY3np?hYuq1pGTVieDeDTlHngjN&jHV_=i%l|3Yf(A4c8%BdE836bxJ-75?=o_5%tdyrhlAB`sav@f4*qsUjTsyA_Vvsi5~vN;yk1S z{kMqG{#$Dx+u5!@HVg${0Jp6<_W9QA=P`+RcyRw%PA)(cR92zBz)m3b;^+qwsY?6` z?OkBoGB;pH*x4#~B4u8bIzfwl$S$%g_>sNM&IXum`$Sn#Hu)0T$-zA|$=MLHXp*yG zWWnm=Yy?>}$=N8fXp*zJ$f8Nk!e@t<X>z+0F*WZpz@c4`~{pZr-qOW-EWr+wo44$9E2?2K*CB>$86|60-7kmh2vlhhgSk*`hl6}s zWn-;tHWo{*fFHl;UPt%ZjAV1{Erk zF5fCJgH`ugs#WcNEVW!ldD_DB*|LnCYF$+c2(k7s^nu306#$b1b z*%(MR)^uvD0Dsm{sl0|WCRAsf8fz*e-aC02@!rmJb-tyQHgWcm_VQ5#lt%Dp=iz46 z9&T3ka5!w2o8X>KKm)NR%V~JF^RlDrxo{ALl9{F@wHzD#_b&yvH1^y|84R!WYT&DG zj`8e0vbGZb5l+22d^6}bz{Ei29fV(@(gbR6i6xko&5YZ{+>f`)lI7yCR32O|c5(%q zU`#j;X|sUnuLMN@zX77ZIv{3UI=lqVj+fu?c3IN2qBlrH<8_thm5a-84FM}iU#QaH zdMK{JTgG(&*IKDrE_$M9vRy^vDrLC7#;$^ES*1RTZnmplB5f`YBPOVX+B`%L%)h$}jPo$*08LtRYTmek^}E705m~7-st^@C_N7?F>1)0ko)D zff4*zjCqHd+^NV6>i`%P>J?lV%L9QZGX+@lGGp#kGxCMJuy)|LC02;#f)x#<%SB+r zO+Y%+^fDsil3fbg>ofr3!AZEZQI)}{s&1?guwgj0!db;vE@<3|= zzYWKVD2l$1T^15SY1$w$pApMLj63=9WOvMD41iDs(&GBipB0in&iO-;|@tL$cKAWD7FQ&b5FiGQJlE!bPm*aQPtMNPOjrdAB9A8E6 z$5+#l_!>GIzni{^ucM#i>*@FS2AG4c7w-5*krOW$ainJaKG7(?S#*j&DEh^>z|?aq zOg$eI7sj`XvGIS33Gp3b67pBYE5x+;E-@$mkeG-3LhPA~;*Y}Ab2m&qpAb9akcGsb z5>LkWh-Z<10cHE+&xp6<{}S)SpA$bI{W<=k_#^(3QY*e+iN#-53gZWq`p6f>Ur|cp zuPL45uPa^RZz*TR-&Xn~e}4S1GCcmSa#8#}VOZ@z0bc@z0fINN8M!@jSkuXqoXzi=`f?SHpb|pU1@aHrWvPcHyfvGON}1d3gb-e9;2tW%{WVY z%;=>(XY|$%7=5(YjDFhNMt|*7!_q!C253JT1NA&(fNmK>^j5}&dTZk%y|XbwKi{}m zA8cHr4>QK-ml$L9Nyb0)8&EdQxKzK%xJ+MWOwd;v6ZN}|%k}$>NqPnH4;xqMj~Q3% zPZ^W-=Zx$0*NrLq`^F9WXU0_h3#4BgH|oC_)AZkwo;0Sryv7Vyz?kU@As;nnxst|g zS0U1jF~?P6%yl&}ZgMq8zLhc0)ybIe>WZ|RvB1^WSm^3!EOMQP{6J%|You|r>k_2@ zFqXQ;8_QhR7`M6ZGOly2HkP~A87p0zja9D4jMc7ZjWw>9jJ2-Ujk{g%A^)MV&UMt- z;0_rZ-Fe0)cWdKPcbT!--O+f!eVXy0yN|KOJ;?Z{`yyk9dyKKueFgGY8@t?7jfdQ` zjfdS!j3?Zyj3@DX%Dv9m$?Y zyT*R^hsMk9kBtNF-;tg)p7bcjo1R+68=koFmM3kz<0&={dRibYHQx1fG2ZhGFh24O zF+TQ;Hja8OH$L%PXMF0JX&mz`G(PhzH9q&OLwb+#h35g|E6*O|glDhugXaz7N6#VS zC(lviXV33QPa3~_HRBJj-}uuT$%7lNJjI)zr+U+QnzwGA?ro0iR(YNpN4z<%-u4ks zO@N;kfqZefz|MQ;!$zB2gQwhv4Bl+L(UJ= ziQdd601mh9IiRKJH-nH-sW%URZfd3Xg&fqliODI})`4^P>ms=O|e4?OyX`j zvUT)G*^FHTD%X41MT48!afsPcWajW&*n_;Y3toBZQ*v*X?1&1qB0GTHx+9+G=XegR zQn>W8D+_i!-!yy6mJ_mUey!ss(1$av{Z0%VuKmD)tLD6qg&Q}qk`Zeuw#l}#TT)^f zIO+*D!sF1?WCwuk@{f&la>eCxe3h9>X2!47ktpwB^5i{2exx~hyD5S+H}6qO<~>36 z^PZ&Ud3&fs-qUnu-oNOayuCCi?^zm__Z(f4_X5qydyy98?WbGv4$y6Ruh8qdM58}I*@me4&@!Dck_|hrDAVnD?2eop)T+&HGw3%sU}k zWPchacafPXft4&?Z1_`tn=`E&5!0(~h3@86P z5r}s;t{*p5@w{0}ylTe9Tc#mCG4sUdrYXKRE%CdVuc&5$qMI2dVAiRzV&=Ns4r8qg z7;9KD;wsGZa-5aE1eZYvV1OaSB$5uFWmyP{HU}txZg9v!oQ-vMWd>7;9qO!NsrPl9 z)z_iVyX23@KWON7fPv50nZl>CfPM5 z*fZTY#LzY~AfejkR|zQP#yI{p!Fp~+WoAq2VYUM8+ZwEkHXx5%(>Sv& zU1qjNFo+Ixt=W<0nVo2<*%ew|r_r6}8MM*tPWPH;(L-i0ddBQcFPeSmHM1|hZJtd> z%ya0t*^j<8`_oV6x%7*9zEI5Gkegp1a?Gl;pfwRVaws zn%c*P==1h@V7qK&B;NSEL@Wpz0iC8LrHD?3#?Ru$FRpfDy>p{E9(bg(e3!bwDNhuI z8{6j(yZ{Fe=Wx<1=4I=47t8g05Urp;3{Zhm@Be!--=8o3pT&GIQ#cJ`zF`pa4TqR- zB*c58DUrT}3esaJlO9WT)8nW?dOVe+CsLF2<(!0~MXhV7~#CcQbzVv+BkzN2% z-a>i;`90~I>811%dLw-cy^Z{#^sRI>eH(q5zMZ~7{yVUAz6X=#$Mju7!#?azuN1!Y z8WBma6}8gqgqdD1YNt1fqI9`vjI>#LlW3E^SF}gkDSf}_o8Bz?r!Ny1q%Rf2(%ZzS zG)VpQKgEsd9by{N+3AXE@T+*|=|>&JI0*0ykBMR|^N01Kl5CJ5ASc*nD13 zNiK}4C8ro+kO9FsC}KYXcPt3S$x#wOY)DGr`nSqEBjp{i=X|y&E1dS)7nML~^SH{m z4hsNLhoqv~F2#HTk#D3D5#Ty&#N(GLd+-lw1{|9pKPzBPth8CUlePT-q_%@-;75P9 z&#-Sm`&qOal8AFfR!Q(SeoS(4TF8(pTgXHRixwwiPdLmn|Z=d?U!rK;3lUcVn-1ZqMc0RkBt1Zy*XahT&fmINWLmhg+~s z3AKjNUk7Ry>PYQFo#>2EXF3!4UZE~@eyA%A51mFMLub;MP*1un)QcvBpw*7_+7LX{ zht8q7p#iicG?4BJ4WhM3*M}~k2SS5sJJOw@p>WJ~Aw7!p$9HeqIGDx=op$IP7BQx-H@Ic znlH`^EfhmTi^Pb~VlfKom{7wS05?C2Fo|8QDWFuK?G2)7S=HVk{eK1CJmsnbdSh(%~H<^X#S8u)1uBsK&~r%PXTvT*Q=Wb#@h^?o_BlB*^07 zmYbQ<*v>WHu42-&tKw=8p~fQaEVSIgyS@JcZTL>*egqL>2mVonGuo*vM1GzOK*|#F zc?f^BTkHVK{)e52XH%BDTfE89%knq|5UQ(ZS36APnz{SHo{xpiT+nQ>Al5-SjW=`c zg&o5N7&l|N;u47$Qck^H>IO4cE|$~nwKPvI>R9vzSuNvKaaZ|DZiXLLy~XH5K7HjJCu&>3$8@w*kN2XP3{dmS)i@jM4LEdAmbM_ z3UzRV+Io}?Rt8Hk#B%D7laAf!ncNg~xmQppnd3%V$u3IS&qi*Pk0sR`EsJrGq!VTF zA~TK=)Y_$j7Og_7x`S3d2(+Y*V+&l)4Eaw$XWq@r$2;UJm7fHj0UCMdLm!sPd37{@JYjjxF;aC_PF>wdvaxaOuY>t>%O_#uf z&o_uz^DX(2<^)c_3)44HGWrf)n0}@@fnTV8;8%EJ`i)8hzf-5cAJjGQC-n-Pq;o(m zT@VyBDyYzepi0*THM%{h)AFE;RtEjFAsC?hgHfso=F#K91RV-m^jR=TUj+;3M6i&4 z4W@)1ObZ{5uK2B3pNvdgDu36U`sI~*h-8EmWfHh zc4Bg{y_gy7B<2J=izUG>;*Q{H`1KI0f@g}=NY@AZh)uzMVkgpvg6D~+g6E5W1qX@) z!6D*caHu#Eyij}^940H*rl_kL&l@-Bh%7)-{<-y<#<)z?k<>lZU<;~z+<%8g2 z<#_OB<%i%B<=5aX%Adidsv2CTrh>Psje~2|vfw>x=io-QTd-U`E4WGRAG}u`5ZtVe z4nC+(3~s4`LKnC?*(fx2FXqn}g~Yx}$+2JJ zQ7#JrNjfs*AhM1OnZ>|$Y=q2WVB1||Rt(IKu^70qU4g~G4qJl7z%%XATF5%`W?0ok z%orrX63MfSI9`e2jY`RLUL|Tb@u(w%P9W>ZpeC_=*urHkOY87L#BW=yj>4X@ZH712^kajRSe+Q(X4`V#8B9r4#a+z}RkRbnI@=S#*fQ%?(T|9WT=QOi zwX{L3-g0uyY9M0uWvcK*<66U1ikr;%KB#$M3hJ48`ye?-uajnCA3;+~+xiJNc!Vzvr+PgNC zu@pmG9WRjO;C&TAU#i&5wRvA9u@dHeL6ZuChbeq7R$}wMiY0z6=I;%@P7$-g8uJ%s zS+K1LR)l-7Z&G5+LfT>?7-LJbarP#}vwRbPq?a`@S!ips&s=7ct+*&Rn*ek^Ds38L zw}MTIqTiZe6S~Wqna%cPovd?2WfL7}6RlS{0rt}iA)Ts=R^Vrlg(JI6?1B7>T^v0C z=|Vez04g(#GZ*S=3Hl9{(ju)C__st(WFr$?t3tC;^@#*?0VMN$ll>!?$qIQjD}Z6} z9U4!u&XNUETP-b?%PRU%%Pjn01DmVErlST^_h2tnRDQ$_1 zY}lffW>Y(6k=bIa9O_aT5@ik4F0!VB;Qu(LgJmT!7s_@&SIn>Mf7iIe+-tM?_x z%)k~}lTI@EGuNs7Q0(Qp>gxt7%k5ei0c5GytvLA}4+h>Vk$sJ`OJ(+1t_4cE7%+7u zz#!ImIf!4Z;5t>)G`X^OJu9cFTxpG3N^`8gCT6UxsTs4^U$a;#u2%*@PEebF+EX$*!q=vIAqWIi|;6QRihVte~D|bD(##IYW`Bti&wYCjedY(#v7r z_la%UZbl^wx+yvsEx;eMc~w^h1J7J0;LPUL%~-iI(2zs>%hpHOtwYo=TkoIk%5o~@ z{@ESJ@gV!wT(OuZhhJt3!JRgF2NK}cy$I+87HDC%*h`P2h3e~}<=?CahHhs)fRyDe zs1^Q0BSJ6ZPL!Mcx5j#Cje_iYXkED;O1FwKZVPs_<_c*KFdNsECyLocW((|;%Mh2Q zrKClLBZFWlcp{Gf~!D*vq@D zrCQpG3E=cDm08Mc<(8&B$H20724AhE-1&=QMap`FrpscugZyxD0I8Fi@fegZfu+Bg)C1#5<5By_u zp$u$Z#B~B%DQqM(D9~0-_N_eGRa0z2l2K?P0{e(kos-d}8WQzvSW4h(93v1gp@7A? zWl)W^nV52$LC2}ua@xu*w2_Y@Y+e(YK^UQWG6SEh4vF_=_O(%*TAk0!PqxcG3BEqw z4kO`)MVuSKR>|3izp8xrqN<0{ua=k(f2F=ly#e-q{x#S3qhb^;v}%GAEKDSsTbDkP0KvL7z` z1-i$5ied7w_c~Lkly=}*^zoFHm3FXOjg`UICmcV=;PZqDjgGNW<^eIdb>x0Pdot`% zA{q|oFcYxhvLp2Q7aRpJ~lt1ug#C? zSMw-@MxThV`KhqXW1^nX<|u^|C};^_oPPIwR3uU6kmc-j?X7 z-k<2CK9K0FRwTNp&*J)}#OdlgiEirQL=W{?;w<&6L@)K{L~r$vL|@HFoTDWYL$pj{ zsMatsTx*`VNIN}ovDQ6tiPkGIR_mX*Ogld@UK^B{pbbe}r436=)ZS(QZs! zugytJ)m9{?X=@WRwDpPE+NQ)@ZChfVwmUIjdm*tv+n-pZ9Yg+jVyX6BVwp~f+jTW@ zhn|zTQ;#K<>sI0}y!?;zQTA#1Yqy#K*2@5=ULn zA$=KTuO^PU-b#GtI+Xa_^?u^G>saCo*O!SeT|Xthaw~~%+`hyKcP#OpyD;&CyEyTq zyEO5WyDagu`}D*w?lTj=y89=7a}P}X;U1j$)BTUcN%u8KuS4A%EX}>n(%t2j%e~EV zyDKb@`zg!o-f#KcuUJ9%x48b^3cLTbA|BO>dcueemutm61(xBdYvp;0t%Rr4vOH&4 zNlz~;-!l;DP^-XmxmD=7(yHyb#;W6)Zq@b7wd#46S`9pRSq(jFts>7xtHe`b6?=B0 z-N&t_p69G)p8ZyH&zn{Y&j-kVWR-e8vD$cD*6Cia)y*5Q&hUn;?%t@?!yB{C^jcO= zZ-LdzThHq4Ew=i4n^|XjJ6Pvx0@ms;m}ueHwi&ann~7g+D z*CAhS4fZ}@4fSrdF7!TU4fDQ<^c|EPwnlhAu||52Tcf-`;Mt$83EtnViM~SXTwlhz z(pO?#^sZ4*4M|H;u~aL@4L{t!8g*H>Klja@u+vXHPbiKn&F#m z&Gs#@=K3D8Zu0F$`nWaUcg$Mg``TLM7uG_*YAyCRvzGbWTeteVTetapS-1NyuJ3aSoisFv+nmVw>JA%SzG*Tt*!q1tZn`+)<6B*tsVZI$UkK5 z^6$1D_P=61?tjyI!vC)Ir2k{fya=4(mED+*7_{)hV^;ibL-o{57vpmFV=T~->vV1iuF^_XZ;)uTfYQzk&j!y z1=H5=!4m6_U<>PHux(Nao|$w7`z77MK}au5dV`~qzTo9afAGp=FgP`t6P%B9Nir5( zmdp#@3Cp52Nh^47G8udznIGJSd_}S_xI38&K9$S_pH0>YKA)@?d?DE&xIbAGd^uSX zJdkW0d5 z&_Ge6f6ILZYtfN9afDlk9m=w-YO)pSH5dZoVcAxSqW{1Fh2{8Q{ACqVV0dW92a1N7 zc!I`&LuoK;MxJWM;US!t;gT1QcXa!_?2GyMysWDn7G(>p%BVzL|^>$X0*$c~esLCj#SYM_uVli{zz8%U6d0q-sC$w2RJbUJa!)ksM zl*TEKGW9->jlo#;D{H<|kH_acj)91+N+~m2byks*DqfX*uIsZktMR#5>)6a;4?};` zT{)Xl^=mU)|EuGPW_Mlc_N-v~45!ooG6Z}fNZXkDgep*#&5stH5SWt8o&`f6#7my#{Z4tC3rsm7H;XK<~6+Q z4?{4=7s*rj5(0X?NI8Z3DS|Xw_%fM=uTY)BR}swcHELe?I(00369FCHqCSQ1(7A;N z5$x+QU0?V<0vLWk^9nztMTJM`mcox{Md8P^rtm1;Tlfj>C_F|_6n;+o3csM&3csXx z3%{Zxh2PLOg(v8{!XNPaQREf=B=QS?6UBwUi^eGuO;WmOpK^(QDYrN`WD+By5fUWL-AFrNPL@W zEKa0air-VM6(!YHiKIFxu~a7|FV#h9nCh$)r%qE^rA}8mAnlwwL+P37uJl8CUg}I` zc&eu|2I;s|FJ)S)w=y%;N12oAtK5e4&QyP8Rq9-2J<^S-^OXlv1C(v4fy$25AmwSK zdsBmz1F0d(q0}(tXll6fMd~8uhtvq=x70{gO^s4RsnIns*&_Xp#)5n*<4(XA8l${GsXx2&`ZS99vF=!E zU@tpFk>+KG0V1RUWWXjYsh|@G&A@GlFDPgq9i)TV1xHdPC3QC`sdbc-T2F?DgI<<`^r*_cP)J~d}s-Rm_yJ%JF zVY)xHoA#w1#qTkCJ@q)foqB=}rk6>J`xpY0K1WqEqU1(H&{e)SF^h>Mbm~x5enxJK{>D*Q5?%@f{WmQtyjfQy+*G zsSmO6j)+aEkHkMyAB%@mN5vDVPig@4Vpo|1&|#=k2cQGh6gp5H5jRI_ldyu4?a1F( z6ukpTaa$20LQ0h-9j^WCN=}H#TrpZQ4!|ztnq1L=ya6oEUulao0guw70lb^;7N5X9 z0D~@mYj-J8E;B*Ow#u$_Q7zp-?AX ztEO9Z;GnO8U7UiDNSw|J{VV1gKxEi;j*h6JrR z`7DS;L<-qQbug+?wuXY__0}>ywo;oL2wy(N)b$Ve5*$hcRqzVtbheUQ(_B%D$z)h5 zwuyGfAAVn(=oy@2LN^L~c4yayUOGCofU(u94g!+_ZkD5TsmWXNE%@Dm-<|le@MGC7 zB@H(b$lV9Z4`W2|4bux&A&(w3Y6`9&dGu0SZY5Ne_#PvkXC-lnn{uRwx%@7E2HPdP z3sue-pF-|3p~NSX>|?kuAA6??z}}=*P&(W~ntLnx-P@EYuC+*Q1T6ByW63$%od?lmmp-#K^< zl$Pz_HOSb(Yml*n*C10FyvE0>G&0bVox=eaeMRsZ5BS#zTZ6;r!7?Aa8i(FZfZdmJ zj3wwA?-j5>_wy>l=?%kKO|7e)lx<~&TmdV5j)s$6Z&GWfO59#fA7c=k_Q~b>-vY}B z1eV#UY~mHRi37@*p#Sd0#eMiKkY`R4zDXCzPOU;2J7a(#ftCILI-<>gjb(#I<|AMY zC-U9%Wr0d|GG4xECHH53g-TU%hPb2(2XLsHkZ2)FaoppyGeX^ThqLH&5bB20^TapK zA@B@3he!*NriIB5z>aIVl-6odJuOZpnn8^;6Hde|YO57cXRVO>YbhF`)uv0dI&_6r zm!@hBX@*urbF^Ywtd-DhS|eJeHKq+(Q`(_5qvy32^rqI5-qK3x1Fa2xrnMD-N)gif z;n!c}Y3GWxcAhBG&KE6ER;mpUZM1=+1M;1U`X+Ku8zZJMHJ(-n_4L&?$RDs{D+lxErjrIWT$>8>qO`f7`n3voS4 zyIGl}Em0n?erT*fCG)PVL9YS>S$U`IeG>&IovGwf4ugM4Nk z8^l#QqCB~<9HKSs&FmWb-`}jv;x@*}c7yWqdj^!lX?@lSs9m-cWrI=nZMAy0qO3d0 z_HdbCm|V9PUJh#d3|)uC&d0&cOsnmspXF`db^A*wN7(sUj1IbjCUVrErBsjcR#e93 z=B-q+w&2AiUs9pOMjG#M#2r<@^wQM6eTn9=PdpN%sM! z2TUNo-+zz}D;_DN6B#@$pza1kFo75iRmP5*u#FuB0#0SEkq(|Rfs)&Y7HjCaV@@4@ zAL~Xk2;Bx``UtB1m+H)01EI8p*=PT?s{CewB7;IItZloE`_xZfVe&+Q~Q`Q+9yC< zpHg$At+Zo6TAxvO?Q`m_9j9|~JwW>c2<%H5gLIts6lz)=b@~kH7rKjn)ZO%l?h#(y zix^(M|A)Odfsdj{`^TT^?&+TCOom(&7?Kb|I6@A>Wq@#oI|2z14mlJ03rIm|Ld20rmDKS zuC98j>Uo}eo~J~nD?#MB62&pDZeqME33qfQ<1VfgaVkFkY*!lY;_{2jT21>88oyk+!IQG|w1ah1zfN8GX2=j@$g%3eJ+E!?`_~9lXYYTo4FP_cQ`XA=KJC-4muKPY{Am+0!{arn#Huo=Zi}90|(FM>xR;i(6X1r znC%vrAygak3sSz8B#R}pxD(gR6{I{J6@$B|UI^p=kS1aKz8AnAEF_mKNXTz6~IKJEh{T^>l43K>9Aq z)b6HiY!-RiJv2y{!F$-iQB@wvYa#Jxzbpo}quh|3>>IeXBhu zg!W6JY5RfA9T2J7^VqKshz#vTk*U2T2EfnPUJ*mISFvy390elR>oaY-{(XQ5)Act? z{!d7oD0~{@!dZ**r&8E-{5|kmw(6KDxsNx;VJe2sTCjcW56PrRu{=ihu*p@{{^mXBYu_grPHM z^bu>MpiTHGj}+8mcPptdH5f?b&SVAY&zZFRd^3h7X;jDT=UcRQ<%x`E_=C@$K{EJS{{5M^g z`5(G6^S`ts^Lu(M^9On&^GA9S{>zyM=@qOBzs^$W(=46-l4a1pv)sa)R@T03`vfCM&0moo^ zJd8rd*#Lpy1}i8DIZ$rNHU)>Rv0iSClAgoUN(idS;)5^PQ8aEPEBr%5J3D*{f+u_9;}C-Arq;TXD9thBjocqf4?+ryH`* zqT932i-Pr=T;E%LA||6x_*TcaFsk-xMFqH9KCt@DB6(C{otvgWt~K6K1&l`*F@K0r zr0wV!c+9rN6&BX114OxYD%<09W`PB^(*DNn(I};k`*!&Xj0=%Qo_t_~0UO6=$FKzg z&KzS<01d%%zFXzP4<_oi^QFBZ7(9X1BeSnX|6PZ^y8(T7Bjsh^M8gptk-ZTLEjQDI z>|1e0b{id^y_MEy-$@r{-%XdnXw{Y3_tCA{_tPEO56~mo57LwH_hmms&t`9@m$DzF z*Ryv-_3g&c?yA>;&j8E5+BnDVijQ~{3$WWP!Pvd%bT1Ktp$lPj&V?X{xX9tE&?2;H!xe-B;Z{!(724J zwlmSlBPZG?w(e5KL%UnH9;mtkn*(Uy^$Q_4aJYt~+;73XgzWcNy}-8++|M(x7PO1+ zSZMP^rdDbtX>^3oVbmX7LIXs|FTiRMj|WW7$u|KhxC{o&kJ;_wu2R-lvJNQP#f{;* zE=SK=bl!PrFX+4$XJ1-haR+w`X5ek%cAhEQIS1_&lVG@JDDIQuTj(?dUS5OrDMFZXmUr!SgN0{Dqam>23c&EEBot*u$QvdU zxf~`J+o6F6E^BGP)_@Cq~V!1tf< zG>&EsJp!ZnUn&_&FLAeWjIvZ&2ER!;RXIa^fR1=p*)Q%^-&Ma-zYc4lenF=Zxqe5Q z>k~?VF@tp1XSnzH&ot2W7aHOED~)&kji$N2pjmjXa$y&C{hexXtw62oAJl~Veou3K zO;;oRb+}r76Yh4{=K7AdyZ%Fux&BMfVCQ(j^#i@=`jOtosrP5Pi~gqT^o?!^p_{_g zy&_fbCbIM-kqf`So-BswDPko2(U`YW^fWOOex>dgi}iF-r*{{Z>OI86dO*Cd_Y|M# zFbAz?iNET-#Fu(De!Z0pJzMFe=P22FU!}j^PZ_8WPzLFF$}xIAeg(=>_{;P{ZQsxx?j0oAFXWG$0&E}W0mdtIAy0k z9={37v+(!pWy%44vhs>PMR{GHro63BSAMIPD}U0DRld?^s=7Wyb?dX#6um+%)GO7g z`fPQUK1Z$6=cWkI8^`+`weTn*{e!Tj; zeuDanzD#`+{=52#_*JXF*O#kb!2b%*U+cB%w|Y?hL9f$N^%J#p{bVg$Ptf}7rdFV@ z)=KnKw6U(=I(8rOYzo;DQ0@a3%f?qOabPnp>MA)fV>jIi|;uHk>!{K|`6G{4gO zJJNdphZ1^!Pu+X}2=glh^D6@8R}`3E(O`bXfcX^<%&(X*zmfp+D_)piNrd?oAIz_G zgZY&tT8!sqIms};k^u87X)wRyhxwIsm|y8h*W_ft{7NQmhJQy+7TuN8o9;oH`*U(> zXHH*wGN&KyL-^U8JbEQ(AibTFPwyi9K~52UmNSUH$SJ0;5dJ!6D1DPNjQ*7~T<-9a={(4qk_FI zWDx_bMAQ_LronlKMDT61Cbk_FbGJH7nstA`Mm}KP-Lj|RAm#YOIGPQsIIx6!EGt$c zSq{cugxm49I4`ZcmG>2JT1KV}gu{sR$Q0iKiFl;>*RQA4A+3W3%Z3A{DuUQ zq=Mf@=dEbBg-f2#h3cl?5Xme`lldcDTa>Nv z$H3BSB-i`lDl56l-$im2S+$%D`#4reUJU54OTiZdTKzB}l8ZI8Yi&baA>?wNRNua< zB*mWsoh4Q%u{1tmCj`Cz4mRunU+6bxx3VB?4d-(n{GvcAYPW5AVgHuRX0trFKSC{m z)eni-mqH!gQta?cunl-iVcGlKK>B0K4}x&#?dm{!DfIGiJ2#8cbl-q`rg}(lO!-Da z;waob5%33KWA{c$NU|7Tk6-4E=`xG4Lt*Cb}^2eASwgtERvEQ zNZ(Jda~p7EkSfqa&@OEXKj+EkW#Q)>`CJ)(?jxVaho3K&&&A-?Mz=$JykdWh zlp}>zq@xcxnAo|j2ska8$jw}?z_Afp?gV*%v3-~U)Rd>|XkMfK1JYjhMT%{2NoWJL zvDyS!U6@JJV>X(Khvksc|MiShkvopr0aYMwAq(Tclc81 z9{3OVy3FIh_^ofM_|!K|{L438d=LMiZ>pmDW+*=29Hpmkt}@EESQ+PAqEz^nDhqta zD@%PRC@1=sDfRFheKpEyzFOr1U!8K9Z-sI#-rwLmN!jdcR_^e%D0lfTIDO>bt?I8Pz~RWs@Hdun(EuAX81O# zIlgPuzP`_Yc<~-@jbLeE)WhfIrsvgKMhqpsS)AxvIJe*L?Vk5~I&C zZVBPKiM_$12KwZ_GbH&Bj!V0|*5eR-KJX@3s$z5;RzM0A`9`u_>o#fmY1=NPB*gP$ zSz2W{j=3aFhiMjdgok&$>q_n*^S_W1Nno}Uy9x{bo1R9v;LSNbYa8H4{=^ z=T$_?6iu{uFvw0RoH%T`g^y!cSP6TSb^5|~NN_-7=HoCDA-}Ov9+Er|a7pDugY8i; zYtgQ4+(OBTfpuFD?`&XBqDUUA7D*=r+(rLN`Y#btQ=yWrzavmg`T1SdGT!LDTY+ z4Cg&+uu^I*ePFtR`vp@pX|ljgQ0-;B4IG>)ZQ~jwJv;O!>3vWoZ z@dg$mX~v%OM|XRgiYAdw-KBys&Bc=Ex_`3Y@prcJO&>0`xXpPsLKm%Fhh?=b*c>( zat<6kCsH_vc+vt60We@NZC2$?E!Xc-7Ngr$XfE$pVTC7ME$JS@^;nDD{udrd7{CPaEBPV?%euhLF9|4F0qiHqu=$`Kf|K!DF28ShTtNKaakgliHO@g+Ka z_(eP2?Z-OAykY_aM}lZUWSVgF`Gg&m&JkJ0c?8&1go`DoZc%^3u zo$nb&S9(U#&7M-a*E5!OdB)Rgo(c4}XF7fCDW~6ij-@|&X3#hA|LvJY2R*Ze=9we9 zdyW%1o)g3X&oVK@bD}8mREsg5pqSvP6Xl+h#avH=nD1F7j`K8%C7vd6f@ig;_M9SW zJmafF}r zY!J_T&KECvE)ef{E)>7@TqOSNxmbLK@YkNp#J@aOD5__JqI<4ZJf3Tm6!?D6wMuu- z^-8wqMx~$UW+l&at1{TLRT<&ATPgFjD^or9C^J3xDN8-~E47|&%1NFFl+!&ADi?Sj zQZC1>ZZ~-zRc;1H{s9>H-VJ{bp7(loDNlPISAOZ)tGosO9nTZWhn{DZk3GLs{@{5| z`P}o8@{Q+Ls^)oFP4m2>_Vm1}W_w;!`+MF{hj`vpOFVC>V?6JwQ$6pg6`uFixte^$)3;E)t*1AYmxUH&o}DDo^REw;9u+cPTk}=sBSh%-D(Q;ep69* znwq-DbgBDHUEOaQ>TgW9`l0DjzcfwtpJsykoe9&AW|Ed*CTl)3Mawo*wLJI(@my%8 zX@ksk?HE(jO3e&yve`?UZDwl=%v^1e*;hN!?5CY%_SaUK1GLp z+Qnv(cAZ(Q-D(cjwwOb-d(ENRqvkMempNQ}#w^iZG)HK!m?O0}%u(9=W~uhEIa>R( zIY#@&9Ov?y<6Q&H39e(zGFPcN(KXqe_-~twUB5M#xV|)(y8erIKbj}%rdh2g zn#=Wk_(f)oUS}OnIZZd8%Z!xx* zw;K1Ew;2zan~m+}7ULQC&msPK^G@R>^Dg6k_#Ywd@63CRznJ$M|1`H5KbQ}=74t#2 z%X|pdz#nw?Fz1E8O!S1W6u(Ajx(JlI((T&u$3!?16C4V-W7y3*nxpAl&mbgnRCDd@_0N){h5+ z<6H;?Tn2qM1ODuSr=Bn?)Do6+<4ey9{4V>_XkU?E+n@=KsFbQje0}sMey#AS6LA5o zUZk>+4uo+>6(YpZd=)Gdbwk1i`7k9)UL4zbcfbhjP8fjQ1;ekqsUO0{-p6UAcP|XS zK0&j*PvJiA2X)P2ce~!R4s5hOz*6NoxKJej2fNTig`g%KJ~M-GWRFJJYN5&2o%Jb? z@cFFzJC@gD;b2JU+Q;mvtnc|B)*%hO(GP$og(Tda`F5`RS;>lNGsvt&y|@NP#kToy zR=HzVHuU0I%>OhfTUtp|#RanJI^eB9`7N9^!Jlv&WitZCmz)3vIL(2LGN}xmhm_~! zdt0Qb$imK~FtG-@_g9Rwh{~hxhX=SZ%DeX0+I@i9>^_Kmx|Q%@sSV5B75nA}h`q|L z1f?AAN>=~o#GyAGa^Va=)Rh^?_gz${T2+q4(Ab>{i^EV<9fsa;F$de(sTa!cNJghZ z`N!&1d25W-sUGX*n3zt5vb^1?3D%p~PJKoqf^~=QR8Z^%eA$IEfo&sdcT$cu&^%hH zA{qEJY$Qt72scqQBFz?ZY0TKTqfn~Twu?o8WJySgNu95(NJZ`($VsR!G;SpG;!_~@-l+oh|KWR*+r;RD}qA`_THKx&DjOoHK%7w?61*NSDG1#aSBaGQ%j4?-)8C7B$ z!p9o(#Uf*YIMFyx1dT=FBx8wKjc|)`f;iP!CeAWW6dR1?;u3@}H)_QVMo?@q>O{M- zLOg8Li=D_hljW0iQtXcWIOn#703DdP8d{>*3*Um309JEKiejWvqfSf_MD zIK?-UNo*&-ZHLH{$X6J{AgUKb~CP5(~TR{GUFz7nz2!xX>3y08n>vI zuosqBE_@awcp;0&WAp!im{vp z*lGupUp;-7@+O#d>ghYwdy=}HnFM2Ta!Q3G+*>FKcFy>D@D@lIZwozaCJ(MNM&bx? zP=A)}OS^y)(=MdUw2P=$+9gz!b}5ZayA0O|UrFU@SJ8~LYq1GE8fubo*-c_4GG~*N zcCP6RyM1RIs(r>5wvVfZ-s2H6+p@J*EE?V6gQht$;QJ1d;m}2Hj`{3~l!VW|51)NM z^-Oz!2Btko1!)iClOMq+Z>Pm+kJ8e#U37BVZaOt>4_%t}7+s#Wmu^XWf*weFk{(KX z8awhk7#BtVo4ytPa`K9|#T)tt*pqt){`sVc58y-hS-c1T7Wlt`e?9y+k)9|;yk+|z zBK|FMi+ADQ1pj^bcfkJ${@W<;*F^eBf3pUpTTZ-3IH`Lcww>CAm6t^IHRdw;a=IS-U=9XZUeC#`^Y1Qh6;JSJ1 zR|m@*>zW4DG*q{=y!hkePho(Iur^?spb~>dn6Pu;^B}StJ4x&$vy;M3Dm!WH_}NKk zr@NOjsE3#GsF#-t*ePOX2s=aBIfk8)?2KV&EcF$n<_%mR-Nk}N-g6{7`>I((zh*VV1)%i_s)U_odAkazOo^LA>0P|WZy6oYJLRZ|;a zVro5qo2P1hW9!ObYkdt4dZR&N5P!9xgzDDThWeJ)>A~t+q*-3w670~8evaiYW$+1q zsUY|AhNha6tAefQ#G0nY*6RAkma^8?W(j4J1toK2u(7pjb+Bf7bz?2JD8Y{7G)NKZ zNN1_F!J3AuV6YL*uMIZWuL;&pT#w4?>Km&OkIH=YEoIAFTAQnDTCHM|A|qJ2{G?zF z(s)+Yx718+s9u3FAA0lvCTQZ(XNsL=0KS%*rq#j8L9{)H?)A3>TPMZos074M4u5qr zp2}msFs(I+30&P8oYD|ng)S{`tPQTi6lh&p-_mz5dZ!irSy8)efA-#}JJ-{%_5YWp72AWEfD=fx`)u@8q+e3dBe2AROe0~bb}*Tu7}-h>k=cls zc^EQ}Lgrz}JQSHnA0o3BFLMzxk3i-kWG+Pi_Ctde8h~qy2sAI&cRXd0h~CQve0=$T zKLteaZyplw*{0FdqYK##+kE&{C#bQ!xea(!oX|G0tA1 z#@S2MIGI1u&OZ$KvBqGbE8I;`l*0-bTfle}a{*@5c<`hyz^uY`G^{cLH=UBOBtCCr6EC{fx6<#?Lsm@uvXB5kt%H#+xHUod-S?gR!eQKv-_) z_BIX4a(fO;vO#!~4Z@R<1q2w}6gC_d2H|e8ApGA+-+WgC@a5k`B<#XxPHS#zTOEhI z>4gozpq>V0M0NlMT$3H_0GQ)mY<$UH?748VC@r)hbbaBEU93If#&wb`=_1S?CHkM_ zK+$cSG7d7`rR93ePZ>c$E{QsKgiz3;JVJoTbU+FJVdSKb!Gq5b>jTDUE!vX-cmOB} z0onMc#4w>rm=3C=BDXxT42Cb8Z4zzl|l0iT4>O5 z1}!pZF;FJzZDL!6194S$`mmGBPG1u%Qa=wi-u@=mvH|Smnb<%FawwnQ7MS?tLJk$N zGl;Vlb7-&^l>RVwMtP~6hO;w*osrNO!VQEpgC==t7H*uR3U(@KsF!B5GoOy}(h|#oJIiROTtdK3OUoPBaXARBFBy50I=-FQR#z8n24_mkD<6mw{P5xxkr6LG zoVhR_UfH3TaPmW;p>gBEh3sQ3X6sfp6t`5bE3PU#4!B=SFif&YhNCDIq?Go?42j`9 zn&EWdHXRWg^;^xZZz`S*ZeuHWj=}0xN6)!)FOekg@o0~^WMOr4BRH4*pjWS69c%=* z$qlz$*Du%)GX1+(n%P_@1V z9H??;5lVtCy77V>iES%&TZv0jFU#4{QT-Fk9M~Q;DI$N47T2Y+4Im zG`Oj}xHg4)N<)HG;5YGVz<-ReU<$(@j}TZW_$QEzyQ!PCY%+c<*E_A0rXb8q=}a(h zWCmf{i{yQK$-QVd`DPXDq5xZK?p>5r4B>+k&96ab*$cr2h>TKZ1rBH_bzxyr=`Kn} z+U~n3B@|9acp>6?l*0PqF3Q?P*(t7Fl!oi(wv(SLNWn6kR0!D%l#!yq;dH6;IRjR1 zLa9_oDiNKkz`E#LV*M2$zeyWQZfzVTYU3$cn*gghWw4kt5f*bM(I9OKP1mMUg*J^& z(5BN#S~;xbOozdzX)yRS1IC_a!dl%7YS(7bz1kR>fWE=KKUg^xiIOQamC6vuJA!q< zk`hfxe{|EJKm5cUVd($a5wMzB9JT+mBmAEo!9G>{zja3d{__8i9l@RT|HU1_4V5l; z4kfz#P_jFh0`9()?e0f;?*25$od-O7AXT{Y=>&HHo#Za0GvS|u=MC;bbd|f9?u6g& z9!&STvyXm9I6h6u*bn-Ef4p^c0kN1HY-wu1IYrFI0P5xOnZ_wS(3U8^o|UZ*K9>!Gi}EFPvP2uCSyF ziiQ+%+~DDZM-<1@HR0$>00P@q)7sV?w3}OY^hK~N3Qm3`a~8+f4l<&=(t%iai_i>q zH#i83(9ymlDuh9Ii9tE~C(L9pK%6wdl*ZQj*7Xq(>F#{#089)$dXd)xD+h=I9QMy{ zTi#G#!^9OoMMy1QY{z$t=|<{}b%2@ki9m0A@-)Z#)RX5te7=Ao4@dHR;7@c0&|v;6 z(w`)Ak(#1H|1Cv<726c8>QPFuW7$4nir`osvB?&-QG{&r28G-qq~{JLH~fU$VU!3z zDR(%fz)#ODq0HP7)C+!2?nugo-#>R0<-sq^9gGsNB-u@gL(p&)lAu9SL6dNZtjJcc z0k;RsE=^R&wNpvqcHE9J6vP7?rXb&hCWEz?~g^oe|gxq5x$YhZX2HG(MVFjmu zh47hd@PbM!jup{5W9#wf?16X||Cl1{0%$p@&zOzk1i3{_a?@lt4DeH>L9-ofrTGSP znQYDybA_-AxGkqQhjQ4lcuUMt0&mGj{n!C-DIv^T@-c78VBV68c}uW1!`X_w;EREy zRLTsYsmv~#${eMs%qf~i6PTkkh&f7dW-^y)7G&DNR)RB+8Appb+Y;V=mQt~#3I5;D zLK=2NR#Chqzf%mRxXdN56ELvpgqO>ojk1WpbvgJ;z9my3{ngN0w&c(Zr)VydS;u)~ zmd>!8lCj^-Y^ted0fEr6{!`dchuJN<&Y9}cKJzmZ9?{_Nvva8&d?{nC#Z|;MlOUI8 zKEUPW7)t^c!qEuDS<9JcWv%72k!U((KNXp@3Of*Uwg!Y)LdtGvmK5x!9$3axz!OSi zJ{3I4JIb{79xkjWilf{mgqpqN%E`=96y9aK>M$3ItWpUe*nA_Gf!fnfl;kIQ- zZd;ngZA)2Lh}7V>+1xkl89X;UqZh0_i<>2{{K;*^*1Hh~NbTsdHbci)f9r_+jyTf!yY~RmAf6PaP3(z0)(I4~BA64k< zGBiyA-;M=ccxz06J0^B()NfR$Lie5c$EP`6*c!`MG&VH{7p|;t4Yok;IVkz9vD6e~ zQj!fyfqV)##l?t`9%4iB(E~^pBX7y1av6%H3DV{!7c&ye*98$z4g8)5}xgE(EN9~a8Jir(XaKr5ekV3IKv@Qt98m)U80c-4kt~&fWT}i~sf=W)e1NAilBF_|r81JGGLoh8 z0iMc87B0qM2S}Deg&r(bMeGb>r;R#fMx(v7fW~=gA){c& z@dq#BL%qc`nb9r8Ev2!1fCuLU8qWuK6TNgIP4QASJIgso4dZL|RN@?AQFRi9> zFP*}nW)8JLE0J1hwwKyyrkB=HW$Xc4h+WcA>JiscD;&N5ar^!)^UrGRd~A8lEsV5 z%R54s?1I?#b-G{TBs}7d;+SDSF*|o-?2g@a-JW;)op{i9IF~EQth1 zM1mtD!BN1}Y8sjvaUjkN&q-~~&0r5&-#CBnOrUIttq86I$B;v_n}cht(A=gb#5q`j zA$rf+~OG~WSgq_eJwSus> z(A^Fu?xcVn^zFobY>-Opk)Op${Tiq8yEs8W7KvM+30nL6p*n;M7AbWfL3R|EIC^$M zt}S5hB)^5$&OoCUu(Vn3Ex^*CsRUnYD&<~JX}LFmRJ)P#b8iBfwh=7GO*A8S3(d~G zo#yA>K}&MCQg!Z~v?BK|T9tb@HRra|nYs7ShTMDU5|ksTR+4hu0TIM|2W46mB3Er8 z-aC*q2>l_eubfGt@ya-QBf)fa1@I)qe6_HvRPZFz>{_VkGR$3Ub_h z;Bqkx;T>)|&Q0eU(9Flps&uzO?FOz_rF#v!&!GDa+GfxL26Xo6A%h-ffuLiUF$_ng z5)MfR+P*rCWM@+Q7y5(C*jeSJ zv#FY$t;Zdg)?n@X{qz>!nL6=!KP+6<)fW zmU`(5TJ5DP>3A<)!_M`z$V)fSVlUmu&P^P5Gly=W6TEaQhi;=KUfRqrwy<+Mo#>@I z*x5=oUV4O@ytJLxd+AZa?yB_8I|7%xM+`ADxv8d&6*_^NXU4qZ6}q+ps?D>iSK~EH zUNXFdZ~}f~(LhxpHV0&G(1^p!+#FuaQVM6rspU|Iz5U}H)W#)kj#7Rze!0$u@g9lK z9~8F%&V-XDm(44yf>JOT%g7M_cseRW(<*yJj+{0^iw-$rLqdmykcJI5*6`RJ`77rE znL)y+?zhQBMv6gMbs!@<#ze!-?B*uM03niC-q<2fcCC&X(7CcuE1K=>FA0co2Oa$v zC!sSc(tq&_b*8leesr8dkMzxvYG!pRcjwEqN%p8o*)ex#VxmVW(qfEDhhFFy!_Y7$ zPRcm)2ZyR?Y`pA8kzdPWqO}8|7Ik3N(fmRb4P#oH9m6yV3JEeNSb<3^>l=Upr`J?B z4ruKShQ|8djaUPFv+8?cZy>N7Ro>VN!YHK%;u5Vv=hO#((vGyIclg=vX-qQfeatk) zdTPbToi{K>V7=vu$^hyR=J0}G31jlW+?|hBQWm=or{Lo}Jj<`-($GLWPOWclvEr}; zL_LSwogOc`0-FLCHxq)@cE>S+6@Coo_Q#3k%pQ&pHm+dtaaj<~<{EfQvJUgYQJR1(VfxZF_lM

      mu^OH8fS$aq0OhG8C{#S$-( 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òpM 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 BNNxt+boIhepkHRvFCZjw{= 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 E1X4WH{{R30 diff --git a/xdocs/src/contributing.xml b/xdocs/src/contributing.xml deleted file mode 100644 index ef6c91ff..00000000 --- a/xdocs/src/contributing.xml +++ /dev/null @@ -1,346 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Contributing to log4net Development - - - - - -

      - - - - - -
      -

      - All discussion relating to log4net development takes place on this list. All SVN checkin - notifications are also copied to this list. -

      - -
      -

      - You can browse the mailing list archives at the following locations: -

      - -
      -
      - -
      -

      - Subscribe to either the list or to the digest list: -

      - - -
      - -
      -

      - To unsubscribe send an email to the relevant email address: -

      - - -
      - -
      -

      - Most of the guidelines for the log4net-user list also apply to the dev list. - Please have a quick read through the guidelines, thanks. -

      - -

      - To prevent spam, we require you to be subscribed to the list before posting to it. -

      - -

      - This is the log4net developer list, it holds discussions relating to the - development of log4net not the use of log4net. If you have a question that begins - with the word "How" or you are unsure as the the appropriate list to post to then - you probably want to start with the log4net-user list. -

      - -

      - Post to the list by sending mail to - log4net-dev@logging.apache.org. -

      -
      -
      - -
      -

      - The source for log4net is held in the Apache Subversion source code control repository. -

      - -
      -

      - Browse log4net - SVN repository using ViewCVS. -

      -
      - -
      -

      - Anyone can checkout source code from our anonymous SVN - server. To do so, simply use the following command (if you are - using a GUI SVN client, configure it appropriately). -

      - -

      - Checkout the logging/log4net module. -

      - - -svn checkout http://svn.apache.org/repos/asf/logging/log4net/trunk log4net - -

      - If you are not familiar with SVN, the Apache - Source Code Repositories - page has links to more information on SVN. -

      -
      - -
      - -
      -

      - Many bugs reported end up not being a bug in the log4net code, - but are due to incorrect configuration, problems caused by installed applications, - the operating system, etc. -

      -

      - Before reporting a bug please make every effort to investigate and resolve the problem yourself. - Just reporting a bug will not fix it. A good bug report includes a detailed - description of the problem and a succinct test case which can reproduce the problem. -

      -

      - Before reporting an issue please investigate the following information sources for - a potential resolution. -

      - -

      - Before reporting a bug, you are advised to discuss it on the relevant mailing list first. -

      -

      - Search the bug database to see if the bug - you are seeing has already been reported. If it has been reported then you can vote for the issue. -

      - -
      -

      - If after you have exhausted all other resources to resolve a problem you may want to file a bug report. - Please make sure the problem is a bug in Logging and not a bug in your application. -

      -

      - Please make sure you provide as much information as possible. Its very hard to fix a bug if the person - looking into the problem can't reproduce it. Here is a listing of information which should be included: -

      -
        -
      • Version - log4net version, or if from a nightly build, version and date of build.
      • -
      • Application Type - Assembly type, i.e. exe or dll, and how your code is launched, e.g. console application, windows application, ASP.NET project, COM+ hosted object, etc...
      • -
      • Framework - The .NET framework running the application, name (e.g. MS .NET, Mono, SSCLI) and version.
      • -
      • Platform - Computer operating system, version, and hardware platform in use.
      • -
      • Configuration - Attach configuration files if they would help track down the bug.
      • -
      • Log Files - Review your logs files, produced with internal log4net debug enabled. Submit any relevant sections of the log which help document the bug.
      • -
      • Stack Traces - Any stack traces generated by the bug, if any.
      • -
      • Example - Example configuration files or web applications which demonstrate the bug. When submitting an example which reproduces the bug, please try to make it as simple as possible.
      • -
      • Bug Fix Patch - A patch created using diff -u which fixes the bug. (If you have found a bug fix which can be applied to the code).
      • -
      • Description of the Bug - A description of the bug, include observed as well as expected behavior.
      • -
      • Miscellaneous - Any other information you feel will help track down the problem.
      • -
      -

      - Just reporting a bug will not fix it. A good bug report includes a detailed description of the - problem and a succinct test case which can reproduce the problem. The very best sort of report - includes an NUnit testcase which reproduces the issue, this means that we can fix it and that we can - be sure that it stays fixed in future! -

      -

      - Report a log4net issue here. You will need to login to JIRA before you can submit an issue. -

      -
      -
      - -
      -

      - Before starting to work on a patch it is probably a good idea to join the log4net-dev - mailing list to check that equivalent or complementary work is not already underway. -

      -

      - Currently the only supported way of submitting patches to log4net - is via the JIRA issue tracking system. -

      -

      - The preferred method of generating a patch is a unified context diff against - the latest development version in SVN. To do this you should do the following: -

      -
        -
      • -

        - Get the latest version of the code from SVN, see the section above on - Anonymous SVN Access for details on how to obtain the SVN version. -

        -
      • -
      • -

        - Make your code changes to the log4net source. Please follow existing - code styles where possible. If adding new API methods or classes then - these should be appropriately documented with code comments. - Contributions intended for inclusion in ASF products must be licensed - to ASF under the terms of the - Apache Software License. -

        -
      • -
      • -

        - Generate a unified context diff for the files you have changed. Run the - svn diff > patch-file command from the root of the log4net - codebase to generate a diff file. -

        -
      • -
      • -

        - If you have added new files these will not be included in the diff. You - will need to attach these files separately. -

        -
      • -
      -

      - If you are not using SVN then you can still generate a unified context diff - using the diff GNU tool with the -u command line options. - The GNU tools are available for Windows as part - of the Cygwin package. -

      -

      - If you are unable to generate a diff please submit each file separately and place - block comments around each code change to highlight the differences. -

      - -

      - In order to submit your patch please follow the following steps: -

      -
        -
      • -

        - Create a new issue for your patch. On the - log4net issues home page - select the Create New Issue from the menu bar. You will need to be logged - into JIRA in order to create an issue. -

        -
      • -
      • -

        - Select the issue type as appropriate. -

        -
      • -
      • -

        - Prefix the summary with [PATCH]. Enter a description of the changes made, - new features, or bug fixes in your patch. -

        -
      • -
      • -

        - Once the issue has been created you can attach your patch file to the issue - by selecting the Attach file to this issue operation from the left hand - menu. When attaching your patch you must select the Grant license to ASF for - inclusion in ASF works option. When attaching a patch please include in the - description the baseline version of log4net you used to build your patch, if against - an SVN version please include the version number and if from a tag or branch include - the repository path. -

        -
      • -
      • -

        - If you have other files to attach, e.g. you have added new files to log4net, then - attach each file separately. Please include in the description the name of the file - attached and the path it should live in the project. -

        -
      • -
      -

      - A notification will be sent to the log4net-dev list once you have created your issue, - however it may also be worth mailing the log4net-dev list to encourage the project - committers to apply your patch, or at least find out when they may do so. -

      -
      - - -
      - - - diff --git a/xdocs/src/downloads.xml b/xdocs/src/downloads.xml deleted file mode 100644 index a482b177..00000000 --- a/xdocs/src/downloads.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Downloads - - - - - -
      - -
      -

      - log4net has graduated from the Incubator project, however at the time - the following releases were made, log4net was still undergoing incubation, - therefore these releases are not officially endorsed by the ASF. -

      -

      - Future releases of log4net will be officially endorsed by the ASF. -

      -
      - -
      -

      - The following stable releases are available: -

      - - -
      - - - -
      - - -

      - Previous releases of log4net are available from the sourceforge site: -

      - - -
      - -
      - - - -
      diff --git a/xdocs/src/history.xml b/xdocs/src/history.xml deleted file mode 100644 index 7a9264ce..00000000 --- a/xdocs/src/history.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Project History - - - - - -
      - -

      - The log4net project was started by Neoworks Limited - in June 2001. It was created as an internal project within Neoworks to port the Apache - log4j code base to the Microsoft .NET Framework. The code base was initially branched - from a pre-alpha log4j 1.2. -

      - -

      - In July 2001 a Sourceforge project was started - and log4net was published under the Apache Software License. The first public release of - log4net was made in September 2001. A further 10 releases were made on the sourceforge - site. -

      - -

      - In December 2003 the Apache Logging Services project was created. - In February 2004 log4net was donated by Neoworks to the Apache Software Foundation - to become a member of the Logging Services project. -

      - -

      - In February 2007 log4net graduated from the Apache Incubator project to become a - fully fledged Apache project. Apache log4net is a subproject of the Logging Services project. -

      - -
      - - -
      diff --git a/xdocs/src/index.xml b/xdocs/src/index.xml deleted file mode 100644 index 7459d258..00000000 --- a/xdocs/src/index.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Home - - - - - -
      - -
      -

      - log4net is a tool to help the programmer output log statements to a variety - of output targets. log4net is a port of the excellent log4j framework to the - .NET runtime. We have kept the framework similar in spirit to the original log4j - while taking advantage of new features in the .NET runtime. - For more information on log4net see the features document. -

      - -

      - log4net is part of the Apache Logging Services - project. The Logging Services project is intended to provide cross-language logging - services for purposes of application debugging and auditing. -

      -
      - -
      - -
      - -
        -
      • -

        - Curt Arnold -

        -
      • -
      • -

        - Nicko Cadell -

        -
      • -
      • -

        - Niall Daley -

        -
      • -
      • -

        - Gert Driesen -

        -
      • -
      • -

        - Ron Grabowski -

        -
      • -
      - -
      - -
      - -
        -
      • -

        - Julian Biddle -

        -
      • -
      • -

        - Daniel Cazzulino -

        -
      • -
      • -

        - Aspi Havewala -

        -
      • -
      • -

        - Rick Hobbs -

        -
      • -
      • -

        - Lance Nehring -

        -
      • -
      • -

        - Angelika Schnagl -

        -
      • -
      • -

        - Edward Smit -

        -
      • -
      • -

        - Douglas de la Torre -

        -
      • -
      • -

        - Thomas Voss -

        -
      • -
      -
      - -
      - -
      - - -
      diff --git a/xdocs/src/license.xml b/xdocs/src/license.xml deleted file mode 100644 index b0e6e5ec..00000000 --- a/xdocs/src/license.xml +++ /dev/null @@ -1,266 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: License - - - - - -
      - -
      -

      - The Apache Software License Version 2.0 applies to all releases of - log4net starting with log4net 1.2.1. -

      - - - - -

      - The License is accompanied by this NOTICE: -

      - - - -
      - -
      - - -
      diff --git a/xdocs/src/release/building.xml b/xdocs/src/release/building.xml deleted file mode 100644 index af918960..00000000 --- a/xdocs/src/release/building.xml +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Building log4net - - - - - -
      - - -

      - The log4net release builds are built using NAnt. Log4net can also be built - using Visual Studio .NET 2002, 2003, or 2005. -

      -

      - To build a release build of log4net you will need to create a strong - name key file. See the Strong Name section below. -

      - -
      -

      - Visual Studio .NET 2002, 2003 and 2005 are supported build platforms for log4net. -

      - -
      -

      - The log4net distribution includes a solution and project file - for Visual Studio .NET 2002. Open the log4net.sln - from the src directory in the distribution. -

      -

      - The log4net project requires only the following references: -

      -
        -
      • System
      • -
      • System.Data
      • -
      • System.Web
      • -
      • System.XML
      • -
      -
      - -
      -

      - Open the Visual Studio .NET 2002 solution file as above. - Visual Studio will convert the solution and project files - to Visual Studio .NET 2003 format. -

      -

      - After converting the log4net project you must change the - Conditional Compilation Constants specified for the - log4net project. Open the project properties dialog and - select the Configuration Properties/Build sheet. - Replace the NET_1_0 constant with NET_1_1. - Remember to do this for both Debug and Release configurations. -

      -

      - The log4net project file is not suitable for building log4net - for the .NET Compact Framework. To build for the Compact Framework - you must create a new C# project for Smart Devices. Configure the - project as a library project. Add all the C# files from the - src directory in the distribution. -

      -
      - -
      -

      - Open the Visual Studio .NET 2002 solution file as above. - Visual Studio will convert the solution and project files - to Visual Studio .NET 2003 format. -

      -

      - After converting the log4net project you must change the - Conditional compilation symbols specified for the - log4net project. Open the project properties page and - select the Build sheet. - Replace the NET_1_0 symbol with NET_2_0. - Remember to do this for both Debug and Release configurations. -

      -

      - In addition the log4net project requires the following new references: -

      -
        -
      • System.Configuration
      • -
      -

      - The log4net project file is not suitable for building log4net - for the .NET Compact Framework. To build for the Compact Framework - you must create a new C# project for Smart Devices. Configure the - project as a library project. Add all the C# files from the - src directory in the distribution. -

      -
      -
      - -
      -

      - The log4net distribution is built using the NAnt tool. - A recent NAnt version 0.85 nightly build is required to build log4net, this is - available from nant.sourceforge.net. -

      -

      - To support building log4net for the SSCLI framework the NAnt configuration - files need to be updated to specify the SSCLI framework directory. -

      -

      - To build log4net from the command line, change directory to the root of the - log4net distribution, ensure that the nant executable is in the - PATH, and then run the following command: -

      -
      -nant -buildfile:log4net.build compile-all
      -

      - This command will build log4net for all the supported frameworks - that are available on the current machine. To list all the build - targets that are available run the following command: -

      -
      -nant -buildfile:log4net.build -projecthelp
      -

      - Under windows the build.cmd can be used - to script the nant build. This can be called from a different - directory and will locate the correct log4net.build file to use. - For example: -

      -
      -build.cmd compile-all
      -
      - -
      -

      - In order to build the Release builds of log4net a Strong - Name key is required. -

      -

      - Use the sn.exe tool in the - .NET Framework SDK to generate a strong name key pair. -

      -
      -sn -k log4net.snk
      -

      - The log4net.snk file should be placed in the root of the - log4net distribution, in the same folder as the log4net.build - file. -

      -
      - -
      -

      - NDoc 1.3 is used to build the log4net SDK documentation. - NDoc is available from ndoc.sourceforge.net. -

      -
      - -
      -

      - The log4net HTML documentation is built using Velocity. - The source are XML files in the xdocs/src directory. - Building the documentation requires Java, Ant, and Velocity. - Run ant from within the xdocs directory. -

      -
      - -
      - -
      diff --git a/xdocs/src/release/config-examples.xml b/xdocs/src/release/config-examples.xml deleted file mode 100644 index 88b3d16d..00000000 --- a/xdocs/src/release/config-examples.xml +++ /dev/null @@ -1,1038 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Config Examples - - - - - -
      - - - -
      -

      - This document presents example configurations for the built-in appenders. - These configurations are designed to work with the - log4net.Config.DOMConfigurator and the - log4net.Repository.Hierarchy.Hierarchy. -

      -

      - These examples are by no means exhaustive configurations for the appenders. - For a full list of the parameters that can be specified to each appender and - more details on each options see the SDK documentation for the appender. -

      -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.AdoNetAppender. -

      -

      - The configuration of the AdoNetAppender depends on the - provider selected for the target database. Here are some examples. -

      -
      -

      - The following example shows how to configure the AdoNetAppender - to log messages to a SQL Server database. The events are written in batches of 100 - (BufferSize). The ConnectionType specifies the fully qualified type name - for the System.Data.IDbConnection to use to connect to the - database. The ConnectionString is database provider specific. - The CommandText is either a prepared statement or a stored procedure, in this - case it is a prepared statement. Each parameter to the prepared statement or stored procedure - is specified with its name, database type and a layout that renders the value for the - parameter. -

      -

      - The database table definition is: -

      - -

      - The appender configuration is: -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> -
      - -
      -

      - This example shows how to write events to an Access Database. -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> -
      - -
      -

      - This example shows how to write events to an Oracle9i Database. -

      -

      - The database table definition is: -

      - -

      - The appender configuration is: -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> -
      - -
      -

      - This example shows how to write events to an Oracle8i Database. -

      -

      - The database table definition is: -

      - -

      - The appender configuration is: -

      - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> -
      - -
      -

      - This example shows how to write events to an IBM DB2 8.2 Database. - The following syntax should also work with older DB2 database servers. -

      -

      - The database table definition is: -

      - -

      - The appender configuration is: -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> -
      - - -
      -

      - This example shows how to write events to a SQLite Database. - This was tested against v0.21 of the - SQLite .NET provider. -

      -

      - SQLite doesn't have strongly-typed columns or field lengths but its - recommended you still include this information for readability. - The database table definition is: -

      - -

      - The appender configuration is: -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> -
      - -
      - - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.AspNetTraceAppender. -

      -

      - The following example shows how to configure the AspNetTraceAppender - to log messages to the ASP.NET TraceContext. The messages are written to the - System.Web.TraceContext.Write method if they are below - level WARN. If they are WARN or above they are written to the - System.Web.TraceContext.Warn method. -

      - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.BufferingForwardingAppender. -

      -

      - The following example shows how to configure the BufferingForwardingAppender - to buffer 100 messages before delivering them to the ConsoleAppender. -

      - - - - - ]]> -

      - This example shows how to deliver only significant events. A LevelEvaluator - is specified with a threshold of WARN. This means that the events will only - be delivered when a message with level of WARN or higher level is logged. - Up to 512 (BufferSize) previous messages of any level will also be delivered to provide context - information. Messages not sent will be discarded. -

      - - - - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.ColoredConsoleAppender. -

      -

      - The following example shows how to configure the ColoredConsoleAppender - to log messages to the console. By default the messages are sent to the console - standard output stream. This example shows how to highlight error messages. -

      - - - - - - - - - - - ]]> -

      - This example shows how to colorize multiple levels. -

      - - - - - - - - - - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.ConsoleAppender. -

      -

      - The following example shows how to configure the ConsoleAppender - to log messages to the console. By default the messages are sent to the console - standard output stream. -

      - - - - - - ]]> -

      - This example shows how to direct the log messages to the console error stream. -

      - - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.EventLogAppender. -

      -

      - The following example shows how to configure the EventLogAppender to log - to the Application event log on the local machine using the - event Source of the AppDomain.FriendlyName. -

      - - - - - - ]]> -

      - This example shows how to configure the EventLogAppender to - use a specific event Source. -

      - - - - - - - ]]> -

      - For more information on how to setup the event log to allow the - EventLogAppender to write to it, see the - FAQ: Why doesn't the EventLogAppender work?. -

      -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.FileAppender. -

      -

      - The following example shows how to configure the FileAppender - to write messages to a file. The file specified is log-file.txt. The file will - be appended to rather than overwritten each time the logging process starts. -

      - - - - - - - - ]]> -

      - This example shows how to configure the file name to write to using - an environment variable TMP. The encoding to use to write - to the file is also specified. -

      - - - - - - - - - ]]> -

      - This example shows how to configure the appender to use the minimal locking - model that allows multiple processes to write to the same file. -

      - - - - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.ForwardingAppender. -

      -

      - The following example shows how to configure the ForwardingAppender. - The forwarding appender allows a set of constraints to be used to decorate an appender. - In this example the ConsoleAppender is decorated with a Threshold of - level WARN. This means that an event directed to the ConsoleAppender - directly will be logged regardless of its level, but an event directed to the ForwardingAppender - will only be passed on to the ConsoleAppender if its level is WARN - or higher. This appender is used only in special circumstances. -

      - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.MemoryAppender. -

      -

      - It is unlikely that the MemoryAppender will be configured - using a config file, but if you want to do it here's how. -

      - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.NetSendAppender. -

      -

      - The following example shows how to configure the NetSendAppender - to deliver messages to a specific user's screen. As this appender is typically only - used for important notifications a Threshold of level Error - is specified. This example delivers the messages to the user nicko on the - machine SQUARE. However things are not always straight forward using the Windows - Messenger Service, one possible outcome using this configuration is that the Server - will broadcast looking for a WINS server which it will then ask to deliver the message - to the Recipient, the WINS server will deliver it to the first terminal that the - user logged in from. -

      - - - - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.OutputDebugStringAppender. -

      -

      - The following example shows how to configure the OutputDebugStringAppender - to write logging messages to the OutputDebugString API. -

      - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.RemotingAppender. -

      -

      - The following example shows how to configure the RemotingAppender - to deliver logging events to a specified Sink (in this example - the sink is tcp://localhost:8085/LoggingSink). - In this example the events are delivered in blocks of 95 events because - of the BufferSize. No events are discarded. The OnlyFixPartialEventData - option allows the appender to ignore certain logging event properties that - can be very slow to generate (e.g. the calling location information). -

      - - - - - - - ]]> -

      - This example configures the RemotingAppender to - deliver the events only when an event with level ERROR - or above is logged. When the events are delivered, up to 200 (BufferSize) - previous events (regardless of level) will be delivered to provide context. - Events not delivered will be discarded. -

      - - - - - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.RollingFileAppender. -

      -

      - The RollingFileAppender builds on the - FileAppender and has the same options - as that appender. -

      -

      - The following example shows how to configure the RollingFileAppender - to write to the file log.txt. The file written to will always be called log.txt - because the StaticLogFileName param is specified. The file will be rolled based on - a size constraint (RollingStyle). Up to 10 (MaxSizeRollBackups) - old files of 100 KB each (MaximumFileSize) will be kept. These rolled files will be - named: log.txt.1, log.txt.2, log.txt.3, etc... -

      - - - - - - - - - - - - ]]> -

      - This example show how to configure the RollingFileAppender - to roll log files on a date period. This example will roll the log file every minute! - To change the rolling period adjust the DatePattern value. - For example, a date pattern of "yyyyMMdd" will roll every day. - See System.Globalization.DateTimeFormatInfo for a list of available patterns. -

      - - - - - - - - - - ]]> -

      - This example show how to configure the RollingFileAppender - to roll log files on a date period and within a date period on file size. For each day - only the last 10 files of 1MB will be kept. -

      - - - - - - - - - - - - ]]> -

      - This example show how to configure the RollingFileAppender - to roll log files once per program execution. The appendToFile - property is set to false to prevent the appender from overwriting - the existing files. The maxSizeRollBackups is set to negative - 1 to allow an infinite number of backup files. The file size does have to be limited but - here it is set to 50 Gigabytes which, if a log file exceeds this size limit during a single - run then it will also be rolled. -

      - - - - - - - - - - - ]]> -

      - A more basic approach to once per application rolling is to use a FileAppender - with appendToFile set to false or set the - RollingFileAppender's rollingStyle property to false. -

      - - - - - - - - - ]]> - - -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.SmtpAppender. -

      -

      - The following example shows how to configure the SmtpAppender - to deliver log events via SMTP email. The To, From, Subject and - SmtpHost are required parameters. - This example shows how to deliver only significant events. A LevelEvaluator - is specified with a threshold of WARN. This means that an email - will be sent for each WARN or higher level message that is logged. - Each email will also contain up to 512 (BufferSize) previous messages of any level to - provide context. Messages not sent will be discarded. -

      - - - - - - - - - - - - - - - ]]> -

      - This example shows how to configure the SmtpAppender - to deliver all messages in emails with 512 (BufferSize) messages per - email. -

      - - - - - - - - - - - - ]]> -

      - This example shows a more verbose formatting layout for the mail messages. -

      - - - - - - - - - - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.SmtpPickupDirAppender. -

      -

      - The SmtpPickupDirAppender is configured similarly - to the SmtpAppender. The only difference is that rather - than specify a SmtpHost parameter a PickupDir must be specified. -

      -

      - The PickupDir parameter is a path that must exist and the code executing the - appender must have permission to create new files and write to them in this directory. - The path is relative to the application's base directory (AppDomain.BaseDirectory). -

      -

      - The following example shows how to configure the SmtpPickupDirAppender - to deliver log events via SMTP email. The To, From, Subject and - PickupDir are required parameters. - This example shows how to deliver only significant events. A LevelEvaluator - is specified with a threshold of WARN. This means that an email - will be sent for each WARN or higher level message that is logged. - Each email will also contain up to 512 (BufferSize) previous messages of any level to - provide context. Messages not sent will be discarded. -

      - - - - - - - - - - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.TraceAppender. -

      -

      - The following example shows how to configure the TraceAppender - to log messages to the System.Diagnostics.Trace system. - This is the tracing system supplied with the .net base class libraries. - See the MSDN documentation for the System.Diagnostics.Trace - class for more details on how to configure the trace system. -

      - - - - - - ]]> -
      - -
      -

      - For full details see the SDK Reference entry: log4net.Appender.UdpAppender. -

      -

      - The following example shows how to configure the UdpAppender - to send events to a RemoteAddress on the specified RemotePort. -

      - - - - - - - - - ]]> -
      -
      - - -
      diff --git a/xdocs/src/release/example-apps.xml b/xdocs/src/release/example-apps.xml deleted file mode 100644 index 2a0e76a0..00000000 --- a/xdocs/src/release/example-apps.xml +++ /dev/null @@ -1,504 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Examples - - - - - - - - - -
      - - - -
      -

      - The following examples are only available in the log4net release download, not - on-line. To obtain the examples download one of the log4net releases. - -

      -
      - -
      -
      -

      - A single example can be build by running nant from - the example directory. -

      -

      - For example running nant in the - examples\net\1.0\Tutorials\ConsoleApp\cs directory - will build the C# version of the .NET 1.0 ConsoleApp example. -

      -

      - nant can be run in any directory containing a - nant.build file. The typical behavior of the build file - is to build all projects under the current directory. -

      -

      - For example running nant in the - examples\net\1.1 directory - will build all the examples for the .NET 1.1 platform. -

      -
      - -
      -

      - To build all the examples either run nant in the - examples directory or you can specify the - compile-examples target to the main log4net nant build. -

      -
      - -
      -

      - There are Visual Studio .NET 2002 project files for the .NET 1.0 framework. - The solution files for C# and VB are in the examples\net\1.0 - folder. -

      -

      - For the Managed C++ project there is a Visual Studio .NET 2003 project file - in the examples\net\1.1 folder. -

      -
      -
      - -
      - -
      -

      - ConsoleApp shows how to write a simple console application that initializes - logging and logs various events. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      - -

      - To run this example execute ConsoleApp.exe from the build output directory. -

      -
      - -
      -

      - ConsoleApp shows how to write a simple ASP.NET web application that initializes - logging and logs various events. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - .NET 1.0: - C#, - VB -
      • -
      -

      - To run this example you need to have an ASP.NET container application to - host the web application, for example IIS. In IIS create a new virtual - directory pointing to the WebApp src directory. Configure IIS to recognize - this virtual directory as an application. Open up a web browser, navigate to - the virtual directory and to the WebForm1.aspx page within it. -

      -
      - -
      -

      - The RemotingClient application is a simple console application that configures - log4net with the RemotingAppender. This appender will attempt to deliver the - logging events to a remoting listener. This example should be run in conjunction - with the RemotingServer. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - .NET 1.0: - C# -
      • -
      -

      - To run this example execute RemotingClient.exe from the build output directory. -

      -
      - -
      -

      - The RemotingServer application is a simple console application that listens for - logging events from a remote RemotingAppender and then logs them through the - local log4net instance. This example should be run in conjunction - with the RemotingClient. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - .NET 1.0: - C# -
      • -
      -

      - To run this example execute RemotingServer.exe from the build output directory. - While this process is running execute the RemotingClient.exe program on - the same machine. The logging events from the client are transferred to the server. -

      -
      - -
      -

      - The SimpleModule is a class library that is intended to be used as part of - the SimpleApp example, - This class library uses the log4net.Config.Repository - attribute to create a separate configuration space from other assemblies. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - MONO 1.0: - C# -
      • -
      • - .NET 1.0: - C#, - VB -
      • -
      • - .NET 1.1: - JScript.NET -
      • -
      • - SSCLI 1.0: - C# -
      • -
      -

      - This library is intended to be used as part of the SimpleApp example. -

      -
      - -
      -

      - The SharedModule is a class library that is intended to be used as part of - the SimpleApp example, - This class library uses log4net but does not attempt to configure logging. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - MONO 1.0: - C# -
      • -
      • - .NET 1.0: - C#, - VB -
      • -
      • - .NET 1.1: - JScript.NET -
      • -
      • - SSCLI 1.0: - C# -
      • -
      -

      - This library is intended to be used as part of the SimpleApp example. -

      -
      - -
      -

      - The SimpleApp example uses the SimpleModule and SharedModule to demonstrate - the ways in which multiple assemblies within the same process may be - separately configured. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - MONO 1.0: - C# -
      • -
      • - .NET 1.0: - C#, - VB -
      • -
      • - .NET 1.1: - JScript.NET -
      • -
      • - SSCLI 1.0: - C# -
      • -
      -

      - To run this example execute SimpleApp.exe from the build output directory. -

      -
      - -
      -

      - The EventIDLogApp example demonstrates using the log4net.Ext.EventID extension. - The extension needs to be built separately from the - extensions\net\1.0\log4net.Ext.EventID directory. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - .NET 1.0: - C# -
      • -
      -

      - To run this example execute EventIDLogApp.exe from the build output directory. -

      -
      - -
      -

      - The TraceLogApp example demonstrates using the log4net.Ext.Trace extension. - The extension needs to be built separately from the - extensions\net\1.0\log4net.Ext.Trace directory. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - .NET 1.0: - C# -
      • -
      -

      - To run this example execute TraceLogApp.exe from the build output directory. -

      -
      - -
      -

      - This project includes the following example appenders. -

      -
        -
      • - AsyncAppender -
      • -
      • - FastDbAppender -
      • -
      • - FireEventAppender -
      • -
      • - MessageBoxAppender -
      • -
      • - MessageObjectExpanderAppender -
      • -
      • - MsmqAppender -
      • -
      • - PatternFileAppender -
      • -
      • - SimpleSmtpAppender -
      • -
      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - .NET 1.0: - C# -
      • -
      -

      - To run this example execute SampleAppendersApp.exe from the build output directory. -

      -
      - -
      -

      - This project includes the following example layouts. -

      -
        -
      • - ForwardingLayout -
      • -
      • - LineWrappingLayout -
      • -
      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - .NET 1.0: - C# -
      • -
      -

      - To run this example execute SampleLayoutsApp.exe from the build output directory. -

      -
      - -
      -

      - The NotLogging example benchmarks the performance of log4net logging statements in - user code in various scenarios including when logging is disabled. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - MONO 1.0: - C# -
      • -
      • - .NET 1.0: - C#, - VB -
      • -
      -

      -

      -
      - -
      -

      - The WmiAppender sample shows an example appender that fires events through - Windows Management Instrumentation. -

      -

      - This example is available for the following platforms and languages. If a version - is not available for your chosen platform and language combination then select the - nearest platform for the appropriate language. -

      -
        -
      • - .NET 1.0: - C# -
      • -
      -

      -

      -
      - -
      - -
      - -
      diff --git a/xdocs/src/release/faq.xml b/xdocs/src/release/faq.xml deleted file mode 100644 index 18d905b5..00000000 --- a/xdocs/src/release/faq.xml +++ /dev/null @@ -1,969 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Frequently Asked Questions - - - - - -
      - - -
      - -
      -

      - log4net is a tool to help the programmer output log statements to a variety of - output targets. -

      -

      - In case of problems with an application, it is helpful to enable logging so - that the problem can be located. With log4net it is possible to enable logging at - runtime without modifying the application binary. The log4net package is designed - so that log statements can remain in production code without incurring a - high performance cost. It follows that the speed of logging (or rather not - logging) is crucial. -

      -

      - At the same time, log output can be so voluminous that it quickly becomes - overwhelming. One of the distinctive features of log4net (and common to all of - the log4x libraries) is the notion of hierarchical - loggers. Using these loggers it is possible to selectively control - which log statements are output at arbitrary granularity. -

      -

      - log4net is designed with two distinct goals in mind: speed and flexibility. There - is a tight balance between these two requirements. -

      -
      -

      Back to Top

      - - -
      -

      - No. log4net is not reliable. It is a best-effort and fail-stop logging system. -

      -

      - By fail-stop, we mean that log4net will not throw unexpected exceptions at - run-time potentially causing your application to crash. If for any reason, log4net - throws an uncaught exception (except for ArgumentException and - ArgumentNullException which may be thrown), please send an email - to the - log4net-user@logging.apache.org mailing list. Uncaught exceptions - are handled as serious bugs requiring immediate attention. -

      -

      - Moreover, log4net will not revert to System.Console.Out - or System.Console.Error when its designated - output stream is not opened, is not writable or becomes full. This avoids - corrupting an otherwise working program by flooding the user's terminal because - logging fails. However, log4net will output a single message to - System.Console.Error and System.Diagnostics.Trace - indicating that logging can not be performed. -

      -
      -

      Back to Top

      - - -
      -

      - log4net runs on many different frameworks and each framework has its own requirements. - As a rule of thumb you will need an ECMA-335 compliant CLI runtime, for example, - the Microsoft .NET runtime 1.0 (1.0.3705) or 1.1 (1.1.4322). -

      -

      - Not all frameworks are created equal and some features have been excluded from - some of the builds. See the Framework Support - document for more information. -

      -
      -

      Back to Top

      - - -
      -

      - There is a directory containing examples in log4net\examples. - The examples are broken down by framework. -

      -
      -

      Back to Top

      - - -
      -
        -
      • - log4net is optimized for speed.
      • -
      • - log4net is based on a named logger hierarchy.
      • -
      • - log4net is fail-stop but not reliable.
      • -
      • - log4net is thread-safe.
      • -
      • - log4net is not restricted to a predefined set of facilities.
      • -
      • - Logging behavior can be set at runtime using a configuration file. - Configuration files are in XML format.
      • -
      • - log4net is designed to handle exceptions from the start.
      • -
      • - log4net can direct its output to many sinks including: a file, the console, the NT EventLog or even e-mail.
      • -
      • - log4net categorizes logging into levels: DEBUG, INFO, WARN, ERROR and FATAL.
      • -
      • - The format of the log output can be easily changed by implementing a new layout class.
      • -
      • - The target of the log output as well as the writing strategy can be altered by - writing a new appender class.
      • -
      • - log4net supports multiple output appenders per logger.
      • -
      -

      - See the features overview document for more information on the features of log4net. -

      -
      -

      Back to Top

      - - -
      -

      - Yes, log4net is thread-safe. -

      -
      -

      Back to Top

      - - -
      -

      - The log output can be customized in many ways. Moreover, one can completely - override the output format by implementing one's own ILayout -

      -

      - Here is an example output using PatternLayout with the conversion - pattern %timestamp [%thread] %-5level %logger{2} %ndc - %message%newline -

      - -

      - The first field is the number of milliseconds elapsed since the start of the - program. The second field is the thread outputting the log statement. The third - field is the level of the log statement. The fourth field is the rightmost - two components of the name of the logger making the log request. The fifth field (just - before the '-') is the nested diagnostic context (NDC). Note the - nested diagnostic context may be empty as in the first two statements. The text - after the '-' is the message of the statement. -

      -
      -

      Back to Top

      - - -
      -

      - The logger concept lies at the heart of log4net's configuration. Loggers are organized into a - hierarchy and give the programmer run-time control on which logging statements - are printed or not. -

      -

      - Loggers are assigned levels through the configuration of log4net. A log statement is - routed through to the appender depending on its level and its logger. -

      -
      -

      Back to Top

      - - -
      -

      - Contrary to the GNU Public License (GPL) the Apache Software License does not - make any claims over your extensions. By extensions, we mean totally new code - that invokes existing log4net code. You are free to do whatever you wish with - your proprietary log4net extensions. In particular, you may choose to - never release your extensions to the wider public. For details see the - Apache License, Version 2.0. -

      -

      - We are very careful not to unnecessarily change the log4net client API so that newer log4net - releases are backward compatible with previous versions. We are a lot less - scrupulous with the internal log4net API. Thus, if your extension is designed to - work with the internals of a specific log4net version, then when the next release - of log4net comes out, you will probably need to adapt your proprietary extensions to the - new release. Thus, you will be forced to spend precious resources in order to - keep up with log4net changes. This is commonly referred to as the "stupid-tax". - By donating the code and making it part of the standard distribution, you save - yourself the unnecessary maintenance work. -

      -

      - If your extensions are useful then someone will eventually write an extension - providing the same or very similar functionality. Your development effort will - be wasted. -

      -

      - Unless the proprietary log4net extension is business critical, there is little - reason for not donating your extensions back to the project. -

      -
      -

      Back to Top

      - - -
      -
        -
      1. - Stick to the existing indentation style even if you hate it. -

        - Alternating between indentation styles makes it hard to understand the source - code. Make it hard on yourself but easier on others. -

        -
      2. -
      3. - Thoroughly test your code. -

        - There is nothing more irritating than finding the bugs in debugging (i.e. logging) code. -

        -
      4. -
      5. - Keep it simple, small and fast. -

        - It's all about the application not about logging. -

        -
      6. -
      7. - Did I mention sticking with the indentation style?
      8. -
      -
      -

      Back to Top

      - - -
      -

      - As fast as they get reported ;-) -

      -
      -

      Back to Top

      - - -
      -

      - log4net is a port of the popular log4j logging library. - The initial port was done in June 2001, since then we have tried to remain in the - spirit of the original log4j. See the log4net history page for more details. -

      -
      -

      Back to Top

      - - -
      -

      - The log4net home page is a good place to start. -

      -
      -

      Back to Top

      - -
      - -
      - -
      -

      - Logging behavior can be set using configuration files which are parsed at runtime. - Using configuration files the programmer can define loggers and set their - levels. -

      -

      - Configuration files are specified in XML. See log4net.Config.XmlConfigurator - for more details. -

      -

      - See the various log4net.Layout and log4net.Appender - components for specific configuration options. -

      -
      -

      Back to Top

      - - -
      -

      - Setting the Threshold on the Hierarchy to Level OFF will disable all - logging from that Hierarchy. This can be done in the log4net configuration file - by setting the "threshold" attribute on the log4net configuration element to "OFF". - For example: -

      - ]]> -
      -

      Back to Top

      - -
      -

      - log4net uses public properties to configure components such as - Appenders, Layouts, Loggers etc. -

      -

      - Thus, any writable public property in on the appender corresponds to a - configurable option. For example, in RollingFileAppender the - public int MaxSizeRollBackups { set; } property corresponds to - the MaxSizeRollBackups option. -

      -

      - Layouts options are also defined by their writable properties. Same goes for most - other log4net components. -

      -
      -

      Back to Top

      - - -
      -

      - Yes it is. Setting the Threshold option of any appender extending - AppenderSkeleton, (most log4net appenders extend - AppenderSkeleton) will filter out all log events - with a lower level than the value of the threshold option. -

      -

      - For example, setting the threshold of an appender to DEBUG will also allow INFO, - WARN, ERROR and FATAL messages to log along with DEBUG messages. (DEBUG is the - lowest level). This is usually acceptable as there is little use for DEBUG - messages without the surrounding INFO, WARN, ERROR and FATAL messages. - Similarly, setting the threshold of an appender to ERROR will filter out DEBUG, - INFO and WARN messages but not ERROR or FATAL messages. -

      -

      - This policy usually best encapsulates what the user actually wants to do, as - opposed to her mind-projected solution. -

      -

      - If you must filter events by exact level match, then you can attach a - LevelMatchFilter to any appender to filter out logging - events by exact level match. -

      -
      -

      Back to Top

      - - -
      -

      - Yes. The XmlConfigurator supports automatic - reloading through the ConfigureAndWatch APIs. See the API - documentation for more details. -

      -
      -

      Back to Top

      - - -
      -

      - Yes. When specifying the type in the configuration file you can give the assembly - qualified name of the type. For example: -

      - ]]> -

      - The .NET runtime will try to locate the assembly called MyAssembly. - How .NET locates assemblies is beyond the scope of this FAQ. -

      -

      - When loading an assembly from the GAC the fully qualified assembly name, - including the version, culture and public key must be specified. This is - in the standard syntax supported by System.Type.GetType. - See the next FAQ on how to get the version and public key for an assembly. -

      -
      -

      Back to Top

      - - -
      -

      - The fully qualified name for an assembly includes the version, culture and - public key. The public key is derived from the strong name used to identify - the publisher. When referencing an assembly from the GAC the fully qualified - name must be used. To get the version, culture and public key you can use a - tool like the excellent .NET Reflector from Lutz Roeder available from - http://www.aisto.com/roeder/dotnet. -

      -
      -

      Back to Top

      - - -
      -

      - Newlines in the config file need to be escaped using an XML numeric character reference. - The sequence that represents a CR LF is &#13; &#10;. The following example adds - a header and footer to the output each followed by a newline. -

      - -
      -
      - -]]> -
      -

      Back to Top

      - - -
      -

      - Log4net supports a pattern syntax for setting string properties similar to the - PatternLayout used to format the output messages. - This pattern syntax can be used by specifying type="log4net.Util.PatternString" - on the string property in the config file. This tells the config parser to pass the - value to the PatternString type before converting the result - to a string. For details on the patterns supported see the - PatternString SDK Reference. -

      -

      - The following example sets the file name for a FileAppender to include the - current process id by specifying the %processid pattern in the - File property. -

      - - - -]]> -
      -

      Back to Top

      - - -
      - -
      - -
      -

      - Yes, there are. -

      -

      - You can name logging loggers by locality. It turns out that - instantiating a logger in each class, with the logger name equal to the - fully-qualified name of the class, is a useful and straightforward approach of - defining loggers. This approach has many benefits: -

      -
        -
      • - It is very simple to implement.
      • -
      • - It is very simple to explain to new developers.
      • -
      • - It automatically mirrors your application's own modular design.
      • -
      • - It can be further refined at will.
      • -
      • - Printing the logger automatically gives information on the locality of the - log statement.
      • -
      -

      - However, this is not the only way for naming loggers. A common alternative - is to name loggers by functional areas. For example, the - "database" logger, "remoting" logger, "security" logger, or the "XML" - logger. -

      -

      - You may choose to name loggers by functionality and subcategorize by - locality, as in "DATABASE.MyApp.MyClass" or - "DATABASE.MyApp.MyModule.MyOtherClass". -

      -

      - You are totally free in choosing the names of your loggers. The - log4net package merely allows you to manage your names in a hierarchy. However, - it is your responsibility to define this hierarchy. -

      -

      - Note: by naming loggers by locality one tends to name things by - functionality, since in most cases the locality relates closely to - functionality. -

      -
      -

      Back to Top

      - - -
      -

      - You can easily retrieve the fully-qualified name of a class in a static block - for class X, with the statement typeof(X).Name. - Note that X is the class name and span an instance. - However because the LogManager.GetLogger method is overloaded - to take an instance of Type as well as string - usually only the type of the class is required. -

      -

      - Here is the suggested usage template: -

      - -

      - An equivalent and more portable solution, though slightly longer, is to use the declaring type - of the static constructor. -

      - -

      - Note: the .NET Compact Framework 1.0 does not support System.Reflection.MethodBase.GetCurrentMethod(). -

      -
      -

      Back to Top

      - - -
      -

      - For some logger log, writing, -

      - -

      - incurs the cost of constructing the message parameter, that is converting both - integer i and entry[i] to - a string, and concatenating intermediate strings. This, regardless of whether - the message will be logged or not. -

      -

      - If you are worried about speed, then write -

      - -

      - This way you will not incur the cost of parameter construction if debugging is - disabled for logger log. On the other hand, if the logger is - debug enabled, you will incur the cost of evaluating whether the logger is - enabled or not, twice: once in IsDebugEnabled and once in Debug. - This is an insignificant overhead since evaluating a logger takes less than - 1% of the time it takes to actually log a statement. -

      -
      -

      Back to Top

      - - -
      -

      - So you don't think that the previous FAQ is really the fastest way - of not logging? Well there is a faster way but it does have some - drawbacks. Starting from: -

      - -

      - It is possible to further eliminate the calls to IsDebugEnabled - so that the call is only made once per logger. If you are using one logger - for each class then you can store the enabled state for the logger in a static - variable in the class and then test against this variable: -

      - -

      - So why exactly is this faster? Well to start with the IsDebugEnabled - is not called for each log statement, it is called once per logger. Furthermore as the - isDebugEnabled variable is private static readonly - the JIT compiler can at run-time optimize out the if test altogether. - This means that at runtime the JIT compiler won't even compile the logging statements into native code, i.e. - all the logging just disappears. -

      -

      - So what is the downside to using this? Well one of the clever features of log4net is that - you can change the logging configuration while your program is running. If you need to - investigate an issue in your application, you don't have to stop the application, setup the - logging and restart the application, you can change the logging configuration and the - log4net will reload it (see XmlConfigurator.ConfigureAndWatch APIs for more - information). However if the JIT has compiled out all of the logging statements - then they are gone and you can't get them back by reloading the configuration file. Effectively - this means that the logging configuration can only be set when the application loads and - it cannot be changed at runtime. It is up to you to decide if you need ultimate speed or need - to be able to reload the logging configuration while the application is running. -

      -
      -

      Back to Top

      - - -
      -

      - Many developers are confronted with the problem of distinguishing the log - output originating from the same class but different client requests. They come - up with ingenious mechanisms to fan out the log output to different files. In - most cases, this is not the right approach. -

      -

      - It is simpler to use a context property or stack (ThreadContext). - Typically, one would ThreadContext.Properties["ID"] = "XXX" - client specific information, such as the client's hostname, ID or any other - distinguishing information when starting to handle the client's request. - Thereafter, log output will automatically include the context data - so that you can distinguish logs from different client requests even if they - are output to the same file. -

      -

      - See the ThreadContext and the PatternLayout classes for more - information. -

      -
      -

      Back to Top

      - - -
      -

      - It is quite nontrivial to define the semantics of a "removed" logger which is - still referenced by the user. -

      -
      -

      Back to Top

      - - -
      -

      - By default the FileAppender holds an exclusive write - lock on the log file while it is logging. This prevents other processes from - writing to the file. The FileAppender can be configured - to use a different locking model, MinimalLock, that - only acquires the write lock while a log is being written. This allows multiple - processes to interleave writes to the same file, albeit with a loss in performance. - See the FileAppender config examples - for an example MinimalLock configuration. -

      -

      - While the MinimalLock model may be used to interleave - writes to a single file it may not be the optimal solution, especially when - logging from multiple machines. Alternatively you may have one or more processes - log to RemotingAppenders. - Using the RemoteLoggingServerPlugin (or - IRemoteLoggingSink) a process can receive all the events and - log them to a single log file. -

      -
      -

      Back to Top

      - - -
      -

      - The timestamp is created when the logging event is created. That is so say, - when the Debug, Info, - Warn, Error - or Fatal method is invoked. This is unaffected by the time at - which they may arrive at a remote server. Since the timestamps are - transmitted in UTC format by the RemotingAppender, - they all appear in the same time zone as - the host creating the logfile. Since the clocks of various machines may not be - synchronized, this may account for time interval inconsistencies between events - generated on different hosts. -

      -
      -

      Back to Top

      - - -
      -

      - The simple answer is as soon as possible. The long answer is more complex. -

      -

      - If you are configuring log4net programmatically, i.e. by calling the - XmlConfigurator.Configure method then you should do so - before you begin logging and it is reasonable to do this very soon after application - start. -

      -

      - If you are configuring log4net by specifying assembly level attributes on - your assembly then the configuration will be loaded once the first call to - the LogManager.GetLogger is made. It is necessary - that the first call to LogManager.GetLogger made - during the process (or AppDomain) is made from the assembly that has the - configuration attributes. Log4net will look only once and only on the first - calling assembly for the configuration attributes. -

      -
      -

      Back to Top

      - - -
      - -
      - -
      -

      - Yes. You can implement the log4net.Layout.ILayout - interface to create you own customized log format, or you can extend the - LayoutSkeleton class which provides a default - implementation of the ILayout interface. - Appenders can be parameterized to use the layout of your choice. -

      -
      -

      Back to Top

      - - -
      -

      - Yes. You can implement the log4net.Appender.IAppender - interface to create you own customized appender. We recommend that you extend the - log4net.Appender.AppenderSkeleton class rather than - starting from scratch. You should implement your custom code in a assembly - separate from the log4net assembly. To get started it is worth looking at the - source of the log4net.Appender.TraceAppender as an - example of the minimum amount of code required to get an appender working. -

      -

      - To configure log4net to use your custom appender you need to specify the - assembly qualified name of the appender type in the config file. For - example: -

      - ]]> -

      - The .NET runtime will try to locate the assembly called MyAssembly. - How .NET locates assemblies is beyond the scope of this FAQ. -

      -
      -

      Back to Top

      - -
      - -
      - -
      -

      - There are 2 different ways to enable internal debugging in log4net. - These are listed below. The preferred method is to specify - the log4net.Internal.Debug option in the application's - config file. -

      -
        -
      • -

        - Internal debugging can also be enabled by setting a value in the application's - configuration file (not the log4net configuration file, unless the log4net config - data is embedded in the application's config file). The log4net.Internal.Debug - application setting must be set to the value true. - For example: -

        -
        -<?xml version="1.0" encoding="utf-8" ?>
        -<configuration>
        -    <appSettings>
        -        <add key="log4net.Internal.Debug" value="true"/>
        -    </appSettings>
        -</configuration>
        -

        - This setting is read immediately on startup an will cause all internal - debugging messages to be emitted. -

        -
      • -
      • -

        - To enable log4net's internal debug programmatically you need - to set the log4net.Util.LogLog.InternalDebugging - property to true. Obviously the sooner this - is set the more debug will be produced. -

        -
      • -
      -

      - Internal debugging messages are written to the console and to the - System.Diagnostics.Trace - system. If the application does not have a console the messages logged - there will be lost. Note that an application can redirect the console - stream by setting the System.Console.Out. The - Trace system will by default send the message to an attached debugger - (where the messages will appear in the output window). If the process - does not have a debugger attached then the messages are sent to the - system debugger. A utility like DebugView from - http://www.sysinternals.com - may be used to capture these messages. -

      -

      - As log4net internal debug messages are written to the System.Diagnostics.Trace - system it is possible to redirect those messages to a local file. You can define - a trace listener by adding the following to your application's .config file: -

      -
      -<configuration>
      -    ...
      -    
      -    <system.diagnostics>
      -        <trace autoflush="true">
      -            <listeners>
      -                <add 
      -                    name="textWriterTraceListener" 
      -                    type="System.Diagnostics.TextWriterTraceListener" 
      -                    initializeData="C:\tmp\log4net.txt" />
      -            </listeners>
      -        </trace>
      -    </system.diagnostics>
      -
      -    ...
      -</configuration>
      -

      - Make sure that the process running your application has permission - to write to this file. -

      -
      -

      Back to Top

      - - -
      -

      - If you are not getting events delivered to the event log this usually indicates - a permissions problem. Basically if the event log does not exist the EventLogAppender - tries to create it, but you need local administrator permissions to create event logs - (just to write into the right bit of the registry). You don't need administrator - permissions to log to an existing event log, but it must exist. If you are using the - event log from a web application or service using the event log can be a little tricky. -

      -

      - A web application will run as the user account ASPNET. This account deliberately has - few permissions to reduce the chances of someone hacking into the web server. While the - account has permission to write to the event log it does not have permission to create - event sources (registry create and write access), which are needed to write to the event log. -

      -

      - There are a couple of solutions: -

      -
        -
      1. -

        - Make the ASPNET user a member of the Administrators group. This will work because the - user will then have the required permissions. This is not recommended - for production use. -

        -
      2. -
      3. -

        - As the event source only needs to be created once for the machine, create an installer - and configure it to create the event source. - The installer will need to be run as Administrator (don't they all). See - System.Diagnostics.EventLogInstaller in the Microsoft .NET - Framework SDK for an example of how to create a simple event log installer. -

        -
      4. -
      -

      - There is a Microsoft Knowledge Base article that covers this issue and how to resolve - it. - PRB: "Requested Registry Access Is Not Allowed" Error Message When ASP.NET - Application Tries to Write New EventSource in the EventLog. -

      -
      -

      Back to Top

      - - -
      -

      - The web application runs as a special user account on the web server - called ASPNET. This account has restricted permissions to protect the - web server from attacks. By default this account may not have permission - to write to the file system. Make sure that the ASPNET account has - permission to create and write to files in the directory chosen for - logging. -

      -
      -

      Back to Top

      - - -
      -

      - A windows service runs as a user account specified in the services - control panel. This account may have restricted permissions, make - sure that the account has permission to create and write to files - in the directory chosen for logging. -

      -

      - A windows service is launched by windows. The current directory in - a service is set to the windows system directory (e.g. - C:\Windows\System32). If you are loading - the configuration file from the current directory then be aware - that this path will not be the location of your assemblies. - The best way to get the path to your assemblies is to use - AppDomain.BaseDirectory. - Note that the log4net internals never use the current directory. -

      -
      -

      Back to Top

      - - -
      -

      - For details on the different ways in which ADO.NET can connect to a database see: - Connecting to a Data Source Using ADO.NET. -

      -

      - If you need to use ODBC to connect to your database then please note that the - ADO.NET ODBC drivers are not included in the standard .NET framework redistributable. - You can download the drivers from microsoft download at: - ODBC .NET Data Provider. -

      -
      -

      Back to Top

      - - -
      -

      - See the support page for details. -

      -
      -

      Back to Top

      - - -
      - -
      - -
      -

      - There is a good discussion of this topic on Robert McLaws blog: - Building a Better Server Control Experience, Part 2. -

      -
      -

      Back to Top

      - -
      - -
      - - -
      diff --git a/xdocs/src/release/features.xml b/xdocs/src/release/features.xml deleted file mode 100644 index 616fa089..00000000 --- a/xdocs/src/release/features.xml +++ /dev/null @@ -1,284 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Features - - - - - -
      - - - -
      -

      - log4net is a tool to help the programmer output log statements to a - variety of output targets. In case of problems with an application, - it is helpful to enable logging so that the problem can be located. - With log4net it is possible to enable logging at runtime without - modifying the application binary. The log4net package is designed so - that log statements can remain in shipped code without incurring a - high performance cost. It follows that the speed of logging (or - rather not logging) is crucial. -

      -

      - At the same time, log output can be so voluminous that it quickly becomes - overwhelming. One of the distinctive features of log4net is the notion of - hierarchical loggers. Using these loggers it is possible to selectively - control which log statements are output at arbitrary granularity. -

      -

      - log4net is designed with two distinct goals in mind: speed and flexibility -

      -
      - -
      -
        -
      • Support for multiple frameworks

      • -
      • Output to multiple logging targets

      • -
      • Hierarchical logging architecture

      • -
      • XML Configuration

      • -
      • Dynamic Configuration

      • -
      • Logging Context

      • -
      • Proven architecture

      • -
      • Modular and extensible design

      • -
      • High performance with flexibility

      • -
      -
      - -
      -

      - log4net runs on all ECMA CLI 1.0 compatible runtimes. - log4net has specific builds for the following frameworks: -

      -
        -
      • Microsoft .NET Framework 1.0 (1.0.3705)
      • -
      • Microsoft .NET Framework 1.1 (1.1.4322)
      • -
      • Microsoft .NET Framework 2.0 (2.0.50727)
      • -
      • Microsoft .NET Compact Framework 1.0
      • - -
      • Mono 1.0
      • -
      • Mono 2.0
      • -
      • Microsoft Shared Source CLI 1.0
      • -
      • CLI 1.0 Compatible
      • -
      -

      - Note: Due to the .NET frameworks support for backward compatibility - log4net will run on future versions of the runtimes listed above. -

      -
      - -
      -

      - log4net ships with the following appenders (not on all frameworks): -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Type - Description
      log4net.Appender.AdoNetAppender - Writes logging events to a database using either prepared statements or stored - procedures. -
      log4net.Appender.AnsiColorTerminalAppender - Writes color highlighted logging events to a an ANSI terminal window. -
      log4net.Appender.AspNetTraceAppender - Writes logging events to the ASP trace context. These can then be rendered at - the end of the ASP page or on the ASP trace page. -
      log4net.Appender.ColoredConsoleAppender - Writes color highlighted logging events to the application's Windows Console. -
      log4net.Appender.ConsoleAppender - Writes logging events to the application's Console. The events may go to either - the standard our stream or the standard error stream. -
      log4net.Appender.EventLogAppender - Writes logging events to the Windows Event Log. -
      log4net.Appender.FileAppender - Writes logging events to a file in the file system. -
      log4net.Appender.LocalSyslogAppender - Writes logging events to the local syslog service (UNIX only). -
      log4net.Appender.MemoryAppender - Stores logging events in an in memory buffer. -
      log4net.Appender.NetSendAppender - Writes logging events to the Windows Messenger service. These messages are - displayed in a dialog on a users terminal. -
      log4net.Appender.OutputDebugStringAppender - Writes logging events to the debugger. If the application has no - debugger, the system debugger displays the string. If the application has no - debugger and the system debugger is not active, the message is ignored. -
      log4net.Appender.RemoteSyslogAppender - Writes logging events to a remote syslog service using UDP networking. -
      log4net.Appender.RemotingAppender - Writes logging events to a remoting sink using .NET remoting. -
      log4net.Appender.RollingFileAppender - Writes logging events to a file in the file system. The RollingFileAppender can - be configured to log to multiple files based upon date or file size - constraints. -
      log4net.Appender.SmtpAppender - Sends logging events to an email address. -
      log4net.Appender.TelnetAppender - Clients connect via Telnet to receive logging events. -
      log4net.Appender.TraceAppender - Writes logging events to the .NET trace system. -
      log4net.Appender.UdpAppender - Sends logging events as connectionless UDP datagrams to a remote host or a - multicast group using a UdpClient. -
      -
      -

      -

      - -
      -

      - Hierarchical logging is an ideal fit with component based development. - Each component has its own of logger. When individually tested, the - properties of these loggers may be set as the developer requires. - When combined with other components, the loggers inherit the properties - determined by the integrator of the components. One can selectively elevate - logging priorities on one component without affecting the other components. - This is useful when you need a detailed trace from just a single component - without crowding the trace file with messages from other components. All - this can be done through configuration files; no code changes are required. -

      -
      - -
      -

      - log4net is configured using an XML configuration file. The configuration - information can be embedded within other XML configuration files - (such as the application's .config file) or in a separate file. The - configuration is easily readable and updateable while retaining the - flexibility to express all configurations. -

      -

      - Alternatively log4net can be configured programmatically. -

      -
      - -
      -

      - log4net can monitor its configuration file for changes and dynamically - apply changes made by the configurator. The logging levels, appenders, - layouts, and just about everything else can be adjusted at runtime. - In many cases it is possible to diagnose application issues without - terminating the process in question. This can a very valuable tool in - investigating issues with deployed applications. -

      -
      - -
      -

      - log4net can be used to collect logging context data in a way that is transparent - to the developer at the point of logging. The GlobalContext and the - ThreadContext allow the application to store contextual data that is - attached to logging messages. For instance, in a web service, - once the caller is authenticated the username of the caller could be - stored in a ThreadContext property. This property would then be automatically - logged as part of each subsequent logging message made from the same thread. -

      -
      - -
      -

      - log4net is based on the highly successful log4j logging library, - in development since 1996. This popular and proven architecture has - so far been ported to 12 languages. -

      -
      - -
      - -
      diff --git a/xdocs/src/release/framework-support.xml b/xdocs/src/release/framework-support.xml deleted file mode 100644 index f8d14e81..00000000 --- a/xdocs/src/release/framework-support.xml +++ /dev/null @@ -1,592 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Supported Frameworks - - - - - -
      - - - -
      -

      - log4net is built on a number of different frameworks. Each new version of the frameworks add - new features. To take advantage of these new features we must build log4net using the - appropriate framework. We also maintain builds compatible with older versions of the frameworks. -

      -

      - It is important to remember that the .NET frameworks support backward compatibility, that is - a new version of the framework will run binary assemblies that were targeted to previous versions - of the framework. -

      -

      - While the number of different builds available may seem confusing, you only need to select the - nearest build for your platform that is equal to or earlier than your chosen deployment framework. - If you intend to deploy your application on the Microsoft .NET Framework 1.0 don't pick the - log4net build that is built against the Microsoft .NET Framework 1.1 because the .NET framework - does not guarantee forward compatibility only backward compatibility. -

      -

      - The lowest common denominator build is the CLI 1.0 Compatible build. This build is compatible with - the ECMA/ISO CLI 1.0 standard APIs and will run on all frameworks that support the standard. (Note - that the Microsoft .NET Compact Framework does not support this standard). Use this build if you - intend to deploy you application on both the Microsoft .NET Frameworks and the Mono frameworks. -

      -

      - log4net now builds on 6 frameworks: -

      - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      FrameworkWebsite
      Microsoft .NET Framework 1.0 (1.0.3705)http://msdn.microsoft.com/net
      Microsoft .NET Framework 1.1 (1.1.4322)http://msdn.microsoft.com/net
      Microsoft .NET Framework 2.0 (2.0.50727)http://msdn.microsoft.com/net
      Microsoft .NET Compact Framework 1.0http://msdn2.microsoft.com/en-us/netframework/aa497273.aspx
      Microsoft .NET Compact Framework 2.0http://msdn2.microsoft.com/en-us/netframework/aa497273.aspx
      Mono 1.2.3http://www.mono-project.com
      Microsoft Shared Source CLI 1.0http://msdn.microsoft.com/library/en-us/dndotnet/html/mssharsourcecli.asp
      CLI 1.0 Compatiblehttp://msdn.microsoft.com/net/ecma/
      -
      -

      - For each of these frameworks a log4net assembly targeting the framework is supplied. Although it's - perfectly possible to use the .NET Framework 1.0 version of log4net on the .NET Framework 1.1, having - an assembly that really targets a specific framework allows us to use features in that framework that - are not available in other frameworks or remove features from log4net that are not supported in a - specific framework. -

      -
      - -
      -

      - The appenders available to each framework depend on the functionality of the - framework and the platform it runs on: -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Appender.NET Framework 1.0.NET Framework 1.1.NET Framework 2.0.NET CF 1.0Mono 1.2Shared Source CLI 1.0CLI 1.0 Compatible
      AdoNetAppenderxxxxxx
      AnsiColorTerminalAppenderxxxxxxx
      AspNetTraceAppenderxxxxx
      BufferingForwardingAppenderxxxxxxx
      ColoredConsoleAppenderxxx
      ConsoleAppenderxxxxxxx
      DebugAppenderxxxxxxx
      EventLogAppenderxxxxx
      FileAppenderxxxxxxx
      ForwardingAppenderxxxxxxx
      LocalSyslogAppenderxxxxx
      MemoryAppenderxxxxxxx
      NetSendAppenderxxx
      OutputDebugStringAppenderxxxx
      RemoteSyslogAppenderxxxxxxx
      RemotingAppenderxxxxxx
      RollingFileAppenderxxxxxxx
      SmtpAppenderxxxxx
      SmtpPickupDirAppenderxxxxxxx
      TelnetAppenderxxxxxxx
      TraceAppenderxxxxxxx
      UdpAppenderxxxxxxx
      -
      -
      - -
      -
      -

      - none -

      -
      - -
      -

      - none -

      -
      - -
      -

      - none -

      -
      - -
      -
        -
      • -

        Assembly attributes

        -

        - The .NET Compact Framework 1.0 does not support retrieving assembly level - attributes, therefore all log4net configuration attributes were removed from - the .NET Compact Framework 1.0 version of log4net. -

        -

        - For Smart-device applications, the log4net system can be configured by passing - the location of the log4net configuration file to the - log4net.Config.XmlConfigurator.Configure(FileInfo) - method in the entry point of the application. -

        -

        For example:

        -

        -

        -namespace TestApp
        -{
        -    using System.IO;
        -
        -    public class EntryPoint
        -    {
        -        /// <summary>
        -        /// Application entry point.
        -        /// </summary>
        -        public static void Main() 
        -        {
        -            // Uncomment the next line to enable log4net internal debugging
        -            // log4net.Util.LogLog.InternalDebugging = true;
        -
        -            // This will instruct log4net to look for a configuration file
        -            // called config.log4net in the root directory of the device
        -            log4net.Config.XmlConfigurator.Configure(new FileInfo(@"\config.log4net"));
        -
        -            ...
        -            
        -            // This will shutdown the log4net system
        -            log4net.LogManager.Shutdown();
        -        }
        -    }
        -}                        
        -                            
        -
      • -
      • -

        Notification events

        -

        - The .NET Compact Framework 1.0 does not support notification events during the - application shutdown, therefore log4net cannot automatically hook the - application shutdown notification. -

        -

        - Applications will need to programmatically shutdown the log4net system during - the application's shutdown using the - log4net.LogManager.Shutdown() - method in order to prevent losing logging events. - See the code above for an example. -

        -
      • -
      • -

        FileSystemWatcher

        -

        - The .NET Compact Framework 1.0 does not support the - System.IO.FileSystemWatcher - class. As a result, the - XmlConfiguratorAttribute.Watch - property and the - XmlConfigurator.ConfigureAndWatch - methods are not available. Watching changes to the log4net configuration - file is not supported on the .NET Compact Framework 1.0. -

        -
      • -
      • -

        UserName

        -

        - The .NET Compact Framework 1.0 does not support the - System.Security.Principal.WindowsIdentity class. - This is used to capture the current thread's user identity. Therefore - the LoggingEvent.UserName property will return the value - "NOT AVAILABLE". -

        -
      • -
      • -

        Identity

        -

        - The .NET Compact Framework 1.0 does not support the - System.Security.Principal.IPrincipal interface. - This is used to capture the current thread's user identity. Therefore - the LoggingEvent.Identity property will return the value - "NOT AVAILABLE". -

        -
      • -
      • -

        Environment variables

        -

        - The .NET Compact Framework 1.0 does not support retrieving environment - variables, therefore it's not possible to substitute environment variables in - parameter values when using the .NET Compact Framework 1.0 version of log4net. -

        -
      • -
      • -

        Serialization

        -

        - The .NET Compact Framework 1.0 does not support serialization, therefore none of - the log4net classes in the .NET Compact Framework 1.0 version are serializable. -

        -
      • -
      • -

        LoggingEvent.Domain

        -

        - The .NET Compact Framework 1.0 does not support AppDomain functionality. The - friendly name for the current AppDomain is stored in the LoggingEvent.Domain - property and is accessed using the %a pattern of the - PatternLayout. On the .NET Compact Framework 1.0 this - value is generated by taking the file name for the application's primary module. -

        -
      • -
      -
      - -
      -

      - There are 2 separate builds of log4net for mono; Mono 1.0, built using the C# compiler in a mode - which is compatible with the CLI 1.0 language specification, and; Mono 2.0, built using the .NET - 2.0 extensions to the C# language. -

      - -
      -

      - none -

      -
      -
      -

      - none -

      -
      - -
      - -
      -
        -
      • -

        FileSystemWatcher

        -

        - SSCLI 1.0 does not support the - System.IO.FileSystemWatcher - class. As a result, the - XmlConfiguratorAttribute.Watch - property and the - XmlConfigurator.ConfigureAndWatch - methods are not available. Watching changes to the log4net configuration - file is not supported on SSCLI 1.0. -

        -
      • -
      • -

        UserName

        -

        - SSCLI 1.0 does not support the - System.Security.Principal.WindowsIdentity class. - This is used to capture the current thread's user identity. Therefore - the LoggingEvent.UserName property will return the value - "NOT AVAILABLE". -

        -
      • -
      • -

        Identity

        -

        - SSCLI 1.0 does not support the - System.Security.Principal.IPrincipal interface. - This is used to capture the current thread's user identity. Therefore - the LoggingEvent.Identity property will return the value - "NOT AVAILABLE". -

        -
      • -
      -
      - -
      -

      - This build of log4net is designed to run on any ECMA CLI 1.0 compatible runtime. - The assembly does not support any platform specific features. The build includes - the common subset of functionality found in the .NET 1.0 and Mono 1.0 builds. - The output assembly is built using the Microsoft .NET 1.0 compiler and library. -

      -

      - The log4net CLI 1.0 assembly is runtime compatible with the following frameworks: -

      -
        -
      • Microsoft .NET Framework 1.0 (and higher)
      • -
      • Mono 1.0 (and higher)
      • -
      -

      - Only a Release build is generated for this configuration because the assembly - debugging information has not been standardized. -

      -
      - -
      - -
      - - -
      diff --git a/xdocs/src/release/howto/chainsaw.xml b/xdocs/src/release/howto/chainsaw.xml deleted file mode 100644 index 8ad6f17e..00000000 --- a/xdocs/src/release/howto/chainsaw.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - Ron Grabowski - Nicko Cadell - Apache log4net: How To view logging events using Apache log4j Chainsaw - - - - - -
      - - -

      - Apache log4j includes Chainsaw - a graphical log viewer. -

      -

      - Chainsaw can either receive and display log events in realtime over - the network, or it can load a previously created log file. -

      - -

      - Before Chainsaw can display data, one or more receivers must be setup. - This is usually done by specifying an xml config file when the program - first starts up.
      - Save one or more of the sample xml config files to your local system and - load them when Chainsaw starts. -

      - -
      -

      - log4net can be configured to log messages via UDP in such a way that Chainsaw - can receive and display them. -

      - -
      -

      - Configure log4net to use a UdpAppender with the following config snippet: -

      - - - - - - - -]]> -
      - -
      -

      - Chainsaw should be configured to start a UDPReceiver using the - following configuration document: -

      - - - - - - - -]]> -
      - -
      - -
      -

      - Chainsaw can also load an XML log file if it is formatted according - to the log4j schema. Use the following log4net config to output - to file using the log4j schema: -

      - - - - - - - -]]> - -

      - To load the file into Chainsaw drag the file into the Chainsaw - app and drop it on the tab labeled Drag & Drop log files here. -

      -
      - -
      - -
      diff --git a/xdocs/src/release/howto/index.xml b/xdocs/src/release/howto/index.xml deleted file mode 100644 index 0cbb9622..00000000 --- a/xdocs/src/release/howto/index.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: How Tos - - - - - -
      - -

      - Below are presented, in no particular order, a series of documents - on how to get stuff done. -

      -

      - New documents can be contributed via the issue tracking system. - See the Contributing page for - details. -

      - - - -
      - -
      diff --git a/xdocs/src/release/manual/configuration.xml b/xdocs/src/release/manual/configuration.xml deleted file mode 100644 index 7d9be6e3..00000000 --- a/xdocs/src/release/manual/configuration.xml +++ /dev/null @@ -1,1207 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net Manual: Configuration - - - - - -
      - - - -
      -

      - Inserting log requests into the application code requires a fair amount of - planning and effort. Observation shows that approximately 4 percent of code is - dedicated to logging. Consequently, even moderately sized applications will - have thousands of logging statements embedded within their code. Given their - number, it becomes imperative to manage these log statements without the need - to modify them manually. -

      -

      - The log4net environment is fully configurable programmatically. However, it is - far more flexible to configure log4net using configuration files. Currently, - configuration files are written in XML. -

      -

      - Let us give a taste of how this is done with the help of an imaginary - application - MyApp - that uses log4net. -

      -
      -using Com.Foo;
      -
      -// Import log4net classes.
      -using log4net;
      -using log4net.Config;
      -
      -public class MyApp 
      -{
      -    // Define a static logger variable so that it references the
      -    // Logger instance named "MyApp".
      -    private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
      -
      -    static void Main(string[] args) 
      -    {
      -        // Set up a simple configuration that logs on the console.
      -        BasicConfigurator.Configure();
      -
      -        log.Info("Entering application.");
      -        Bar bar = new Bar();
      -        bar.DoIt();
      -        log.Info("Exiting application.");
      -    }
      -}
      -

      - MyApp - begins by importing log4net related classes. It then defines a static logger - variable with the name - MyApp - which happens to be the fully qualified name of the class. -

      -

      - MyApp - uses the following - Bar - class: -

      -
      -// Import log4net classes.
      -using log4net;
      -
      -namespace Com.Foo
      -{
      -    public class Bar 
      -    {
      -        private static readonly ILog log = LogManager.GetLogger(typeof(Bar));
      -
      -        public void DoIt()
      -        {
      -            log.Debug("Did it again!");
      -        }
      -    }
      -}
      -

      - The invocation of the - BasicConfigurator.Configure() - method creates a rather simple log4net setup. This method is hardwired to add - to the root logger a - ConsoleAppender. The output will be formatted using a - PatternLayout - set to the pattern - "%-4timestamp [%thread] %-5level %logger %ndc - %message%newline". -

      -

      - Note that by default, the root logger is assigned to - Level.DEBUG. -

      -

      - The output of MyApp is: -

      - -

      - As a side note, let me mention that in log4net child loggers link only to their - existing ancestors. In particular, the logger named - Com.Foo.Bar - is linked directly to the - root - logger, thereby circumventing the unused - Com - or - Com.Foo - loggers. This significantly increases performance and reduces log4net's memory - footprint. -

      -

      - The - MyApp - class configures log4net by invoking - BasicConfigurator.Configure() - method. Other classes only need to import the - log4net - namespace, retrieve the loggers they wish to use, and log away. -

      -

      - The previous example always outputs the same log information. Fortunately, it - is easy to modify - MyApp - so that the log output can be controlled at run-time. Here is a slightly - modified version. -

      -
      -using Com.Foo;
      -
      -// Import log4net classes.
      -using log4net;
      -using log4net.Config;
      -
      -public class MyApp 
      -{
      -    private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
      -
      -    static void Main(string[] args) 
      -    {
      -        // BasicConfigurator replaced with XmlConfigurator.
      -        XmlConfigurator.Configure(new System.IO.FileInfo(args[0]));
      -
      -        log.Info("Entering application.");
      -        Bar bar = new Bar();
      -        bar.DoIt();
      -        log.Info("Exiting application.");
      -    }
      -}
      -

      - This version of - MyApp - instructs the - XmlConfigurator - to parse a configuration file and set up logging accordingly. The path to the - configuration file is specified on the command line. -

      -

      - Here is a sample configuration file that results in exactly same output as the - previous - BasicConfigurator - based example. -

      - - - - - - - - - - - - - - - -]]> -

      - Suppose we are no longer interested in seeing the output of any component - belonging to the - Com.Foo - package. The following configuration file shows one possible way of achieving - this. -

      - - - - - - - - - - - - - - - - - - - - - -]]> -

      - The output of - MyApp - configured with this file is shown below. -

      - -2000-09-07 14:07:41,508 [main] INFO MyApp - Entering application. -2000-09-07 14:07:41,529 [main] INFO MyApp - Exiting application. -

      - As the logger - Com.Foo.Bar - does not have an assigned level, it inherits its level from - Com.Foo, which was set to WARN in the configuration - file. The log statement from the - Bar.DoIt - method has the level DEBUG, lower than the logger level WARN. Consequently, - DoIt() - method's log request is suppressed. -

      -

      - Here is another configuration file that uses multiple appenders. -

      - - - - - - - - - - - - - - - - - - - - - - - - -]]> -

      - Calling the enhanced MyApp with the this configuration file will output the - following on the console. -

      - -

      - In addition, as the root logger has been allocated a second appender, output - will also be directed to the - example.log - file. This file will be rolled over when it reaches 100KB. When roll-over - occurs, the old version of - example.log - is automatically moved to - example.log.1. -

      -

      - Note that to obtain these different logging behaviors we did not need to - recompile code. We could just as easily have logged to an email address, - redirected all - Com.Foo - output to an NT Event logger, or forwarded logging events to a remote log4net - server, which would log according to local server policy. -

      -

      - For more examples of configuring appenders using the XmlConfigurator - see the Example Appender Configuration - document. -

      - -
      -

      - The log4net configuration can be configured using assembly-level attributes rather than - specified programmatically. -

      -
        -
      • - XmlConfiguratorAttribute -

        - The log4net.Config.XmlConfiguratorAttribute Allows the - XmlConfigurator to be configured using the following properties: -

        -
          -
        • - ConfigFile -

          - If specified, this is the filename of the configuration file to use with the - XmlConfigurator. This file path is relative to the - application base directory (AppDomain.CurrentDomain.BaseDirectory). -

          -

          - This property cannot be used in conjunction with the - ConfigFileExtension property. -

          -
        • -
        • - ConfigFileExtension -

          - If specified, this is the extension for the configuration file. The assembly - file name is used as the base name with the this extension appended. For example - if the assembly is loaded from the a file TestApp.exe - and the ConfigFileExtension property is set to - log4net then the configuration file name is - TestApp.exe.log4net. This is equivalent to setting the - ConfigFile property to TestApp.exe.log4net. -

          -

          - The path to the configuration file is build by using the application base - directory (AppDomain.CurrentDomain.BaseDirectory), - the assembly file name and the configuration file extension. -

          -

          - This property cannot be used in conjunction with the - ConfigFile property. -

          -
        • -
        • - Watch -

          - If this flag is specified and set to true - then the framework will watch the configuration file and will reload the config - each time the file is modified. -

          -
        • -
        -

        - If neither of the ConfigFile or ConfigFileExtension - properties are specified, the application configuration file (e.g. TestApp.exe.config) - will be used as the log4net configuration file. -

        -

        - Example usage: -

        -
        -// Configure log4net using the .config file
        -[assembly: log4net.Config.XmlConfigurator(Watch=true)]
        -// This will cause log4net to look for a configuration file
        -// called TestApp.exe.config in the application base
        -// directory (i.e. the directory containing TestApp.exe)
        -// The config file will be watched for changes.
        -                            
        -
        -// Configure log4net using the .log4net file
        -[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net",Watch=true)]
        -// This will cause log4net to look for a configuration file
        -// called TestApp.exe.log4net in the application base
        -// directory (i.e. the directory containing TestApp.exe)
        -// The config file will be watched for changes.
        -                            
        -

        - This attribute may only be used once per assembly. -

        -
      • -
      -

      - Using attributes can be a clearer method for defining where the application's - configuration will be loaded from. However it is worth noting that attributes - are purely passive. They are information only. Therefore if you use configuration - attributes you must invoke log4net to allow it to read the attributes. A simple - call to LogManager.GetLogger will cause the attributes - on the calling assembly to be read and processed. Therefore it is imperative - to make a logging call as early as possible during the application start-up, and - certainly before any external assemblies have been loaded and invoked. -

      -
      - -
      -

      - Typically the log4net configuration is specified using a file. This file can - be read in one of two ways: -

      -
        -
      • Using the .NET System.Configuration API
      • -
      • Reading the file contents directly
      • -
      - -
      -

      - The System.Configuration API is only available if the - configuration data is in the application's config file; the file named - MyApp.exe.config or Web.config. Because the System.Configuration - API does not support reloading of the config file the configuration settings - cannot be watched using the log4net.Config.XmlConfigurator.ConfigureAndWatch - methods. The main advantage of using the System.Configuration - APIs to read the configuration data is that it requires less permissions than accessing - the configuration file directly. -

      -

      - The only way to configure an application using the System.Configuration - APIs is to call the log4net.Config.XmlConfigurator.Configure() method or - the log4net.Config.XmlConfigurator.Configure(ILoggerRepository) method. -

      -

      - In order to embed the configuration data in the .config file the section name must be - identified to the .NET config file parser using a configSections element. - The section must specify the log4net.Config.Log4NetConfigurationSectionHandler - that will be used to parse the config section. This type must be fully assembly qualified - because it is being loaded by the .NET config file parser not by log4net. The correct - assembly name for the log4net assembly must be specified. - The following is a simple example configuration file that specifies the correct - section handler to use for the log4net section. -

      - - - -
      - - - - - - - - - - - - -]]> -

      - In the above example the log4net assembly is specified. - This assembly must be located where the .NET runtime can find it. For example it could - be located in the same directory as the application. If the log4net assembly is stored in - the GAC then the fully qualified assembly name must be specified including the culture, - version and public key. -

      -

      - When using the .config file to specify the configuration the section name and - XML element name must be log4net. -

      -
      - -
      -

      - The XmlConfigurator can directly read any XML file and use it to configure log4net. - This includes the application's .config file; the file named MyApp.exe.config - or Web.config. The only reason not to read the configuration file directly is if the - application does not have sufficient permissions to read the file, then the configuration - must be loaded using the .NET configuration APIs (see above). -

      -

      - The file to read the configuration from can be specified using any of - the log4net.Config.XmlConfigurator methods that - accept a System.IO.FileInfo object. Because the - file system can be monitored for file change notifications the - ConfigureAndWatch methods can be used to monitor - the configuration file for modifications and automatically reconfigure log4net. -

      -

      - Additionally the log4net.Config.XmlConfiguratorAttribute - can be used to specify the file to read the configuration from. -

      -

      - The configuration is read from the log4net element - in the file. Only one log4net element can be specified - in the file but it may be located anywhere in the XML hierarchy. For example it - may be the root element: -

      - - - - - - - - - - - -]]> -

      - Or it may be nested within other elements: -

      - - - -
      - - - - - - - - - - - - -]]> -

      - The above example shows how the configuration data can be embedded - inside a .config file even though the file is being read directly - by log4net. An important note is that the .NET config file parser - will throw an exception if it finds an element that has not been - registered using the configSections element. - Therefore in the above example the log4net - section name is registered, but the type specified to handle the - section is System.Configuration.IgnoreSectionHandler. - This is a built-in class that indicates that another method for reading - the config section will be employed. -

      -
      - -
      - -
      -

      - log4net includes a configuration reader that parses an XML DOM, the - log4net.Config.XmlConfigurator. This section defines the - syntax accepted by the configurator. -

      -

      - This is an example of a valid XML configuration. The root element - must be <log4net>. Note that this does not mean - that this element cannot be embedded in another XML document. See the section above - on Configuration Files for more information - on how to embed the XmlConfigurator XML in a configuration file. -

      - - - - - - - - - - -]]> -

      - The <log4net> element supports the following attributes: -

      -
      - - - - - - - - - - - - - - - - - - - - - -
      AttributeDescription
      debug - Optional attribute. Value must be either true or false. - The default value is false. Set this attribute to true - to enable internal log4net debugging for this configuration. -
      update - Optional attribute. Value must be either Merge or Overwrite. - The default value is Merge. Set this attribute to Overwrite - to reset the configuration of the repository being configured before applying this configuration. -
      threshold - Optional attribute. Value must be the name of a level registered on the repository. - The default value is ALL. Set this attribute to limit the messages - that are logged across the whole repository, regardless of the logger that the message is logged to. -
      -
      -

      - The <log4net> element supports the following child elements: -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ElementDescription
      appender - Zero or more elements allowed. Defines an appender. -
      logger - Zero or more elements allowed. Defines the configuration of a logger. -
      renderer - Zero or more elements allowed. Defines an object renderer. -
      root - Optional element, maximum of one allowed. Defines the configuration of the root logger. -
      param - Zero or more elements allowed. Repository specific parameters -
      -
      - -
      -

      - Appenders may only be defined as child elements of the <log4net> - element. Each appender must be uniquely named. The implementing type for the appender must be specified. -

      -

      - This example shows an appender of type log4net.Appender.ConsoleAppender being - defined. The appender will be known as ConsoleAppender. -

      - - - - -]]> - -

      - The <appender> element supports the following attributes: -

      -
      - - - - - - - - - - - - - - - - - -
      AttributeDescription
      name - Required attribute. Value must be a string name for this appender. The name must be unique - among all the appenders defined in this configuration file. This name is used by the - <appender-ref> element of a Logger to reference an appender. -
      type - Required attribute. Value must be the type name for this appender. If the appender is - not defined in the log4net assembly this type name must be fully assembly qualified. -
      -
      -

      - The <appender> element supports the following child elements: -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      ElementDescription
      appender-ref - Zero or more elements allowed. Allows the appender to reference other appenders. - Not supported by all appenders. -
      filter - Zero or more elements allowed. Defines the filters used by this appender. -
      layout - Optional element, maximum of one allowed. Defines the layout used by this appender. -
      param - Zero or more elements allowed. Appender specific parameters. -
      -
      - -

      - For examples of configuring appenders see the - Example Appender Configuration - document. -

      - -
      -

      - Filters elements may only be defined as children of <appender> elements. -

      -

      - The <filter> element supports the following attributes: -

      -
      - - - - - - - - - - - - - -
      AttributeDescription
      type - Required attribute. Value must be the type name for this filter. If the filter is - not defined in the log4net assembly this type name must be fully assembly qualified. -
      -
      -

      - The <filter> element supports the following child elements: -

      -
      - - - - - - - - - - - - - -
      ElementDescription
      param - Zero or more elements allowed. Filter specific parameters. -
      -
      - -

      - Filters form a chain that the event has to pass through. Any filter along the way can accept the event - and stop processing, deny the event and stop processing, or allow the event on to the next filter. - If the event gets to the end of the filter chain without being denied it is implicitly accepted and will be logged. -

      - - - -]]> -

      - This filter will deny events that have a level that is lower than INFO - or higher than FATAL. - All events between INFO and FATAL will be logged. -

      -

      - If we want to only allow messages through that have a specific substring (e.g. 'database') - then we need to specify the following filters: -

      - - - -]]> -

      - The first filter will look for the substring 'database' in the message text of the event. - If the text is found the filter will accept the message and filter processing will stop, - the message will be logged. If the substring is not found the event will be passed to - the next filter to process. If there is no next filter the event would be implicitly - accepted and would be logged. But because we don't want the non matching events to be - logged we need to use a log4net.Filter.DenyAllFilter - that will just deny all events that reach it. This filter is only useful at the end of the filter chain. -

      -

      - If we want to allow events that have either 'database' or 'ldap' in the message text we can use the following filters: -

      - - -
      - - - -]]> -
      - -
      -

      - Layout elements may only be defined as children of <appender> elements. -

      -

      - The <layout> element supports the following attributes: -

      -
      - - - - - - - - - - - - - -
      AttributeDescription
      type - Required attribute. Value must be the type name for this layout. If the layout is - not defined in the log4net assembly this type name must be fully assembly qualified. -
      -
      -

      - The <layout> element supports the following child elements: -

      -
      - - - - - - - - - - - - - -
      ElementDescription
      param - Zero or more elements allowed. Layout specific parameters. -
      -
      -

      - This example shows how to configure a layout that uses the log4net.Layout.PatternLayout. -

      - - -]]> - -
      -
      - -
      -

      - Only one root logger element may only be defined and it must be a child of <log4net> element. - The root logger is the root of the logger hierarchy. All loggers ultimately inherit from this logger. -

      -

      - An example root logger: -

      - - - -]]> - -

      - The <root> element supports no attributes. -

      -

      - The <root> element supports the following child elements: -

      -
      - - - - - - - - - - - - - - - - - - - - - -
      ElementDescription
      appender-ref - Zero or more elements allowed. Allows the logger to reference appenders by name. -
      level - Optional element, maximum of one allowed. Defines the logging level for this logger. - This logger will only accept event that are at this level or above. -
      param - Zero or more elements allowed. Logger specific parameters. -
      -
      -
      - -
      -

      - Logger elements may only be defined as children of the <log4net> element. -

      -

      - An example logger: -

      - - - -]]> - -

      - The <logger> element supports the following attributes. -

      -
      - - - - - - - - - - - - - - - - - -
      AttributeDescription
      name - Required attribute. Value must be the name of the logger. -
      additivity - Optional attribute. Value may be either true or false. - The default value is true. Set this attribute to false - to prevent this logger from inheriting the appenders defined on parent loggers. -
      -
      -

      - The <logger> element supports the following child elements: -

      -
      - - - - - - - - - - - - - - - - - - - - - -
      ElementDescription
      appender-ref - Zero or more elements allowed. Allows the logger to reference appenders by name. -
      level - Optional element, maximum of one allowed. Defines the logging level for this logger. - This logger will only accept event that are at this level or above. -
      param - Zero or more elements allowed. Logger specific parameters. -
      -
      -
      - -
      -

      - Renderer elements may only be defined as children of the <log4net> element. -

      -

      - An example renderer: -

      - ]]> - -

      - The <renderer> element supports the following attributes. -

      -
      - - - - - - - - - - - - - - - - - -
      AttributeDescription
      renderingClass - Required attribute. Value must be the type name for this renderer. If the type is - not defined in the log4net assembly this type name must be fully assembly qualified. - This is the type of the object that will take responsibility for rendering the - renderedClass. -
      renderedClass - Required attribute. Value must be the type name for the target type for this renderer. If the type is - not defined in the log4net assembly this type name must be fully assembly qualified. - This is the name of the type that this renderer will render. -
      -
      -

      - The <renderer> element supports no child elements. -

      -
      - -
      -

      - Parameter elements may be children of many elements. See the specific elements above for details. -

      -

      - An example param: -

      - ]]> - -

      - The <param> element supports the following attributes. -

      -
      - - - - - - - - - - - - - - - - - - - - - -
      AttributeDescription
      name - Required attribute. Value must be the name of the parameter to set on the parent object. -
      value - Optional attribute. One of value or type attributes must be specified. - The value of this attribute is a string that can be converted to the value of the - parameter. -
      type - Optional attribute. One of value or type attributes must be specified. - The value of this attribute is a type name to create and set as the value of the - parameter. If the type is not defined in the log4net assembly this type name must - be fully assembly qualified. -
      -
      -

      - The <param> element supports the following child elements: -

      -
      - - - - - - - - - - - - - -
      ElementDescription
      param - Zero or more elements allowed. Parameter specific parameters. -
      -
      -

      - An example param that uses nested param elements: -

      - - -]]> - -
      -

      - Configuration parameters map directly to writable properties on an object. - The properties available depend on the actual type of the object being - configured. The log4net SDK documentation contains the API reference for - all the components included in the log4net assembly. -

      -

      - For 3rd party components please see their relevant API reference for - details of the properties available. -

      -
      - -
      -

      - All parameters may alternately be specified using the parameter name as the element name - rather than using the param element and name attribute. -

      -

      - For example a param: -

      - - -]]> -

      - may be written as: -

      - - -]]> -
      -
      -
      - -
      - -
      - - diff --git a/xdocs/src/release/manual/contexts.xml b/xdocs/src/release/manual/contexts.xml deleted file mode 100644 index 96c7ce66..00000000 --- a/xdocs/src/release/manual/contexts.xml +++ /dev/null @@ -1,266 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net Manual: Contexts - - - - - -
      - - -

      - Most real-world systems have to deal with multiple clients simultaneously. In a - typical multithreaded implementation of such a system, different threads will - handle different clients. Logging is especially well suited to trace and debug - complex distributed applications. An approach to differentiate the - logging output of one client from another is to instantiate a new separate - logger for each client. However this promotes the proliferation of loggers and - increases the management overhead of logging. -

      -

      - A lighter technique is to uniquely stamp each log request initiated from the - same client interaction. -

      -

      - Log4net supports different types of contextual logging and contexts with different scopes. -

      - -
      -

      - Contextual data can be set in different scopes. These contexts have progressively narrower visibility. - In the logging event itself the values from all of the contexts are combined together such that - values specified in a lower scoped context hide values from a higher context. -

      - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ScopeTypeDescription
      Globallog4net.GlobalContext - The global context is shared by all threads in the current AppDomain. - This context is thread safe for use by multiple threads concurrently. -
      Threadlog4net.ThreadContext - The thread context is visible only to the current managed thread. -
      Logical Threadlog4net.ThreadLogicalContext - The logical thread context is visible to a logical thread. Logical - threads can jump from one managed thread to another. For more details - see the .NET API System.Runtime.Remoting.Messaging.CallContext. -
      Eventlog4net.Core.LoggingEvent - Each event captures the current contextual state at the time the event - is generated. Contextual data can be set on the event itself. This context - is only visible to the code generating the event itself. -
      -
      -
      - -
      -

      - The log4net contexts store properties, i.e. name value pairs. The name is a string - the value is any object. A property can be set as follows: -

      - -

      - If properties with the same name are set in more than one context scope then - the value in the narrowest scope (lower down in the list above) will hide the - other values. -

      -

      - The property values are stored as objects within the LoggingEvent. - The PatternLayout supports rendering the value of a named - property using the %property{name} syntax. The value is - converted to a string by passing it to the log4net.ObjectRenderer.RendererMap - which will locate any custom renderer for the value type. The default behavior for - custom types is to call the object's ToString() method. -

      - -
      -

      - An active property value is one who's value changes over time. -

      -

      - For example, imagine a custom type that implemented the - ToString() method to return the - number of bytes allocated by the runtime garbage collector. -

      - -

      - An instance of this type can be added to the log4net.GlobalContext - during application startup: -

      - -

      - Once this property is set in the context all subsequent logging events will have a property - called GCAllocatedBytes. The value of the property will be an instance of the - GCAllocatedBytesHelper type. When this value is rendered to a - string by calling the ToString method the current number of bytes - allocated by the garbage collector will be returned and included in the output. -

      -

      - Note that the ToStringmethod will not be - called until the LoggingEventis rendered, as - explained in the Fixingsection. An active property - is not eligible to be fixed unless it implements - IFixingRequired. -

      -
      -
      - -
      -

      - Some properties, e.g. the current thread property, or any - active properties, are not realised - until their containing LoggingEventis rendered. If the - LoggingEventis been sent to a buffering appender (such as - AdoNetAppender) then this rendering will not happen - unless the - BufferingAppenderSkeleton's - Fix propertyhas been set. In addition, an active property is not eligible to be fixed unless it implements - IFixingRequired. -

      -
      - -
      -

      - Sometimes simple key value pairs are not the most convenient way of capturing contextual - information. A stack of information is a very convenient way of storing data especially - as our applications tend to be stack based. -

      -

      - The ThreadContext and LogicalThreadContext - also support storing contextual data in a stack. The stack is stored in context property, - therefore stacks have names and more than one stack can exist in the same context. A property - value set in a narrower context would override a stack with the same property name set in a - wider scoped context. -

      -

      - The stack supports Push and Pop methods. - As more contextual data is pushed onto the stack the stack grows. When the stack is rendered - all the data pushed onto the stack is output with the most recent data to the right hand - end of the string. -

      -

      - As the stack is just an object stored in the context properties it is also rendered - using the same PatternLayout syntax: %property{name}. - Where name is the name of the stack. -

      -

      - Calls the the stack's Push and Pop - methods must be matched up so that each push has a corresponding pop. The - Push method also returns an IDisposable - object that will perform the required pop operation when it is disposed. This allows - the C# using syntax to be used to automate the stack management. -

      - -

      - The INFO level log has a stack stored in its NDC property. The top item in the - stack is the string context. - The using syntax ensures that the value context is popped off the stack - at the end of the block. -

      -

      - The using - syntax is recommended because it removes some work load from the developer and - reduces errors in matching up the Push and Pop calls, especially when exceptions - can occur. -

      -
      - -
      -

      - The NDC (Nested Diagnostic Context) exists for compatibility - with older versions of log4net. This helper class implements a stack which is stored - in the thread context property named NDC. -

      -
      - -
      -

      - The MDC (MappedDiagnostic Context) exists for compatibility - with older versions of log4net. This helper class implements a properties map which is - mapped directly through to the thread context properties. -

      -
      - -

      - To illustrate this point, let us take the example of a web service delivering - content to numerous clients. The web service can build the NDC at the very - beginning of the request before executing other code. The contextual - information can be the client's host name and other information inherent to the - request, typically information contained in cookies. Hence, even if the web - service is serving multiple clients simultaneously, the logs initiated by the - same code, i.e. belonging to the same logger, can still be distinguished - because each client request will have a different NDC stack. Contrast this with - the complexity of passing a freshly instantiated logger to all code exercised - during the client's request. -

      -

      - Nevertheless, some sophisticated applications, such as virtual hosting web - servers, must log differently depending on the virtual host context and also - depending on the software component issuing the request. Log4net supports - multiple logger repositories. This would allow each virtual host to possess its own copy - of the logger hierarchy. Configuring multiple logger hierarchies is beyond the - scope of this document. -

      - -
      - -
      diff --git a/xdocs/src/release/manual/internals.xml b/xdocs/src/release/manual/internals.xml deleted file mode 100644 index 650461d5..00000000 --- a/xdocs/src/release/manual/internals.xml +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net Manual: Internals - - - - - -
      - - -
      -

      - One of the often-cited arguments against logging is its computational cost. - This is a legitimate concern as even moderately sized applications can generate - thousands of log requests. Much effort was spent measuring and tweaking logging - performance. Log4net claims to be fast and flexible: speed first, flexibility - second. -

      -

      - The user should be aware of the following performance issues. -

      -
        -
      1. - Logging performance when logging is turned off. -

        - When logging is turned off entirely or just for a set of levels, the cost of a - log request consists of a method invocation plus an integer comparison. -

        -

        - However, The method invocation involves the "hidden" cost of parameter - construction. -

        -

        - For example, for some logger - log, writing, -

        -
        -log.Debug("Entry number: " + i + " is " + entry[i].ToString());
        -

        - incurs the cost of constructing the message parameter, i.e. converting both - integer - i - and - entry[i] - to strings, and concatenating intermediate strings, regardless of whether the - message will be logged or not. This cost of parameter construction can be quite - high and it depends on the number and type of the parameters involved. -

        -

        - To avoid the parameter construction cost write: -

        -
        -if(log.IsDebugEnabled)
        -{
        -    log.Debug("Entry number: " + i + " is " + entry[i].ToString());
        -}
        -

        - This will not incur the cost of parameter construction if debugging is - disabled. On the other hand, if the logger is debug-enabled, it will incur - twice the cost of evaluating whether the logger is enabled or not: once in - IsDebugEnabled - and once in - Debug. This is an insignificant overhead because - evaluating a logger takes about 1% of the time it takes to actually log. -

        -

        - Certain users resort to pre-processing or compile-time techniques to compile - out all log statements. This leads to perfect performance efficiency with - respect to logging. However, since the resulting application binary does not - contain any log statements, logging cannot be turned on for that binary. In - many people's opinion this is a disproportionate price to pay in exchange for a - small performance gain. -

        -
      2. -
      3. - The performance of deciding whether to log or not to log when logging is - turned on. -

        - This is essentially the performance of walking the logger hierarchy. When - logging is turned on, log4net still needs to compare the level of the log - request with the level of the request logger. However, loggers may not have an - assigned level; they can inherit them from the logger hierarchy. Thus, before - inheriting a level, the logger may need to search its ancestors. -

        -

        - There has been a serious effort to make this hierarchy walk to be as fast as - possible. For example, child loggers link only to their existing ancestors. In - the - BasicConfigurator - example shown earlier, the logger named - Com.Foo.Bar - is linked directly to the root logger, thereby circumventing the nonexistent - Com - or - Com.Foo - loggers. This significantly improves the speed of the walk, especially in - "sparse" hierarchies. -

        -

        - The typical cost of walking the hierarchy is typically 3 times slower than when - logging is turned off entirely. -

        -
      4. -
      5. - Actually outputting log messages -

        - This is the cost of formatting the log output and sending it to its target - destination. Here again, a serious effort was made to make layouts (formatters) - perform as quickly as possible. The same is true for appenders. -

        -
      6. -
      -

      - Although log4net has many features, its first design goal was speed. Some - log4net components have been rewritten many times to improve performance. - Nevertheless, contributors frequently come up with new optimizations. You - should be pleased to know that when configured with the - SimpleLayout - performance tests have shown log4net to log within an order of magnitude of - System.Console.WriteLine. -

      -
      - -
      -

      - The following is the series of steps and checks that a messages goes through while being logged. - For the purposes of this example we will document an INFO level - message being logged on logger ConsoleApp.LoggingExample. This logger is configured - to use the log4net.Appender.ConsoleAppender. The repository used - in this example is a log4net.Repository.Hierarchy object. -

      -
        -
      1. -

        - The user logs a message using the ILog.Info method on the logger - obtained using a call to log4net.LogManager.GetLogger("ConsoleApp.LoggingExample"). - For example: log4net.LogManager.GetLogger("ConsoleApp.LoggingExample").Info("Application Start"); - The ILog interface is actually an extension to log4net that provides level - specific logging methods (i.e. Debug, Info, Warn, Error, and Fatal). -

        -
      2. -
      3. -

        - The message is then logged through to the ILogger.Log method on the - appropriate log4net.Repository.Hierarchy.Logger object. The - ILogger.Log method takes the Level to - log at as a parameter and therefore works for all levels. -

        -
      4. -
      5. -

        - The repository threshold level is compared to the message level to determine if the message - can be logged. If the message level is below the threshold level the message is not logged. - In this case the repository is a log4net.Repository.Hierarchy object. -

        -
      6. -
      7. -

        - The Logger level is compared to the message level to determine if the - message can be logged. Note that the Logger level is inherited from a - parent Logger if not specified explicitly for this Logger. - If the message level is below the Logger level the message is not logged. -

        -
      8. -
      9. -

        - A LoggingEvent instance is created to encapsulate the message being logged. -

        -
      10. -
      11. -

        - The list of appenders for the Logger is built. This includes appenders - attached to parent Loggers except where excluded by the - Logger.Additivity property. -

        -
      12. -
      13. -

        - The LoggingEvent object is passed to the - IAppender.DoAppend method for each appender. -

        -
      14. -
      -

      - For Each Appender that the LoggingEvent is delivered to the following - actions take place: -

      -
        -
      1. -

        - The appender threshold level is compared to the message level to determine if the message - can be logged. If the message level is below the threshold level the message is not logged. -

        -
      2. -
      3. -

        - If the appender has a filter chain the LoggingEvent is passed down the - filter chain which can decide if the message can be logged or not. -

        -
      4. -
      5. -

        - Next an appender specific check is performed. Usually this check will verify that all the - required properties are set for the appender (e.g. a Layout is set if required). -

        -
      6. -
      7. -

        - The LoggingEvent is passed to the appender specific - Append method. What happens now is specific to the appender. -

        -
      8. -
      -

      - The following actions take place in the ConsoleAppender.Append method: -

      -
        -
      1. -

        - The ConsoleAppender uses a Layout to - format the message as a string for display. -

        -
      2. -
      3. -

        - The Layout uses the LoggingEvent.RenderedMessage - property to get the string for the message object. This uses the registered - IObjectRenderer for the type of the message object. -

        -
      4. -
      5. -

        - The message text is displayed on the console using the Console.WriteLine method. -

        -
      6. -
      -
      - -
      - -
      diff --git a/xdocs/src/release/manual/introduction.xml b/xdocs/src/release/manual/introduction.xml deleted file mode 100644 index 626b290d..00000000 --- a/xdocs/src/release/manual/introduction.xml +++ /dev/null @@ -1,1028 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net Manual: Introduction - - - - - -
      - - -
      -

      - This document is based on Short introduction to log4j by Ceki Gülcü. -

      -

      - The log4net framework is based on log4j, see - http://logging.apache.org/log4j for more information on log4j. - The log4net framework, source code, binaries, documentation, examples and related - materials are published under the terms of the - Apache License, Version 2.0, - a copy of which has been included with this distribution in the LICENSE.txt file. -

      -

      - This document is an introduction to the log4net API, its unique features and - design rationale. Log4net is an open source project based on the work of many - authors. It allows the developer to control which log statements are output - with arbitrary granularity. It is fully configurable at runtime using external - configuration files. -

      -

      - Almost every large application includes its own logging or tracing API. - Inserting log statements into code is a low-tech method for debugging it. It - may also be the only way because debuggers are not always available or - applicable. This is usually the case for multithreaded applications and - distributed applications at large. -

      -

      - Once an application has been deployed it may not be possible to utilize - development and debugging tools. An administrator can use effective logging - systems to diagnose and fix many configuration issues. -

      -

      - Experience indicates that logging is an important component of the development - cycle. It offers several advantages. It provides precise context about the - execution of the application. Once inserted into the code, the generation of - logging output requires no human intervention. Moreover, log output can be - saved in persistent medium to be studied at a later time. In addition to its - use in the development cycle, a sufficiently rich logging package can also be - viewed as an auditing tool. -

      -

      - Logging does have its drawbacks. It can slow down an application. If too - verbose, it can cause scrolling blindness. To alleviate these concerns, log4net - is designed to be reliable, fast and extensible. Since logging is rarely the - main focus of an application, the log4net API strives to be simple to - understand and to use. -

      -
      - -
      -

      - Log4net is available for several frameworks. For each supported framework an - assembly targeting that framework is built: -

      -
        -
      • Microsoft .NET Framework 1.0 (1.0.3705)
      • -
      • Microsoft .NET Framework 1.1 (1.1.4322)
      • -
      • Microsoft .NET Framework 2.0 (2.0.50727)
      • -
      • Microsoft .NET Compact Framework 1.0
      • -
      • Microsoft .NET Compact Framework 2.0
      • -
      • Mono 1.0
      • -
      • Mono 2.0
      • -
      • Microsoft Shared Source CLI 1.0
      • -
      • CLI 1.0 Compatible
      • -
      -

      - Not all frameworks are created equal and some features have been excluded from - some of the builds. See the Framework Support - document for more information. -

      -
      - -
      -

      - Log4net has three main components: loggers, appenders and layouts. - These three types of components work together to enable developers to log - messages according to message type and level, and to control at runtime how - these messages are formatted and where they are reported. These components are - helped by filters that control the actions of the appender and - object renderers that turn objects into strings. -

      - -
      -

      - The first and foremost advantage of any logging API over plain - System.Console.WriteLine - resides in its ability to disable certain log statements while allowing others - to print unhindered. This capability assumes that the logging space, that is, - the space of all possible logging statements, is categorized according to some - developer-chosen criteria. -

      -

      - Loggers are named entities. Logger names are case-sensitive and they follow the - following hierarchical naming rule: -

      -
      -
      Named Hierarchy
      -
      -

      - A logger is said to be an ancestor of another logger if its name - followed by a dot is a prefix of the descendant logger name. A logger is - said to be a parent of a child logger if there are no ancestors - between itself and the descendant logger. -

      -

      - The hierarchy works very much in the same way as the namespace and class - hierarchy in .NET. This is very convenient as we shall soon see. -

      -
      -
      -

      - For example, the logger named - "Foo.Bar" - is a parent of the logger named - "Foo.Bar.Baz". Similarly, - "System" - is a parent of - "System.Text" - and an ancestor of - "System.Text.StringBuilder". This naming scheme - should be familiar to most developers. -

      -

      - The root logger resides at the top of the logger hierarchy. It is exceptional - in three ways: -

      -
        -
      1. - It always exists
      2. -
      3. - It cannot be retrieved by name
      4. -
      5. - It always has an assigned level
      6. -
      -

      - Loggers are retrieved using the static method from the - log4net.LogManager - class. The - GetLogger - methods take the name of the desired logger as a parameter. They are listed - below: -

      - -

      - The - GetLogger - methods that takes a - Type - parameter uses the fully qualified type name as the name of the logger to - retrieve. -

      -

      - These - GetLogger - methods return an - ILog - interface. That is the representation of the Logger passed back to the - developer. The - ILog - interface is defined below: -

      - -

      - Loggers may be assigned levels. Levels are instances of the - log4net.Core.Level - class. The following levels are defined in order of increasing priority: -

      -
        -
      • - ALL -
      • -
      • - DEBUG -
      • -
      • - INFO -
      • -
      • - WARN -
      • -
      • - ERROR -
      • -
      • - FATAL -
      • -
      • - OFF -
      • -
      -

      - If a given logger is not assigned a level, then it inherits one from its - closest ancestor with an assigned level. More formally: -

      -
      -
      Level Inheritance
      -
      -

      - The inherited level for a given logger X, is equal to the first - non-null level in the logger hierarchy, starting at X and proceeding - upwards in the hierarchy towards the root logger. -

      -
      -
      -

      - To ensure that all loggers can eventually inherit a level, the root logger - always has an assigned level. The default value for the root logger is - DEBUG. -

      -

      - Below are four tables with various assigned level values and the resulting - inherited levels according to the above rule. -

      -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Logger name - Assigned level - Inherited level
      rootProotProot
      XnoneProot
      X.YnoneProot
      X.Y.ZnoneProot
      -
      -

      - In Example 1 above, only the root logger is assigned a level. This level - value, - Proot, is inherited by the other loggers - X, - X.Y - and - X.Y.Z. -

      -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Logger name - Assigned level - Inherited level
      rootProotProot
      XPxPx
      X.YPxyPxy
      X.Y.ZPxyzPxyz
      -
      -

      - In Example 2 above, all loggers have an assigned level value. There is - no need for level inheritance. -

      -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Logger name - Assigned level - Inherited level
      rootProotProot
      XPxPx
      X.YnonePx
      X.Y.ZPxyzPxyz
      -
      -

      - In Example 3 above, the loggers - root, - X - and - X.Y.Z - are assigned the levels - Proot, - Px - and - Pxyz - respectively. The logger - X.Y - inherits its level value from its parent - X. -

      -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Logger name - Assigned level - Inherited level
      rootProotProot
      XPxPx
      X.YnonePx
      X.Y.ZnonePx
      -
      -

      - In Example 4 above, the loggers root and - X - and are assigned the levels - Proot - and - Px - respectively. The loggers - X.Y - and - X.Y.Z - inherits their level value from their nearest parent - X - having an assigned level. -

      -

      - Logging requests are made by invoking one of the printing methods of a logger - instance (through the log4net.ILog). These printing methods are - Debug, - Info, - Warn, - Error, and - Fatal. -

      -

      - By definition, the printing method determines the level of a logging request. - For example, if - log - is a logger instance, then the statement - log.Info("..") - is a logging request of level INFO. -

      -

      - A logging request is said to be enabled if its level is higher than or - equal to the level of its logger. Otherwise, the request is said to be disabled. - A logger without an assigned level will inherit one from the hierarchy. This - rule is summarized below. -

      -
      -
      Basic Selection Rule
      -
      -

      - A log request of level L in a logger with (either assigned or inherited, - whichever is appropriate) level K, is enabled if L >= K. -

      -
      -
      -

      - This rule is at the heart of log4net. It assumes that levels are ordered. For - the standard levels, we have - DEBUG < INFO < WARN < ERROR < FATAL. -

      -

      - Calling the - log4net.LogManager.GetLogger - method with the same name will always return a reference to the exact same - logger object. -

      -

      - For example, in: -

      - -

      - x - and - y - refer to exactly the same logger object. -

      -

      - Thus, it is possible to configure a logger and then to retrieve the same - instance somewhere else in the code without passing around references. In - fundamental contradiction to biological parenthood, where parents always - precede their children, log4net loggers can be created and configured in any - order. In particular, a "parent" logger will find and link to its descendants - even if it is instantiated after them. -

      -

      - Configuration of the log4net environment is typically done at application - initialization. The preferred way is by reading a configuration file. This - approach will be discussed shortly. -

      -

      - Log4net makes it easy to name loggers by software component. This can be - accomplished by statically instantiating a logger in each class, with the - logger name equal to the fully qualified name of the class. This is a useful - and straightforward method of defining loggers. As the log output bears the - name of the generating logger, this naming strategy makes it easy to identify - the origin of a log message. However, this is only one possible, albeit common, - strategy for naming loggers. Log4net does not restrict the possible set of - loggers. The developer is free to name the loggers as desired. -

      -

      - Nevertheless, naming loggers after the class where they are located seems to be - the best strategy known so far. It is simple an obvious to the developers where - each log message came from. Most importantly it leverages the design of the - application to produce the design of the logger hierarchy. Hopefully some - thought has gone into the design of the application. -

      -
      - -
      -

      - The ability to selectively enable or disable logging requests based on their - logger is only part of the picture. Log4net allows logging requests to print to - multiple destinations. In log4net speak, an output destination is called an appender. - Appenders must implement the log4net.Appenders.IAppender - interface. -

      -

      - The following appenders are defined in the log4net package: -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Type - Description
      log4net.Appender.AdoNetAppender - Writes logging events to a database using either prepared statements or stored - procedures. -
      log4net.Appender.AnsiColorTerminalAppender - Writes color highlighted logging events to a an ANSI terminal window. -
      log4net.Appender.AspNetTraceAppender - Writes logging events to the ASP trace context. These can then be rendered at - the end of the ASP page or on the ASP trace page. -
      log4net.Appender.BufferingForwardingAppender - Buffers logging events before forwarding them to child appenders. -
      log4net.Appender.ColoredConsoleAppender - Writes logging events to the application's Console. The events may go to either - the standard our stream or the standard error stream. The events may have configurable - text and background colors defined for each level. -
      log4net.Appender.ConsoleAppender - Writes logging events to the application's Console. The events may go to either - the standard our stream or the standard error stream. -
      log4net.Appender.EventLogAppender - Writes logging events to the Windows Event Log. -
      log4net.Appender.FileAppender - Writes logging events to a file in the file system. -
      log4net.Appender.ForwardingAppender - Forwards logging events to child appenders. -
      log4net.LocalSyslogAppender - Writes logging events to the local syslog service (UNIX only). -
      log4net.Appender.MemoryAppender - Stores logging events in an in memory buffer. -
      log4net.Appender.NetSendAppender - Writes logging events to the Windows Messenger service. These messages are - displayed in a dialog on a users terminal. -
      log4net.Appender.OutputDebugStringAppender - Writes logging events to the debugger. If the application has no - debugger, the system debugger displays the string. If the application has no - debugger and the system debugger is not active, the message is ignored. -
      log4net.Appender.RemoteSyslogAppender - Writes logging events to a remote syslog service using UDP networking. -
      log4net.Appender.RemotingAppender - Writes logging events to a remoting sink using .NET remoting. -
      log4net.Appender.RollingFileAppender - Writes logging events to a file in the file system. The RollingFileAppender can - be configured to log to multiple files based upon date or file size - constraints. -
      log4net.Appender.SmtpAppender - Sends logging events to an email address. -
      log4net.Appender.SmtpPickupDirAppender - Writes SMTP messages as files into a pickup directory. - These files can then be read and sent by an SMTP agent - such as the IIS SMTP agent. -
      log4net.Appender.TelnetAppender - Clients connect via Telnet to receive logging events. -
      log4net.Appender.TraceAppender - Writes logging events to the .NET trace system. -
      log4net.Appender.UdpAppender - Sends logging events as connectionless UDP datagrams to a remote host or a - multicast group using a UdpClient. -
      -
      -

      - More than one appender can be attached to a logger. -

      -

      - - Each enabled logging request for a given logger will be forwarded to all - the appenders in that logger as well as the appenders higher in the hierarchy. - - In other words, appenders are inherited additively from the logger hierarchy. - For example, if a console appender is added to the root logger, then all - enabled logging requests will at least print on the console. If in addition a - file appender is added to a logger, say X, then enabled logging requests - for X and X's children will print on a file and on the - console. It is possible to override this default behavior so that appender - accumulation is no longer additive by setting the additivity flag on the logger - to - false. -

      -

      - The rules governing appender additivity are summarized below. -

      -
      -
      Appender Additivity
      -
      -

      - The output of a log statement of logger X will go to all the appenders - in X and its ancestors. This is the meaning of the term "appender - additivity". -

      -

      - However, if an ancestor of logger X, say Y, has the additivity - flag set to - false, then X's output will be directed to all - the appenders in X and it's ancestors up to and including Y but - not the appenders in any of the ancestors of Y. -

      -

      - Loggers have their additivity flag set to - true - by default. -

      -
      -
      -

      - The table below shows an example: -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Logger Name - Added Appenders - Additivity Flag - Output Targets - Comment
      rootA1not applicableA1There is no default appender attached to root.
      xA-x1, A-x2trueA1, A-x1, A-x2Appenders of "x" and root.
      x.ynonetrueA1, A-x1, A-x2Appenders of "x" and root.
      x.y.zA-xyz1trueA1, A-x1, A-x2, A-xyz1Appenders in "x.y.z", "x" and root.
      securityA-secfalseA-secNo appender accumulation since the additivity flag is set to - false.
      security.accessnonetrueA-secOnly appenders of "security" because the additivity flag in "security" is set - to - false.
      -
      -
      - -
      -

      - Appenders can filter the events that are delivered to them. The filters can be - specified in the configuration to allow fine control of the events that are - logged through different appenders. -

      -

      - The simplest form of control is to specify a - Threshold - on the appender. This works by logging only the events that have a level that - is greater than or equal to the threshold. -

      -

      - More complex and custom event filtering can be done using the filter chain - defined on each appender. Filters must implement the - log4net.Filter.IFilter interface. -

      -

      - The following filters are defined in the log4net package: -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Type - Description
      log4net.Filter.DenyAllFilter - Drops all logging events. -
      log4net.Filter.LevelMatchFilter - An exact match to the event's level. -
      log4net.Filter.LevelRangeFilter - Matches against a range of levels. -
      log4net.Filter.LoggerMatchFilter - Matches against a the start of the logger name. -
      log4net.Filter.PropertyFilter - Matches a substring from a specific property value. -
      log4net.Filter.StringMatchFilter - Matches a substring from the event's message. -
      -
      -

      - The filters can be configured to either accept or reject the event based upon - the match. -

      -
      - -
      -

      - More often than not, users wish to customize not only the output destination - but also the output format. This is accomplished by associating a layout - with an appender. The layout is responsible for formatting the logging request - according to the user's wishes, whereas an appender takes care of sending the - formatted output to its destination. The - PatternLayout, part of the standard log4net - distribution, lets the user specify the output format according to conversion - patterns similar to the C language - printf - function. -

      -

      - For example, the PatternLayout with the conversion pattern - "%timestamp [%thread] %-5level %logger - %message%newline" - will output something akin to: -

      - -

      - The first field is the number of milliseconds elapsed since the start of the - program. The second field is the thread making the log request. The third field - is the level of the log statement. The fourth field is the name of the logger - associated with the log request. The text after the '-' is the message of the - statement. -

      -

      - The following layouts are included in the log4net package: -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Type - Description
      log4net.Layout.ExceptionLayout - Renders the exception text from the logging - event. -
      log4net.Layout.PatternLayout - Formats the logging event according to a flexible - set of formatting flags. -
      log4net.Layout.RawTimeStampLayout - Extracts the timestamp from the logging event. -
      log4net.Layout.RawUtcTimeStampLayout - Extracts the timestamp from the logging event in Universal Time. -
      log4net.Layout.SimpleLayout - Formats the logging event very simply: - [level] - [message] -
      log4net.Layout.XmlLayout - Formats the logging event as an XML element. -
      log4net.Layout.XmlLayoutSchemaLog4j - Formats the logging event as an XML element that - complies with the log4j event dtd. -
      -
      -
      - -
      -

      - Just as importantly, log4net will render the content of the log message - according to user specified criteria. For example, if you frequently need to - log - Oranges, an object type used in your current project, - then you can register an - OrangeRenderer - that will be invoked whenever an orange needs to be logged. -

      -

      - Object rendering follows the class hierarchy. For example, assuming oranges are - fruits, if you register an - FruitRenderer, all fruits including oranges will be - rendered by the - FruitRenderer, unless of course you registered an - orange specific - OrangeRenderer. -

      -

      - Object renderers have to implement the - log4net.ObjectRenderer.IObjectRenderer - interface. -

      -
      - -
      - -
      - -
      diff --git a/xdocs/src/release/manual/plugins.xml b/xdocs/src/release/manual/plugins.xml deleted file mode 100644 index 015f2bd6..00000000 --- a/xdocs/src/release/manual/plugins.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net Manual: Plugins - - - - - -
      - - -
      -

      - Plugins are additional modular components that are attached to a logger repository. -

      -

      - Plugins are stored in the PluginMap of an - ILoggerRepository. - Plugins are attached to the repository by using the PluginMap.Add - method. -

      -

      - The following plugins are included in the log4net package: -

      -
      - - - - - - - - - -
      - Type - Description
      log4net.Plugin.RemoteLoggingServerPlugin - Creates a remote logging sink that can receive logging events from a - RemotingAppender. -
      -
      -
        -
      • -

        RemoteLoggingServerPlugin

        -

        - Creates a remote logging sink that can receive logging events from a - RemotingAppender. -

        -

        - Creates a remoting logging sink. A single - parameter must be passed to the constructor that specifies the sink URI. This is a - name used to identify the logging sink object published via remoting and must be - agreed with the client before communication can take place. -

        -

        - Example usage: -

        - -
      • -
      - -
      -

      - Plugins can be configured using the following assembly-level attributes: -

      -
        -
      • -

        PluginAttribute

        -

        - Specifies a plugin type to create and attach to the default repository. This attribute - does not allow plugins to be parameterized. The plugin class must have a public default constructor. -

        -

        - This attribute may be used as many times as necessary to attach plugins to the repository. -

        -
      • -
      -
      -
      - -
      - -
      diff --git a/xdocs/src/release/manual/repositories.xml b/xdocs/src/release/manual/repositories.xml deleted file mode 100644 index 0a1e8382..00000000 --- a/xdocs/src/release/manual/repositories.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net Manual: Repositories - - - - - -
      - - -
      -

      - Logging repositories are considered advanced functionality. The default behavior - should be sufficient for most users. -

      -

      - Log4net supports logging repositories. A repository is uniquely named. - Each repository is a (ILoggerRepository). - Multiple assemblies can link to the same repository. -

      -

      - By default there is a single logging repository per process (more precisely per AppDomain). This extends - across all assemblies loaded into the process and allows them to all share a - single configuration. The configuration of the repository only needs to be done once, - typically in the entry point to the application, either programmatically or using - a configuration attribute. -

      -

      - Named logging repositories can be created using the LogManager.CreateRepository - method. The repository for can be retrieved using the - LogManager.GetRepository method. - A repository created in this way will need to be configured programmatically. -

      - -
      -

      - An assembly may choose to utilize a named logging repository rather than the default repository. - This completely separates the logging for the assembly from the rest of the application. - This can be very useful to component developers that wish to use log4net for their - components but do not want to require that all the applications that use their - component are aware of log4net. It also means that their debugging configuration is - separated from the applications configuration. The assembly should specify the - RepositoryAttribute to set its logging repository. -

      -

      - The log4net logging repositories can be configured using the following assembly-level - attributes: -

      -
        -
      • - AliasRepositoryAttribute -

        - Specifies a named repository to use as this assembly's repository. -

        -

        - An assembly's logger repository is defined by its - RepositoryAttribute, however this can be overridden by an - assembly loaded before the target assembly. -

        -

        - An assembly can alias another assembly's repository by specifying - this attribute with the name of the target repository. -

        -

        - This attribute may be used as many times as necessary to alias all the required - repositories. -

        -
      • -
      • - RepositoryAttribute -

        - Specifies the logging repository for the assembly. -

        -

        - Assemblies are mapped to logging repositories. This attribute controls the configuration of the repository. The - Name property specifies the name of the repository - for this assembly. The RepositoryType - property specifies the type of the repository object to create for the assembly. - If this attribute is not specified and a Name - is not specified then the assembly will be part of the default shared logging - repository. -

        -

        - This attribute may only be used once per assembly. -

        -
      • -
      -
      -
      -
      - -
      diff --git a/xdocs/src/release/release-notes.xml b/xdocs/src/release/release-notes.xml deleted file mode 100644 index b8346208..00000000 --- a/xdocs/src/release/release-notes.xml +++ /dev/null @@ -1,1085 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Release Notes - - - - - -
      - - - -
      - -
      -
        -
      • [LOG4NET-21] - RemotingAppender fails once NDC becomes empty
      • -
      • [LOG4NET-22] - XmlLayout allows output of invalid control characters
      • -
      • [LOG4NET-23] - example-apps.html links are off by one folder level
      • -
      • [LOG4NET-25] - RollingFileAppender can fail if RollOverIfDateBoundaryCrossing required
      • -
      • [LOG4NET-28] - AdoNetAppender does not support inserting NULL into columns
      • -
      • [LOG4NET-29] - LevelMatchFilter should return Neutral when no match is found
      • -
      • [LOG4NET-32] - AdoNetAppender losing first entry
      • -
      • [LOG4NET-35] - Exception rendering ThreadContextStack if null value pushed into stack
      • -
      • [LOG4NET-36] - System.Diagnostics.Trace may throw exception if AppDomain does not have config file
      • -
      • [LOG4NET-40] - RollingFileAppender does not limit files to MaxSizeRollBackups when CountDirection is 1
      • -
      • [LOG4NET-41] - RollingFileAppender roll over date fail
      • -
      • [LOG4NET-42] - Serialised LoggingEvent does not preserve the Fix flags
      • -
      • [LOG4NET-43] - Specifying an empty string as a property in the config file results in an error
      • -
      • [LOG4NET-44] - XmlLayout emits all properties under a node named global-properties, rather than just properties.
      • -
      • [LOG4NET-49] - CountingQuietTextWriter does not count strings written with WriteLine
      • -
      • [LOG4NET-50] - Process.StartTime hangs on some systems
      • -
      • [LOG4NET-60] - Bug in RollingFileAppender.cs causing failure to timely roll files on monthly interval
      • -
      • [LOG4NET-63] - 1.2.9.0 Documentation typos
      • -
      • [LOG4NET-65] - Unhandled SecurityException exception for FileIOPermission while loading configuration file
      • -
      • [LOG4NET-67] - CVE-2006-0743 Security vulnerability in LocalSyslogAppender
      • -
      • [LOG4NET-69] - Exception thrown when *Format methods are given a malformed format string
      • -
      • [LOG4NET-70] - CoreDll.dll referenced with different capitalisation
      • -
      • [LOG4NET-73] - ADONetAppender.ActivateOptions() leaks database connection when called multiple times
      • -
      -
      - -
      -
        -
      • [LOG4NET-11] - Add Flush command to API
      • -
      • [LOG4NET-24] - Programmatic flush of BufferingAppenderSkeleton buffer
      • -
      • [LOG4NET-37] - Allow the RepositorySelector type to be specified using the AppSettings config
      • -
      • [LOG4NET-46] - Support appenders that can output multiple events efficiently
      • -
      • [LOG4NET-51] - WmiAppender
      • -
      -
      - -
      -
        -
      • [LOG4NET-3] - Support per event patterns in FileAppender File name
      • -
      • [LOG4NET-13] - Allow SMTPAppender to have replaceable parameters in Subject
      • -
      • [LOG4NET-15] - Email high "importance" priority setting with SmtpAppender
      • -
      • [LOG4NET-17] - Line-wrapping Appender Layouts
      • -
      • [LOG4NET-33] - Ability to use global property to point to log4net configuration file
      • -
      • [LOG4NET-34] - Allow xml config values to be set via XmlNodeType.CDATA or XmlNodeType.Text rather than just value="foo"
      • -
      • [LOG4NET-45] - PluginAttribute does not allow plugin type to be specified as a Type, only as a string
      • -
      • [LOG4NET-52] - Allow XML configurator to set properties of type Object
      • -
      • [LOG4NET-53] - Allow repository properties to be set in the config file
      • -
      • [LOG4NET-56] - Support rendering IEnumerator objects as well as ICollections
      • -
      • [LOG4NET-58] - Support clean build on .NET 2.0
      • -
      • [LOG4NET-72] - Performance of ILog.xxxFormat methods
      • -
      • [LOG4NET-74] - Change MemoryAppender member variables to protected
      • -
      -
      - -
      - -
      - -
      -
        -
      • -

        Renamed namespaces

        -

        - Renamed namespace log4net.spi to log4net.Core. - Renamed namespace log4net.helpers to log4net.Util. -

        -
      • -
      • -

        Renamed config classes and attributes

        -

        - In the log4net.Config namespace the DOMConfigurator, - DOMConfiguratorAttribute, DomainAttribute, - and AliasDomainAttribute have been marked as obsolete. These types are - still available and functional in this release. -

        -

        - The XmlConfigurator and XmlConfiguratorAttribute - types replace DOMConfigurator and - DOMConfiguratorAttribute. The RepositoryAttribute - and AliasRepositoryAttribute types replace - DomainAttribute and AliasDomainAttribute. -

        -
      • -
      • -

        Fixed pascal casing of type names

        -

        - Renamed AdoNetAppender, AspNetTraceAppender, - SmtpAppender, Iso8601DateFormatter, - MdcFilter, and NdcFilter. - Note that the config file type resolver is case insensitive so this is only a breaking change - for code that programmatically creates a type that has been renamed. -

        -
      • -
      • -

        Layouts changed to stream their output to a TextWriter

        -

        - Layouts have been changed to format their output to a TextWriter - rather than return a string. This increases performance and reduces temporary object creation. -

        -
      • -
      • -

        C style string escapes no longer supported by config parser

        -

        - The XML config parser no longer supports decoding C style escape sequences in strings. - Previously sequences like \n and \\ - where decoded. Instead use the appropriate XML encodings as required. -

        -
      • -
      -
      - -
      -
        -
      • -

        New CLI build

        -

        - A new log4net assembly is built that targets all CLI 1.0 compatible runtimes. - This build is essentially a common subset of the Mono 1.0 and .NET 1.0 builds. - It is built using the MS .NET 1.0 compiler and libraries but does not use any - platform specific APIs. -

        -

        - This build is only available in release configuration and can be found at - bin\cli\1.0\release. -

        -
      • -
      • -

        Logging contexts

        -

        - Logging contexts can be used to record contextual data that is relevant to the current - process. Logging contexts are both an extension of the concepts embodied in the - MDC and NDC and a replacement for - them. The MDC and NDC have been - reimplemented to use the ThreadContext as storage. -

        -

        - The logging contexts provide a single unified view that cuts across different - scopes within an application. - The contexts are layered in the following order of narrowing scope: - GlobalContext, ThreadContext, - LogicalThreadContext, and LoggingEvent. - Context values specified in a narrower scope hide the matching value in a wider scope. -

        -
      • -
      • -

        PatternLayout customization and long pattern names

        -

        - The PatternLayout now supports long pattern names. - These pattern names are significantly more readable than the single character patterns. -

        -

        - The PatternLayout now supports custom patterns. New patterns - can be defined in the config file: -

        -
        -<layout type="log4net.Layout.PatternLayout">
        -
        -  <converter>
        -    <name value="myConverter" />
        -    <type value="TestApp.MyPatternConverter, TestApp" />
        -  </converter>
        -
        -  <conversionPattern value="%-5level %logger - %myConverter - %message%newline" />
        -</layout>
        -

        - The above config defines a custom pattern called myConverter - which is bound to the TestApp.MyPatternConverter, TestApp - type. This type must extend the log4net.Util.PatternConverter - base class. The custom pattern can then be used in the pattern string. -

        -

        - For full details see the SDK Reference entry: log4net.Layout.PatternLayout. -

        -
      • -
      • -

        PatternString for pattern based configuration

        -

        - A new pattern based type, PatternString, can be used in - the config file to set string properties using a pattern syntax. For example the - File property of the FileAppender could be set as follows: -

        -
        -<file type="log4net.Util.PatternString">
        -
        -  <converter>
        -    <name value="folder" />
        -    <type value="TestApp.SpecialFolderPatternConverter,TestApp" />
        -  </converter>
        -
        -  <conversionPattern value="%folder{LocalApplicationData}\log-file.txt" />
        -</file>
        -

        - The code for the SpecialFolderPatternConverter - is as follows: -

        -
        -public class SpecialFolderPatternConverter : log4net.Util.PatternConverter 
        -{
        -  override protected void Convert(System.IO.TextWriter writer, object state) 
        -  {
        -    Environment.SpecialFolder specialFolder = 
        -      (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), base.Option, true);
        -      
        -    writer.Write(Environment.GetFolderPath(specialFolder));
        -  }
        -}
        -

        - For full details see the SDK Reference entry: log4net.Util.PatternString. -

        -
      • -
      • -

        Loading configuration from a URI

        -

        - The XmlConfigurator methods now support loading the - configuration data from a URI. Config can be loaded from any URI supported by the - System.Net.WebRequest class. -

        -
      • -
      • -

        Support for No-Touch deployment

        -

        - Log4net supports configuring No-Touch deployment applications using the - XmlConfiguratorAttribute. If a relative config file - or extension is specified then this is resolved relative to the deployment - URI. -

        -
      • -
      • -

        Config file parser enhancements

        -

        - The config file parser has been enhanced to support specifying the property subtype, or intermediate type, - directly on the property element, for example: -

        -
        -<layout type="log4net.Layout.PatternLayout" value="%message%newline" />
        -

        - Implicit conversion will be attempted between the value string and the type specified, - and then again between the type and the target property type. -

        -
      • -
      • -

        .NET string formatting syntax

        -

        - Added .NET String.Format style formatting syntax methods to - the ILog interface. The new methods are: - DebugFormat, InfoFormat, - WarnFormat, ErrorFormat - and FatalFormat. -

        -
      • -
      • -

        Customizable levels

        -

        - Levels are defined by the repository LevelMap. The defined - levels, the relative ordering of levels and level display names can be configured on - a per-repository basis. -

        -
      • -
      • -

        Per-appender security contexts

        -

        - Appenders that interact with controlled platform resources, e.g. files, can be - configured to use a separate security context when accessing these resources. - The calling thread may not have appropriate privileges to access the resource a - custom SecurityContext can be used to elevate the - privileges of the appender. The WindowsSecurityContext - is used to specify alternative credentials on the Windows platform. -

        -
      • -
      • -

        Added new appenders

        -
        -
        AnsiColorTerminalAppender
        -
        -

        - The AnsiColorTerminalAppender writes events to - the application's ANSI terminal window. It can be configured to specify - the text and background colors for different level events. Note that Console - applications running on Windows do not have an ANSI terminal window and - should use the ColoredConsoleAppender instead. -

        -
        -
        LocalSyslogAppender
        -
        -

        - Logs events to a local syslog service. This appender uses the POSIX libc syslog - library functions. If these functions are not available on the local system then - this appender will not work! -

        -
        -
        RemoteSyslogAppender
        -
        -

        - The RemoteSyslogAppender uses the BSD syslog protocol to - log to a syslog daemon. The syslogd listens for for messages on UDP port 514. -

        -
        -
        TelnetAppender
        -
        -

        - The TelnetAppender accepts socket connections and streams - logging messages back to the client. The output is provided in a telnet-friendly way - so that a log can be monitored over a TCP/IP socket. - This allows simple remote monitoring of application logging. -

        -
        -
        -
      • -
      • -

        Added new LoggerMatchFilter filter

        -

        - Added LoggerMatchFilter which matches a string against - the event's logger name. -

        -
      • -
      • -

        Pluggable file locking models for the FileAppender

        -

        - The FileAppender (and by extension the - RollingFileAppender) now support pluggable file - locking models. The default model, ExclusiveLock, - maintains the current exclusive file locking behavior. An alternative - model, MinimalLock, can be used to support writing to - a single output file from multiple processes. -

        -

        - For full details see the SDK Reference entry: log4net.Appender.FileAppender.LockingModel. -

        -
      • -
      • -

        RollingFileAppender roll once

        -

        - The RollingFileAppender now supports a new - rolling style, Once. In this mode the appender - will roll the file once per run. -

        -
      • -
      • -

        SmtpAppender authentication

        -

        - On the .NET 1.1 platform only, the SmtpAppender supports authenticating - against the mail server using either username and password or integrated NTLM authentication. -

        -
      • -
      • -

        AdoNetAppender ReconnectOnError

        -

        - Added new configuration property to AdoNetAppender. - Setting ReconnectOnError to true - will force the appender to attempt to reconnect to the database if the connection - is lost. -

        -
      • -
      • -

        UdpAppender hostname support

        -

        - The UdpAppender config property RemoteAddress - can now be specified as a DNS hostname string. The hostname is resolved to an IP address. -

        -
      • -
      -
      - -
      -
        -
      • -

        FxCop compliance

        -

        - Updates to bring the internal code in line with the current FxCop rules. -

        -
      • -
      • -

        Separate NUnit tests

        -

        - Moved the NUnit tests into a separate project, log4net.Tests. -

        -
      • -
      • -

        Bug Fixes

        -
        -
        RemotingAppender
        -
        -

        - Sends events from a ThreadPool thread - rather than the calling thread to prevent transfer, - and potential loss, of the CallContext. -

        -
        -
        RollingFileAppender
        -
        -

        - Fixed date rolling period detection for non UTC timezones. -

        -
        -
        ColoredConsoleAppender
        -
        -

        - Updated to support writing more than 30,000 chars in a single message. - Fixed background color overspill if the console window needs to - scroll the contents. -

        -
        -
        -
      • -
      -
      - -
      - -
      -
        -
      • -

        Changed assembly name to log4net

        -

        - The build output is now log4net.dll - for all frameworks. This is a breaking change. -

        -

        - To resolve cross platform and cross version issues we have - changed the log4net assembly to use a common name for all - frameworks. The assembly friendly name is now log4net. - The builds for each framework can now be differentiated - by the assembly title. This includes the name of the framework - that the assembly was built on. -

        -
      • -
      • -

        Combined Release and ReleaseStrong builds

        -

        - The Release and ReleaseStrong builds have been consolidated into - a single build called Release. This Release build is strongly named. -

        -
      • -
      • -

        New Appender: ColoredConsoleAppender

        -

        - The ColoredConsoleAppender writes events to the - application's console. It can be configured to specify the text and background - colors for different level events. -

        -
      • -
      • -

        New Appender: SmtpPickupDirAppender

        -

        - The SmtpPickupDirAppender generates SMTP compliant - messages and writes them to a local directory. These files can then be read - by an SMTP agent (e.g. the IIS SMTP Agent) and delivered. -

        -
      • -
      • -

        New Layout: XmlLayoutSchemaLog4j

        -

        - This new layout formats the logging events as XML which complies with - the log4j event dtd. This can be used to transfer log event from log4net - to log4j. Currently the only appender that can communicate directly with - log4j is the UdpAppender. -

        -
      • -
      • -

        New PatternLayout conversion characters

        -

        - Added support for capturing the current thread principal name and the - app domain friendly name for each logging event. -

        -
        -
        %a
        -
        - Used to output the friendly name of the AppDomain where the - logging event was generated. -
        -
        %u
        -
        - Used to output the user name for the currently active user - (Principal.Identity.Name). -
        -
        -
      • -
      • -

        Types specified in the config file are now loaded ignoring case

        -

        - All types specified in the configuration files are now loaded - using a case insensitive method. -

        -
      • -
      • -

        Fine grained fixing for buffered events

        -

        - The LoggingEvent now supports fine grained - fixing of data that needs to be accessed outside the append context, - e.g. when an event is buffered. The new Fix - property takes a combination of the FixFlags - enumeration values. -

        -
      • -
      • -

        Code updated inline with FxCop 1.21

        -

        - In line with the FxCop 1.21 guidelines: - Sealed utility classes. Added serialization security demand to GetObjectData. - Renamed parameters. -

        -
      • -
      • -

        EventLogAppender 32K Limit

        -

        - There is a limit of 32K characters in an EventLog message. Added a - check that only logs the first 32000 characters from the rendered - message. -

        -
      • -
      -
      - -
      -
        -
      • -

        Updated to support the Microsoft .NET Framework 1.1 Final

        -

        - Updated to support the Microsoft .NET Framework 1.1 Final Beta (1.1.4322). -

        -
      • -
      • -

        Features document

        -

        - Added a new document that covers the main features of log4net. - See the features - document for more information. -

        -
      • -
      • -

        Hierarchy disabled until it is configured

        -

        - The Hierarchy is now disabled until it has been configured. - All messages logged to the Hierarchy before it has been - configured will be ignored without an error message being - written to the console. -

        -

        - If you are configuring log4net programmatically (i.e. not using - one of the built-in configurators) you must set the - ILoggerRepository.Configured property - to true once you have configured - the repository. -

        -

        - The no appenders defined for a logger message will no longer be - displayed on the console by default. This message will only be - displayed if internal debugging is enabled. -

        -
      • -
      • -

        New examples in VisualBasic.NET, JScript and Managed C++

        -

        - New examples in VisualBasic.NET, JScript and Managed C++. - TODO Link to document about examples. -

        -
      • -
      • -

        Code and Documentation Updates

        -

        - Code fixes. Documentation and manual updates. - See the ChangeLog for more information. -

        -
      • -
      • -

        Added document with example appender configurations

        -

        - See the Example Appender Configuration - document for more information. -

        -
      • -
      -
      - -
      -
        -
      • -

        Added support for multiple frameworks

        -

        - log4net 1.2.0 beta 6 adds support for the the following frameworks: -

        -
        - - - - - - - - - - - - - - - - - - - - - - - - -
        - Framework - Website
        Microsoft .NET Framework 1.1 Final Beta (1.1.4322)http://msdn.microsoft.com/net
        Microsoft .NET Compact Framework 1.0 (1.0.5000)http://msdn.microsoft.com/vstudio/device/compactfx.asp
        Mono 0.23http://www.go-mono.org
        Microsoft Shared Source CLI 1.0http://msdn.microsoft.com/library/en-us/dndotnet/html/mssharsourcecli.asp
        -
        -
        -

        - Not all frameworks are created equal and some features have been excluded from - some of the builds. See the Framework Support document for more information. -

        -
      • -
      • -

        New build system using NAnt

        -

        - The new build system allows log4net to be built for all supported frameworks and - in all build configurations in one go. -

        -
      • -
      • -

        New source code & distribution layout

        -

        - The source code & distribution layout has been updated to support the new - build environment and multiple target frameworks. -

        -
      • -
      • -

        Removed DomainAttribute.UseDefaultDomain property

        -

        - Updated default behavior of DefaultRepositorySelector. Assemblies - are now by default placed into the default domain. To specify another domain, - the DomainAttribute must be used. This is the opposite behavior - to what was previously available. If you were previously specifying the DomainAttribute.UseDefaultDomain - property then you should remove it, and if the default behavior is now - sufficient, you do not need to specify the DomainAttribute at all. -

        -
      • -
      • -

        Updated configuration file parser

        -

        - Updated config file parser to use the element name as the property to set. Also - removed <object> tag, the type attribute can now be - specified on the property element directly. -

        -

        - For example: -

        -
        -<appender>
        -  <param name="Evaluator">
        -    <object type="log4net.spi.LevelEvaluator">
        -      <constructor>
        -        <param type="log4net.spi.Level" value="DEBUG"/>
        -      </constructor>
        -    </object>
        -  </param>
        -</appender>
        -

        - becomes: -

        -
        -<appender>
        -  <evaluator type="log4net.spi.LevelEvaluator">
        -    <threshold value="DEBUG"/>
        -  </evaluator>
        -</appender>
        -
      • -
      • -

        Support for event ID

        -

        - The EventLogAppender now supports setting the event ID in the - event log, this is taken from the EventID property from the per - event Properties map on the LoggingEvent. -

        -
      • -
      • -

        Updated ADONetAppender

        -

        -

          -
        • - Added support for prepared statements and stored procedures
        • -
        • - Added RawTimeStampLayoutto correctly convert the timestamps into - database date time format
        • -
        • - Added ExceptionLayout to render the exception data
        • -
        -

        -

      • -
      • -

        Support for front-end extension

        -

        - This allows the logging API to be wrapped or adapted for specific purposes. Two - extension samples are included in the distribution: -

        -
        - - - - - - - - - - - - - - - - - -
        - Extension - Description
        log4net.Ext.TraceAdds trace logging methods
        log4net.Ext.EventIDAdds additional eventId parameter to all methods
        -
        -

        -

      • -
      • -

        Added ForwardingAppender

        -

        Forwards events to multiple sub appenders after applying filter rules.

        -
      • -
      • -

        Added BufferingForwardingAppender

        -

        Forward events to sub appenders after buffering them.

        -
      • -
      • -

        Added ASPNetTraceAppender

        -

        Logs events to the ASP.NET trace system.

        -
      • -
      • -

        Added NetSendAppender

        -

        Delivers logging events using the Windows Messenger service.

        -
      • -
      • -

        Added UdpAppender

        -

        Sends logging events as connectionless UDP datagrams to a remote host or a - multicast group.

        -
      • -
      • -

        Removed obsolete methods

        -
      • -
      • -

        Lots of updates to improve our compliance with FxCop

        -
      • -
      • -

        Improved SDK documentation

        -
      • -
      -
      - -
      -
        -
      • -

        Fixed Exception thrown when DOM Configurator called with a null XML - Element.

        -

        This occurred if the configuration file did not have a log4net section defined.

        -
      • -
      • -

        Made level lookup case insensitive

        -
      • -
      • -

        Prevented the Hierarchy's Threshold level from being set to a null reference

        -
      • -
      -
      - -
      -
        -
      • -

        Added event specific properties to the logging event object

        -

        - Appenders can add additional information to the events they are logging. The RemotingAppender - and the SMTPAppender both add a 'hostname' property to the events. - These properties can be accessed using the PatternLayout with the - %P{name} syntax. -

        -
      • -
      • -

        Added a plugin framework

        -

        An IPlugin interface can be attached to any repository.

        -
      • -
      • -

        A new RemoteLoggingServerPlugin plugin acts as the server for the - RemotingAppender

        -
      • -
      • -

        Updated the core log4net framework to work in an environment with no - permissions

        -

        Specific appenders still require additional permissions to log correctly

        -
      • -
      • -

        Added support for domain aliasing using the AliasDomainAttribute

        -

        This allows a parent assembly to take control of the logging domain for child - assemblies.

        -
      • -
      • -

        Added events for repository creation, configuration change, configuration reset - and repository shutdown

        -
      • -
      • -

        Added LevelMap to the ILoggerRepository interface

        -

        The mapping from level name to level object is now repository specific, - therefore each repository can have independent mappings.

        -
      • -
      • -

        Moved hierarchy specific config file parser to new DOMHierarchyConfigurator class

        -

        This is controlled by the Hierarchy object and allows for better - encapsulation.

        -
      • -
      • -

        Added OnlyFixPartialEventData property to the buffered appenders

        -

        This setting causes slow settings to be ignored. This significantly improves the - performance of the buffered appenders.

        -
      • -
      • -

        XML entity references are supported in the XML config file.

        -
      • -
      • -

        Added support for expanding environment variables in <param> values

        -

        - The environment variables must be specified as ${FOO} where FOO - is the name of the variable to expand. -

        -
      • -
      • -

        Upgraded to use NUnit 2.0

        -
      • -
      • -

        File appenders can specify the encoding to use for the file

        -
      • -
      • -

        Added strong named configuration

        -
      • -
      -
      - -
      -
        -
      • -

        Added log4net.Ext.Trace extension

        -

        This is a separate assembly that adds a trace level to log4net.

        -
      • -
      • -

        The default log file output directory is now the application base directory not - the current directory

        -
      • -
      • -

        Added MemoryAppender

        -

        Stores all the logging events in an in-memory buffer.

        -
      • -
      • -

        Moved the Hierarchy implementation into a separate namespace

        -

        - The log4net.Repository.Hierarchy namespace now contains all the - code that is specific to the Hierarchy implementation. -

        -
      • -
      • -

        Refactored the DOMConfigurator and BasicConfigurator

        -

        - The Hierarchy specific data schema and implementation could be has - now been moved to the log4net.Repository.Hierarchy namespace. The - bootstrap code for these configurators remains in the log4net.Config - namespace. -

        -
      • -
      • -

        Replaced the DOMConfiguratorAttribute UseExecutableDomain - property with UseDefaultDomain

        -

        - This change to the implementation of the DOMConfiguratorAttribute should - allow the configuration of multiple assemblies to be accomplished more easily, - especially when developing web applications (ASP.NET). -

        -
      • -
      • -

        A few good bug fixes!

        -
      • -
      -
      - -
      -
        -
      • -

        Added ADONetAppender

        -

        Thanks to TechnologyOneCorp.com.

        -
      • -
      • -

        Added TraceLogAssembly extensibility example

        -
      • -
      • -

        Lots of bug fixes

        -
      • -
      -
      - -
      -
        -
      • -

        Added 6 new examples

        -
      • -
      • -

        Split Category class into Logger and LogManager classes

        -

        - The instance methods from Category have moved to the Logger - class. The static methods from Category have moved to the LogManager - class. The Category class still exists but for backward - compatibility only. Changed interface ICategoryFactory to ILoggerFactory - and the implementation class DefaultCategoryFactory to DefaultLoggerFactory. -

        -
      • -
      • -

        Replaced Priority class with Level class

        -

        - The Priority class has been replaced by the Level class. - The Priority class still exists for backward compatibility only. - The Level class implements a static pool of Level objects. - The Level class is sealed and serializable. -

        -
      • -
      • -

        Added ILoggerRepository interface implemented by Hierarchy

        -

        - The Hierarchy class implements the ILoggerRepository interface. - This interface is used by the LogManager class and therefore - allows different implementations of ILoggerRepository to be used. -

        -
      • -
      • -

        Enhanced NUnit tests

        -

        - All the NUnit tests can be run using a single TestSuite: NUnitGUI - log4net.LogManager+AllTests,log4net.dll. -

        -
      • -
      • -

        Added support for serializing LoggingEvents

        -

        - The LoggingEvent class is serializable. All local state is - captured before serialization occurs. This now allows LoggingEvent - objects to be serialized between applications or machines. -

        -
      • -
      • -

        Added RemotingAppender

        -

        - Delivers LoggingEvents to a remote interface. This can be used to - collect distributed logging into a single log file. There is an example - remoting sink that receives the logging events, see examples\net\remoting\RemotingServer - for details. -

        -
      • -
      • -

        Added support for rendering composite objects

        -

        - The IObjectRenderer interface method DoRender now - takes a RendererMap argument. This allows the renderer to use the - appropriate renderer from the RendererMap to render any nested - objects. -

        -
      • -
      • -

        Added support for rendering exceptions

        -

        - The DefaultRenderer now has support for rendering exceptions to a - string. This includes nested exceptions. The RendererMap is now - used to render exceptions in the LoggingEvent. This allows the - rendering of specific exceptions to be enhanced by specific renderers. -

        -
      • -
      • -

        Added ITriggeringEventEvaluator interface

        -

        - This interface is used by SMTPAppender and RemotingAppender - to determine if a LoggingEvent meets a set of user defined - criteria. These appenders use the interface to determine whether or not to - deliver the current buffer of events to their listener. The interface is - implemented by the LevelEvaluator class, which triggers above a - set level. -

        -
      • -
      • -

        Added regex matching to the MDCFilter, NDCFilter and StringMatchFilter

        -

        - The MDCFilter, NDCFilter and StringMatchFilter - can now be configured to use regex matches in addition to substring matches. - Set the RegexToMatch property to use this feature. -

        -
      • -
      • -

        Added XMLLayout

        -

        - emits an XML element for each LoggingEvent. This allows logging - events to be stored and manipulated as XML. The DTD for the XML emitted is in - the log4net-events.dtd -

        -
      • -
      • -

        Added support for <logger> and <level> elements in the - DOMConfigurator

        -

        - As the Category and Priority classes have been - replaced by the Logger and Level classes. The DOMConfigurator - has been updated to allow the <logger> and <level> - elements to be used in place of the <category> and <priority> - elements. The old elements are still accepted for backward compatibility. -

        -
      • -
      • -

        Added Threshold property to Hierarchy

        -

        - Changed DisableXXX() methods on Hierarchy to a Threshold - property. -

        -
      • -
      • -

        Added support for logging domains

        -

        - The LogManager supports multiple logging domains. The LogManager - uses an instance of the IRepositorySelector class to map from - domains to ILoggerRepository instances. The default implementation - is to have a separate ILoggerRepository for each domain. When a - call is made to the static methods on LogManager the domain can be - specified (as a string) or the domain can be inferred automatically from the - calling assembly. The default behavior is for each assembly loaded into the - process to have its own domain and ILoggerRepository. These can - each be configured separately. This allows standalone assemblies to use log4net - without conflicting with other modules in the process. The domain for the - assembly is configured using metadata attributes defined on the assembly. -

        -
      • -
      • -

        DOMConfigurator can set params to arbitrary objects

        -

        - Using a new <object> element, params can now be set to any - creatable object. -

        -
      • -
      -
      - -
      - -
      diff --git a/xdocs/src/roadmap.xml b/xdocs/src/roadmap.xml deleted file mode 100644 index bbffc23f..00000000 --- a/xdocs/src/roadmap.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Development Roadmap - - - - - -
      -

      - The log4net development roadmap is managed by our JIRA issue tracking system. -

      -

      - For a list of upcoming fixes and in-progress tasks see: -

      - -
      - - - -
      diff --git a/xdocs/src/stylesheets/project.xml b/xdocs/src/stylesheets/project.xml deleted file mode 100644 index 557a2e01..00000000 --- a/xdocs/src/stylesheets/project.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - log4net - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/xdocs/src/stylesheets/site.vsl b/xdocs/src/stylesheets/site.vsl deleted file mode 100644 index 25910232..00000000 --- a/xdocs/src/stylesheets/site.vsl +++ /dev/null @@ -1,406 +0,0 @@ - - - - - - ## Defined variables - #set ($bodybg = "#ffffff") - #set ($bodyfg = "#000000") - #set ($bodylink = "#525D76") - - #set ($titlebg = "#FFFFFF") - #set ($titlefg = "#2222AA") - -## #set ($bannerbg = "#525D76") - #set ($bannerbg = "#FFFFFF") - #set ($bannerfg = "#2222AA") - - #set ($subbannerbg = "#828DA6") - #set ($subbannerfg = "#ffffff") - #set ($tablethbg = "#039acc") - #set ($tabletdbg = "#a0ddf0") - - -#document() - - -## This is where the macro's live - -#macro ( projectanchor $name $value ) -#if ($value.startsWith("http://")) - $name -## #elseif ($value.startsWith("/site")) -## $name -#else - $name -#end -#end - -#macro ( metaauthor $author $email ) - - -#end - -#macro ( image $value ) -#if ($value.getAttributeValue("width")) -#set ($width=$value.getAttributeValue("width")) -#end -#if ($value.getAttributeValue("height")) -#set ($height=$value.getAttributeValue("height")) -#end -#if ($value.getAttributeValue("align")) -#set ($align=$value.getAttributeValue("align")) -#end - -#end - -#macro ( old_source $value ) -
      - - - - - - - - - - - - - - - - -
      $escape.getText($value.getText())
      -
      -#end - -#macro ( source $value ) - -
      $escape.getText($value.getText())
      - -#end - -## =================================== -## titleSection macro -## =================================== -#macro ( titleSection $titleSection) - $titleSection.getAttributeValue("name") -#end - -## ================================ -## section macro -## ================================ -#macro ( section $section $level ) - #if($section.getAttributeValue("id")) - $section.getAttributeValue("name") - #else - $section.getAttributeValue("name") - #end -
      - #foreach ( $item in $section.getChildren() ) - #if ($items.getName().equals("img")) - #image ($item) - #elseif ($item.getName().equals("source")) - #source ($item) - #elseif ($item.getName().equals("table")) - #table ($item) - #elseif ($item.getName().equals("section")) - #set ($nextLevel = $level + 1) - #section ($item $nextLevel ) - #set ($nextLevel = $nextLevel - 1) - #elseif ($item.getName().equals("sectionMenu")) - #set ($nextLevel = $level + 1) - #sectionMenu1 ($item $item.getParent() $nextLevel) - #set ($nextLevel = $nextLevel - 1) - #else - $item - #end - #end -
      -#end - -## ================================ -## sectionMenu1 macro -## ================================ -#macro ( sectionMenu1 $sectionMenu $section $level ) - #if($sectionMenu.getAttributeValue("name")) - $sectionMenu.getAttributeValue("name") -
      - #foreach ( $items in $section.getChildren() ) - #if ($items.getName().equals("section")) - #sectionMenu2 ($items ) - #end - #end -
      - #else - #foreach ( $items in $section.getChildren() ) - #if ($items.getName().equals("section")) - #sectionMenu2 ($items ) - #end - #end - #end -#end - -## ================================ -## sectionMenu2 macro -## ================================ -#macro ( sectionMenu2 $section ) - #if ($section.getAttributeValue("id")) - $section.getAttributeValue("name")
      - #else - $section.getAttributeValue("name")
      - #end -
      - #foreach ( $items in $section.getChildren() ) - #if ($items.getName().equals("section")) - #sectionMenu2 ($items ) - #end - #end -
      -#end - -## =================================== -## make navigation bar -## =================================== - -#macro ( makeNavigationBar ) - -
      - #set ($menus = $project.getChild("body").getChildren("menu")) - #foreach ( $menu in $menus ) - - #foreach ($item in $menu.getChildren() ) - #set ($name = $item.getAttributeValue("name")) - - #end - #end -
      - -#end - -## ==================================== -## getProjectImage -## ==================================== -#macro (getProjectImage) - ## -#end - -#macro (printMeta $metaElement) - -#end - -#macro (messages $root) - #foreach ( $m in $root.getChild("body").getChildren() ) - #if ($m.getName().equals("message")) - -
      - $m.getChild("explanation").getContent() -
      - #end - #end -#end - -#macro (document) - #set ($properties = $root.getChild("properties") ) - - - - - - - - - #set ($authors = $root.getChild("properties").getChildren("author")) - #foreach ( $au in $authors ) - #metaauthor ( $au.getText() $au.getAttributeValue("email") ) - #end - - #set ($metas = $root.getChildren("meta")) - - ## Parse meta directives such as - ## - #foreach ($meta in $metas) #printMeta($meta) #end - - ## Support for tags. - #if ($root.getChild("properties").getChild("base")) - #set ($url = $root.getChild("properties").getChild("base").getAttributeValue("href")) - - #end - - - - #foreach ( $cssItem in $project.getChildren("css") ) - - #end - - $root.getChild("properties").getChild("title").getText() - - #if ($root.getChild("head")) - $root.getChild("head").getContent() - #end - - - - ## Google analytics code - - - - -## -## -## - #getProjectImage() -## -##
      - - - -
      - ##
      - - -## -## - -## -## -## -## -## - - - #messages ($root) - - -

       

      - -## -## - ##
      -##
      -##
      - - #foreach ( $item in $root.getChild("body").getChildren() ) - #if ($item.getName().equals("img")) - #image ($item) - #elseif ($item.getName().equals("section")) - #section ($item 1) - #elseif ($item.getName().equals("source")) - #source ($item) - #elseif ($item.getName().equals("table")) - #table ($item) - #elseif ($item.getName().equals("sectionMenu")) - #sectionMenu1 ($item $item.getParent() 1) - #else - $item - #end - #end - -## #if ($root.getChild("body").getChild("titleSection")) -## #set ($titleSection = $root.getChild("body").getChild("titleSection")) -## #titleSection($titleSection) -## #end -##
      -##
      -##
      -
      - Copyright © - #if($root.getChild("properties").getChild("copyright").getAttributeValue("year")) - ${root.getChild("properties").getChild("copyright").getAttributeValue("year")}, - #elseif($project.getChild("copyright").getAttributeValue("year")) - ${project.getChild("copyright").getAttributeValue("year")}, - #else - 1999-2007, - #end - #if($root.getChild("properties").getChild("copyright").getAttributeValue("holder")) - ${root.getChild("properties").getChild("copyright").getAttributeValue("holder")} - #elseif($project.getChild("copyright").getAttributeValue("holder")) - ${project.getChild("copyright").getAttributeValue("holder")} - #else - Apache Software Foundation - #end -
      - ##
      - - -
      - - - #makeNavigationBar() - - ## Call the google analyticis code to register this page - - - -#end - - - - - diff --git a/xdocs/src/support.xml b/xdocs/src/support.xml deleted file mode 100644 index dbf661ec..00000000 --- a/xdocs/src/support.xml +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - Nicko Cadell - Apache log4net: Support - - - - - -
      - -

      - log4net user support is provided via a mailing list. Discussion on log4net is held on the - log4net-user mailing list. Please search the archives before posting because it - is likely that your question has been answered before. -

      - -
      -

      - You can browse the mailing list archives at the following locations: -

      - - -
      - -
      -

      - Subscribe to either the list or to the digest list: -

      - - -
      - -
      -

      - To unsubscribe send an email to the relevant email address: -

      - - -
      - -
      -

      - Before posting please read the following guidelines: -

      - -
        -
      • -

        - Ask smart questions
        - Every volunteer project obtains its strength from the people involved - in it. You are welcome to join any of our mailing lists. You can - choose to lurk, or actively participate; it's up to you. The level of - community responsiveness to specific questions is generally directly - proportional to the amount of effort you spend formulating your - question. Eric Raymond and Rick Moen have even written an essay entitled - "Asking Smart Questions" - precisely on this topic. -

        -
      • - -
      • -

        - Keep your email short and to the point
        - If your email is more than about a page of text, chances are that it - won't get read by very many people. It is much better to try to pack a - lot of informative information (see above about asking smart questions) - into as small of an email as possible. If you are replying to a previous - email, it is a good idea to only quote the parts that you are replying - to and to remove the unnecessary bits. This makes it easier for people - to follow a thread as well as making the email archives easier to search - and read. -

        -
      • - -
      • -

        - Do your best to ensure that you are not sending HTML or "Stylelized" email to the list
        - If you are using Outlook or Outlook Express or Eudora, chances are that - you are sending HTML email by default. There is usually a setting that - will allow you to send "Plain Text" email. If you are using Microsoft - products to send email, there are several bugs in the software that - prevent you from turning off the sending of HTML email. Please read this - page as well. -

        -
      • - -
      • -

        - Watch where you are sending email
        - Our mailing lists have set the Reply-To to go back to the - list. That means that when you Reply to a message, it will go to the list - and not to the original author directly. The reason is because it helps - facilitate discussion on the list for everyone to benefit from. Be careful - of this as sometimes you may intend to reply to a message directly to someone - instead of the entire list. -

        -

        - The appropriate contents of the Reply-To header is an age-old debate that - should not be brought up on the mailing lists. You can examine opposing points of view - condemning - our convention and condoning - it. Bringing this topic up for debate again on a mailing list will add nothing new - and is considered off-topic. -

        -
      • - -
      • -

        - Do not cross post messages
        - In other words, pick a mailing list and send your messages to that mailing - list only. Do not send your messages to multiple mailing lists. The reason is - that people may be subscribed to one list and not to the other. Therefore, - some people will only see part of the conversation. -

        -
      • -
      - -

      - Where relevant please try to include the following information in your postings. -

      - -
        -
      • -

        - Specify the version of log4net you are using. -

        -
      • - -
      • -

        - Specify what your assembly type is, i.e. exe or dll, and how your code is launched, - e.g. console application, windows application, ASP.NET project, COM+ hosted object, etc... -

        -
      • - -
      • -

        - Specify which runtime platform (e.g. MS .NET, Mono, SSCLI) you are using and which version. -

        -
      • - -
      • -

        - If you are having configuration issues then include logging configuration files if any, plus source code. -

        -
      • - -
      • -

        - If possible please reproduce your issue with the - internal log4net debugging - enabled. Include this debug output in your post, it is usually the first thing we ask for in diagnosing issues. -

        -
      • - -
      • -

        - If you think you have found a bug then a short example reproducing the problem is very much appreciated. -

        -
      • -
      - -

      - To prevent spam, we require you to be subscribed to the list before posting to it. -

      - -

      - Ask questions and report bugs via email to the - log4net-user@logging.apache.org - mailing list. -

      -
      -
      - - - -
      From b366b12c1121bff872e1217212988f930471053b Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sat, 10 Sep 2011 05:07:07 +0000 Subject: [PATCH 051/370] TryParse has been introduced in .NET 2.0. LOG4NET-246 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1167457 13f79535-47bb-0310-9956-ffa450edef68 --- src/Core/DefaultRepositorySelector.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Core/DefaultRepositorySelector.cs b/src/Core/DefaultRepositorySelector.cs index 9dca4140..2caecb7f 100644 --- a/src/Core/DefaultRepositorySelector.cs +++ b/src/Core/DefaultRepositorySelector.cs @@ -705,7 +705,24 @@ private void ConfigureRepository(Assembly assembly, ILoggerRepository repository // Determine whether to watch the file or not based on an app setting value: bool watchRepositoryConfigFile = false; +#if NET_2_0 Boolean.TryParse(SystemInfo.GetAppSetting("log4net.Config.Watch"), out watchRepositoryConfigFile); +#else + { + string watch = SystemInfo.GetAppSetting("log4net.Config.Watch"); + if (watch != null && watch.Length > 0) + { + try + { + watchRepositoryConfigFile = Boolean.Parse(watch); + } + catch (FormatException) + { + // simply not a Boolean + } + } + } +#endif if (watchRepositoryConfigFile) { From ce22bb2663ea6f7903d585f67e5944b900f8ced2 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sat, 10 Sep 2011 06:33:34 +0000 Subject: [PATCH 052/370] TryParse is available on Mono as well git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1167469 13f79535-47bb-0310-9956-ffa450edef68 --- src/Core/DefaultRepositorySelector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/DefaultRepositorySelector.cs b/src/Core/DefaultRepositorySelector.cs index 2caecb7f..d4b872e1 100644 --- a/src/Core/DefaultRepositorySelector.cs +++ b/src/Core/DefaultRepositorySelector.cs @@ -705,7 +705,7 @@ private void ConfigureRepository(Assembly assembly, ILoggerRepository repository // Determine whether to watch the file or not based on an app setting value: bool watchRepositoryConfigFile = false; -#if NET_2_0 +#if NET_2_0 || MONO_2_0 Boolean.TryParse(SystemInfo.GetAppSetting("log4net.Config.Watch"), out watchRepositoryConfigFile); #else { From c942a2dea66e87f7e9a04622bbf97a648ce59d1b Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 10:37:30 +0000 Subject: [PATCH 053/370] Deal with SecurityException in EventLogAppender more gracefully. LOG4NET-310 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169681 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/EventLogAppender.cs | 108 ++++++++++----------- tests/src/Appender/EventLogAppenderTest.cs | 16 ++- 2 files changed, 69 insertions(+), 55 deletions(-) diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs index 629f75de..c1864090 100644 --- a/src/Appender/EventLogAppender.cs +++ b/src/Appender/EventLogAppender.cs @@ -233,60 +233,60 @@ public SecurityContext SecurityContext /// override public void ActivateOptions() { - base.ActivateOptions(); - - if (m_securityContext == null) - { - m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); - } - - bool sourceAlreadyExists = false; - string currentLogName = null; - - using(SecurityContext.Impersonate(this)) - { - sourceAlreadyExists = EventLog.SourceExists(m_applicationName); - if (sourceAlreadyExists) - { - currentLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); - } - } - - if (sourceAlreadyExists && currentLogName != m_logName) - { - LogLog.Debug(declaringType, "Changing event source [" + m_applicationName + "] from log [" + currentLogName + "] to log [" + m_logName + "]"); - } - else if (!sourceAlreadyExists) - { - LogLog.Debug(declaringType, "Creating event source Source [" + m_applicationName + "] in log " + m_logName + "]"); - } - - string registeredLogName = null; - - using(SecurityContext.Impersonate(this)) - { - if (sourceAlreadyExists && currentLogName != m_logName) - { - // - // Re-register this to the current application if the user has changed - // the application / logfile association - // - EventLog.DeleteEventSource(m_applicationName, m_machineName); - CreateEventSource(m_applicationName, m_logName, m_machineName); - - registeredLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); - } - else if (!sourceAlreadyExists) - { - CreateEventSource(m_applicationName, m_logName, m_machineName); - - registeredLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); - } - } - - m_levelMapping.ActivateOptions(); - - LogLog.Debug(declaringType, "Source [" + m_applicationName + "] is registered to log [" + registeredLogName + "]"); + try { + base.ActivateOptions(); + + if (m_securityContext == null) { + m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); + } + + bool sourceAlreadyExists = false; + string currentLogName = null; + + using (SecurityContext.Impersonate(this)) { + sourceAlreadyExists = EventLog.SourceExists(m_applicationName); + if (sourceAlreadyExists) { + currentLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); + } + } + + if (sourceAlreadyExists && currentLogName != m_logName) { + LogLog.Debug(declaringType, "Changing event source [" + m_applicationName + "] from log [" + currentLogName + "] to log [" + m_logName + "]"); + } + else if (!sourceAlreadyExists) { + LogLog.Debug(declaringType, "Creating event source Source [" + m_applicationName + "] in log " + m_logName + "]"); + } + + string registeredLogName = null; + + using (SecurityContext.Impersonate(this)) { + if (sourceAlreadyExists && currentLogName != m_logName) { + // + // Re-register this to the current application if the user has changed + // the application / logfile association + // + EventLog.DeleteEventSource(m_applicationName, m_machineName); + CreateEventSource(m_applicationName, m_logName, m_machineName); + + registeredLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); + } + else if (!sourceAlreadyExists) { + CreateEventSource(m_applicationName, m_logName, m_machineName); + + registeredLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); + } + } + + m_levelMapping.ActivateOptions(); + + LogLog.Debug(declaringType, "Source [" + m_applicationName + "] is registered to log [" + registeredLogName + "]"); + } + catch (System.Security.SecurityException ex) { + ErrorHandler.Error("Caught a SecurityException trying to access the EventLog. Most likely the event source " + + m_applicationName + + " doesn't exist and must be created by a local administrator. Will disable EventLogAppender", ex); + Threshold = Level.Off; + } } #endregion // Implementation of IOptionHandler diff --git a/tests/src/Appender/EventLogAppenderTest.cs b/tests/src/Appender/EventLogAppenderTest.cs index 12386a18..4d706664 100644 --- a/tests/src/Appender/EventLogAppenderTest.cs +++ b/tests/src/Appender/EventLogAppenderTest.cs @@ -40,9 +40,10 @@ public class EventLogAppenderTest /// event log enumeration is returned ///

      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

    [Test] - public void TestGetEntryType() + public void TestGetEntryTypeForExistingApplicationName() { EventLogAppender eventAppender = new EventLogAppender(); + eventAppender.ApplicationName = "Winlogon"; eventAppender.ActivateOptions(); Assert.AreEqual( @@ -74,6 +75,18 @@ public void TestGetEntryType() GetEntryType(eventAppender, Level.Off)); } + /// + /// ActivateOption tries to create an event source if it doesn't exist but this is going to fail on more modern Windows versions unless the code is run with local administrator privileges. + /// + [Test] + [Platform(Exclude = "Win2K,WinXP")] + public void ActivateOptionsDisablesAppenderIfSourceDoesntExist() + { + EventLogAppender eventAppender = new EventLogAppender(); + eventAppender.ActivateOptions(); + Assert.AreEqual(Level.Off, eventAppender.Threshold); + } + // // Helper functions to dig into the appender // @@ -82,5 +95,6 @@ private static EventLogEntryType GetEntryType(EventLogAppender appender, Level l { return (EventLogEntryType)Utils.InvokeMethod(appender, "GetEntryType", level); } + } } \ No newline at end of file From fa426b2e18eecca3734d5ec980cbd5149e9ab96d Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 10:59:29 +0000 Subject: [PATCH 054/370] Point to existing FAQ entry. LOG4NET-310 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169687 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/EventLogAppender.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs index c1864090..8e2390cd 100644 --- a/src/Appender/EventLogAppender.cs +++ b/src/Appender/EventLogAppender.cs @@ -38,6 +38,10 @@ namespace log4net.Appender /// Writes events to the system event log. ///
    /// + /// + /// The appender will fail if you try to write using an event source that doesn't exist unless it is running with local administrator privileges. + /// See also http://logging.apache.org/log4net/release/faq.html#trouble-EventLog + /// /// /// The EventID of the event log entry can be /// set using the EventLogEventID property () @@ -284,7 +288,9 @@ override public void ActivateOptions() catch (System.Security.SecurityException ex) { ErrorHandler.Error("Caught a SecurityException trying to access the EventLog. Most likely the event source " + m_applicationName - + " doesn't exist and must be created by a local administrator. Will disable EventLogAppender", ex); + + " doesn't exist and must be created by a local administrator. Will disable EventLogAppender." + + " See http://logging.apache.org/log4net/release/faq.html#trouble-EventLog", + ex); Threshold = Level.Off; } } From 3c7a162cbc260f6de9200a8067ba45d5e47fb0b9 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 11:05:49 +0000 Subject: [PATCH 055/370] Allow EventId to be specified by a property that is neither a string nor an int in EventLogAppender. LOG4NET-129 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169688 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/EventLogAppender.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs index 8e2390cd..72fa4f29 100644 --- a/src/Appender/EventLogAppender.cs +++ b/src/Appender/EventLogAppender.cs @@ -350,6 +350,10 @@ override protected void Append(LoggingEvent loggingEvent) else { string eventIDPropertyString = eventIDPropertyObj as string; + if (eventIDPropertyString == null) + { + eventIDPropertyString = eventIDPropertyObj.ToString(); + } if (eventIDPropertyString != null && eventIDPropertyString.Length > 0) { // Read the string property into a number From 95921e67347832507b0c60b8449234454d340412 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 11:11:35 +0000 Subject: [PATCH 056/370] Bad property name git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169691 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/EventLogAppender.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs index 72fa4f29..1e18b5ab 100644 --- a/src/Appender/EventLogAppender.cs +++ b/src/Appender/EventLogAppender.cs @@ -44,7 +44,7 @@ namespace log4net.Appender /// /// /// The EventID of the event log entry can be - /// set using the EventLogEventID property () + /// set using the EventID property () /// on the . /// /// From b1c7bdcb4200eeb017a0d5cd0fc929c300024f44 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 11:18:52 +0000 Subject: [PATCH 057/370] Allow default value for event id to be specified via configuration. LOG4NET-214 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169694 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/EventLogAppender.cs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs index 1e18b5ab..d3a7b07f 100644 --- a/src/Appender/EventLogAppender.cs +++ b/src/Appender/EventLogAppender.cs @@ -215,6 +215,22 @@ public SecurityContext SecurityContext set { m_securityContext = value; } } + /// + /// Gets or sets the EventId to use unless one is explicitly specified via the LoggingEvent's properties. + /// + /// + /// + /// The EventID of the event log entry will normally be + /// set using the EventID property () + /// on the . + /// This property provides the fallback value which defaults to 0. + /// + /// + public int EventId { + get { return m_eventId; } + set { m_eventId = value; } + } + #endregion // Public Instance Properties #region Implementation of IOptionHandler @@ -337,7 +353,7 @@ override protected void Append(LoggingEvent loggingEvent) // // Write the resulting string to the event log system // - int eventID = 0; + int eventID = m_eventId; // Look for the EventLogEventID property object eventIDPropertyObj = loggingEvent.LookupProperty("EventID"); @@ -479,6 +495,11 @@ virtual protected EventLogEntryType GetEntryType(Level level) ///
    private SecurityContext m_securityContext; + /// + /// The event ID to use unless one is explicitly specified via the LoggingEvent's properties. + /// + private int m_eventId = 0; + #endregion // Private Instance Fields #region Level2EventLogEntryType LevelMapping Entry From 46d625d423a6e024a23170895c180edcefecd663 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 11:58:00 +0000 Subject: [PATCH 058/370] Allow EventLog category to be specified via the LoggingEvent's properties or a configured value. Based on patch by Ron Grabowsky. LOG4NET-38 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169705 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/EventLogAppender.cs | 67 ++++++++++++++++++++++++++++++-- src/Util/SystemInfo.cs | 50 +++++++++++++++++++++++- 2 files changed, 112 insertions(+), 5 deletions(-) diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs index d3a7b07f..1c384074 100644 --- a/src/Appender/EventLogAppender.cs +++ b/src/Appender/EventLogAppender.cs @@ -47,6 +47,11 @@ namespace log4net.Appender /// set using the EventID property () /// on the . /// + /// + /// The Category of the event log entry can be + /// set using the Category property () + /// on the . + /// /// /// There is a limit of 32K characters for an event log message /// @@ -231,7 +236,24 @@ public int EventId { set { m_eventId = value; } } - #endregion // Public Instance Properties + + /// + /// Gets or sets the Category to use unless one is explicitly specified via the LoggingEvent's properties. + /// + /// + /// + /// The Category of the event log entry will normally be + /// set using the Category property () + /// on the . + /// This property provides the fallback value which defaults to 0. + /// + /// + public short Category + { + get { return m_category; } + set { m_category = value; } + } + #endregion // Public Instance Properties #region Implementation of IOptionHandler @@ -355,7 +377,7 @@ override protected void Append(LoggingEvent loggingEvent) // int eventID = m_eventId; - // Look for the EventLogEventID property + // Look for the EventID property object eventIDPropertyObj = loggingEvent.LookupProperty("EventID"); if (eventIDPropertyObj != null) { @@ -386,6 +408,38 @@ override protected void Append(LoggingEvent loggingEvent) } } + short category = m_category; + // Look for the Category property + object categoryPropertyObj = loggingEvent.LookupProperty("Category"); + if (categoryPropertyObj != null) + { + if (categoryPropertyObj is short) + { + category = (short) categoryPropertyObj; + } + else + { + string categoryPropertyString = categoryPropertyObj as string; + if (categoryPropertyString == null) + { + categoryPropertyString = categoryPropertyObj.ToString(); + } + if (categoryPropertyString != null && categoryPropertyString.Length > 0) + { + // Read the string property into a number + short shortVal; + if (SystemInfo.TryParse(categoryPropertyString, out shortVal)) + { + category = shortVal; + } + else + { + ErrorHandler.Error("Unable to parse event category property [" + categoryPropertyString + "]."); + } + } + } + } + // Write to the event log try { @@ -401,7 +455,7 @@ override protected void Append(LoggingEvent loggingEvent) using(SecurityContext.Impersonate(this)) { - EventLog.WriteEntry(m_applicationName, eventTxt, entryType, eventID); + EventLog.WriteEntry(m_applicationName, eventTxt, entryType, eventID, category); } } catch(Exception ex) @@ -500,7 +554,12 @@ virtual protected EventLogEntryType GetEntryType(Level level) ///
    private int m_eventId = 0; - #endregion // Private Instance Fields + /// + /// The event category to use unless one is explicitly specified via the LoggingEvent's properties. + /// + private short m_category = 0; + + #endregion // Private Instance Fields #region Level2EventLogEntryType LevelMapping Entry diff --git a/src/Util/SystemInfo.cs b/src/Util/SystemInfo.cs index 87634cc2..51c150b7 100644 --- a/src/Util/SystemInfo.cs +++ b/src/Util/SystemInfo.cs @@ -835,7 +835,55 @@ public static bool TryParse(string s, out long val) #endif } - /// + /// + /// Parse a string into an value + /// + /// the string to parse + /// out param where the parsed value is placed + /// true if the string was able to be parsed into an integer + /// + /// + /// Attempts to parse the string into an integer. If the string cannot + /// be parsed then this method returns false. The method does not throw an exception. + /// + /// + public static bool TryParse(string s, out short val) + { +#if NETCF + val = 0; + try + { + val = short.Parse(s, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture); + return true; + } + catch + { + } + + return false; +#else + // Initialise out param + val = 0; + + try + { + double doubleVal; + if (Double.TryParse(s, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out doubleVal)) + { + val = Convert.ToInt16(doubleVal); + return true; + } + } + catch + { + // Ignore exception, just return false + } + + return false; +#endif + } + + /// /// Lookup an application setting /// /// the application settings key to lookup From 04d7d79b1ab53001cb617e12cdb9e207f53d7991 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 12:36:06 +0000 Subject: [PATCH 059/370] Race-Condition via shared StringBuilder in ReUsableStringWriter. LOG4NET-76 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169711 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/AppenderSkeleton.cs | 13 +++++++---- src/Util/PatternConverter.cs | 40 ++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/Appender/AppenderSkeleton.cs b/src/Appender/AppenderSkeleton.cs index 10c39814..db5c2297 100644 --- a/src/Appender/AppenderSkeleton.cs +++ b/src/Appender/AppenderSkeleton.cs @@ -697,11 +697,14 @@ protected string RenderLoggingEvent(LoggingEvent loggingEvent) m_renderWriter = new ReusableStringWriter(System.Globalization.CultureInfo.InvariantCulture); } - // Reset the writer so we can reuse it - m_renderWriter.Reset(c_renderBufferMaxCapacity, c_renderBufferSize); - - RenderLoggingEvent(m_renderWriter, loggingEvent); - return m_renderWriter.ToString(); + lock (m_renderWriter) + { + // Reset the writer so we can reuse it + m_renderWriter.Reset(c_renderBufferMaxCapacity, c_renderBufferSize); + + RenderLoggingEvent(m_renderWriter, loggingEvent); + return m_renderWriter.ToString(); + } } /// diff --git a/src/Util/PatternConverter.cs b/src/Util/PatternConverter.cs index ba4c0188..7b333957 100644 --- a/src/Util/PatternConverter.cs +++ b/src/Util/PatternConverter.cs @@ -174,33 +174,43 @@ virtual public void Format(TextWriter writer, object state) } else { - m_formatWriter.Reset(c_renderBufferMaxCapacity, c_renderBufferSize); - - Convert(m_formatWriter, state); - - StringBuilder buf = m_formatWriter.GetStringBuilder(); - int len = buf.Length; - - if (len > m_max) - { - writer.Write(buf.ToString(len - m_max, m_max)); - } - else if (len < m_min) + string msg = null; + int len; + lock (m_formatWriter) + { + m_formatWriter.Reset(c_renderBufferMaxCapacity, c_renderBufferSize); + + Convert(m_formatWriter, state); + + StringBuilder buf = m_formatWriter.GetStringBuilder(); + len = buf.Length; + if (len > m_max) + { + msg = buf.ToString(len - m_max, m_max); + len = m_max; + } + else + { + msg = buf.ToString(); + } + } + + if (len < m_min) { if (m_leftAlign) { - writer.Write(buf.ToString()); + writer.Write(msg); SpacePad(writer, m_min - len); } else { SpacePad(writer, m_min - len); - writer.Write(buf.ToString()); + writer.Write(msg); } } else { - writer.Write(buf.ToString()); + writer.Write(msg); } } } From a7988be37d31128e295d9c9ea5a6982335c736d7 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 12:58:01 +0000 Subject: [PATCH 060/370] rename KEYS file, add my own key git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169723 13f79535-47bb-0310-9956-ffa450edef68 --- KEYS | 600 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ KEYS.txt | 54 ----- 2 files changed, 600 insertions(+), 54 deletions(-) create mode 100644 KEYS delete mode 100644 KEYS.txt diff --git a/KEYS b/KEYS new file mode 100644 index 00000000..58130c5f --- /dev/null +++ b/KEYS @@ -0,0 +1,600 @@ +This file contains the PGP keys of various Apache developers. +These keys are primarily used for code signing. + +These keys can be verified using any OpenPGP compatible system, +for example, http://www.gnupg.org. + +Developers: To add key information use: + gpg --list-keys UID + gpg --export -a UID + +(Where UID is your email address) + + +User: To import this key file into your keyring use: + gpg --import KEYS.txt + + + + + +pub 1024D/914A4D28 2005-03-07 +uid Nicko Cadell +sub 2048g/6923CBDA 2005-03-07 + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.0 (MingW32) + +mQGiBEIsjHURBAC9JqRzMEh6pEZuuyqHGwfBkQZnvOuj0Yp88lDsJtNl62cRaQJk +7eP+kVxCbl12qr1EDz1z/ZON7/+vF9YoiRh7Cydck6wLe/kQcJtUevm00q35pUQJ +7c2TSY+QbTKWriUKueOyRR6p2lpscUHhbCPB9NOLfQmJvZsa47gDZSybCwCgh0+u +8KkkcovlV55K/WrSGg16o8kEAKFGmpDKDnv0Sg1rRnvBGJv5WZFR/57p1SArMXHi +oBkj71wlWz9Ia4tonfc12TXUwoVs3WbIFOoLz1Iw31cGnwUsNkvEclaZigG9iYhx +S6+2i7jrQIivO5iXJtTuePb4zFgLwZcaoFySvLIKRm8+X6KXvoslKAYM/F/Yd0jm +OebkA/4uwIt7cGOWGIaiH2n/80QgXN6FyOhNsgCihZZcPwXo7c/gtszpJ74CwtXD +SVghIwTQ0zK4wtWcHSjf7FelPmeDSga7dLgnxQmmhjIK+sBnPIcBrNiUc3jFnRzK +o3ZIBPsGoo0jUsemgkiQA4ptVybeak/SmrTsRgxWkT4Paw41zrQfTmlja28gQ2Fk +ZWxsIDxuaWNrb0BhcGFjaGUub3JnPoheBBMRAgAeBQJCLIx1AhsDBgsJCAcDAgMV +AgMDFgIBAh4BAheAAAoJEA3R7CqRSk0ooTIAnRZ+vUY+ZN8CgL0fvDbZv76kgQG+ +AJ9vp4BwPLU5jM+YOY3hJPp1bNw1RLkCDQRCLIx/EAgArSrXU4kkXNLCTBIAMaIx +diiVvQ2JqzrFkXf4yAlE+xiy19bqGewmslt+dLmLUEtt1UFMU5b2kAiZLNMvdBWQ +OStwK0SABRESjb5sAjAcFXUeqBzjVBDvsSGxJZZa5He1pQMjFzm4hG6GNl3+vOx6 +r6fly9W5Ddc8wqfDb8JU0c6gG8s10D4gthWWyJ2K1u3BcvpggoGyqyxisvF/QM68 +KnXf8/wp+5sOfl6glyluR/OyGMCU3c38eHYU2XMzlcT3fh1VcU5MvPastp+76vUy +ImrAfb7RhS3sDrmRd9ZS8FE5JRB3967hETRSLjHW+/TZeyvxaGMJkBPdv2BdwnD8 +6wADBQf+NaK8teolegPc1LdmX3bAhR2bhfqIpuUwPBRHqIU2OtWsMJ9sEsVZY4LC +OLOHMHI1spWHEo39mx3fz5MR4x2z3+HzZRq8tzMFn5PC3c7yb06CMfqRf8pvYWVP +0cMvEctViAc+xwSpZgXQGLkwZ37KtqWncfBVocxQMj4CVUx3PeyozWGEG+bpGSso +Mrvnch41AGL3NA9bA2cgTVuOYSXZLK9TOgh4gXCM4jWTI4BqTY5w0riDwqwt5+qH +e8/HBowGa4jNopl9kWaQuEoXH7GGOTJsc9eKMK+k++iqSWiqVXFTLd7/UhUPv6Oj +7Pqm7+oSumphn00rC2DVeAAWDt7umohJBBgRAgAJBQJCLIx/AhsMAAoJEA3R7CqR +Sk0ouF4An1sFuJ+/kJlvKRs+nNjFqrQdsuDCAJ9WDNgUqnAkdLVTRJq8UeK0AjOq +oQ== +=4aNz +-----END PGP PUBLIC KEY BLOCK----- + +pub 1024D/5F6B8B72 2001-05-28 +uid Stefan Bodewig +sig 3 5F6B8B72 2001-05-28 Stefan Bodewig +sig 51898504 2002-01-11 Conor MacNeill +sig 3 F88341D9 2003-03-17 Lars Eilebrecht +sig 3 2261D073 2003-03-17 Astrid Kessler (Kess) +sig 21D0A71B 2003-03-17 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 75A67692 2003-03-18 Erik Abele +sig B3B2A12C 2003-05-20 ct magazine CERTIFICATE +sig 3 8103A37E 2003-04-04 Andre Malo +sig 3 5F6B8B72 2001-05-28 Stefan Bodewig +sig D6298F01 2003-04-27 Paulo Henrique Gaspar Jorge +sig 0CAA68B4 2004-11-11 Patrick Rentsch +sig 2FE28BCF 2005-07-01 Harald Wilhelm (HAWI) +sig 5793498F 2005-07-21 Tim Ellison +sig E4136392 2005-07-21 Noel J. Bergman +sig 8408F755 2005-07-21 Christian Geisert +sig 2 FC243F3C 2005-07-20 Henk P. Penning +sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 3 EE65E321 2005-07-20 Martin Kraemer +sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size +sig 3 3642CB4B 2005-07-20 Martin Kraemer +sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) +sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size +sig 3 CC78C893 2005-07-22 Rich Bowen +sig 3 E2D774DF 2005-07-22 Sylvain Wallez +sig 3 E04F9A89 2005-07-22 Roy T. Fielding +sig 3 015AFC8A 2005-07-22 Bertrand Delacretaz +sig 3 87315C31 2005-07-23 Raphal Luta +sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler +sig 3 F39B3750 2005-07-24 Colm MacCarthaigh +sig 1CD4861F 2005-07-25 Eran Chinthaka +sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) +sig 333E4E84 2005-07-26 Chathura Kamalanath Herath (Apachecon Europe 2005) +sig 152924AF 2005-07-29 Sander Temme +sig 3 9C85222B 2005-07-24 Henning Schmiedehausen +sig 3 9978AF86 2005-07-25 [User ID not found] +sig 3 2A623F72 2005-07-25 [User ID not found] +sig 3 F8EA2967 2005-07-26 [User ID not found] +sig 3 C152431A 2005-07-27 Steve Loughran +sig DE885DD3 2005-11-25 Sander Striker +sig CE419C8F 2007-01-05 Upayavira +sig E222DE4F 2007-05-02 Mathias Herberts +sig 911203E4 2007-05-02 [User ID not found] +sig F12F6072 2007-05-05 [User ID not found] +sig 3 990ED4AA 2007-05-02 Knut Anders Hatlen +sig 3 311A3DE5 2007-05-05 Ruediger Pluem +sig 3 88817402 2007-05-06 Thomas Vandahl +sig 5F298824 2007-05-06 Simon Pepping +sig 4CEED75F 2007-05-06 Nick Burch +sig 4358C584 2007-05-06 Vincent Hennebert +sig 0B7E6CFA 2007-05-06 Sami Siren +sig 3 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) +sig 40581837 2007-05-08 Nick Kew +uid Stefan Bodewig +sig 3 5F6B8B72 2003-03-07 Stefan Bodewig +sig 3 F88341D9 2003-03-17 Lars Eilebrecht +sig 3 2261D073 2003-03-17 Astrid Kessler (Kess) +sig 21D0A71B 2003-03-17 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 75A67692 2003-03-18 Erik Abele +sig B3B2A12C 2003-05-20 ct magazine CERTIFICATE +sig 3 8103A37E 2003-04-04 Andre Malo +sig 51898504 2005-06-21 Conor MacNeill +sig 0CAA68B4 2004-11-11 Patrick Rentsch +sig 2FE28BCF 2005-07-01 Harald Wilhelm (HAWI) +sig 5793498F 2005-07-21 Tim Ellison +sig 8408F755 2005-07-21 Christian Geisert +sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 3 EE65E321 2005-07-20 Martin Kraemer +sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size +sig 3 3642CB4B 2005-07-20 Martin Kraemer +sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) +sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size +sig 3 CC78C893 2005-07-22 Rich Bowen +sig 3 E2D774DF 2005-07-22 Sylvain Wallez +sig 3 E04F9A89 2005-07-22 Roy T. Fielding +sig 3 87315C31 2005-07-23 Raphal Luta +sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler +sig 3 F39B3750 2005-07-24 Colm MacCarthaigh +sig 1CD4861F 2005-07-25 Eran Chinthaka +sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) +sig 333E4E84 2005-07-26 Chathura Kamalanath Herath (Apachecon Europe 2005) +sig 152924AF 2005-07-29 Sander Temme +sig 3 9C85222B 2005-07-24 Henning Schmiedehausen +sig 3 9978AF86 2005-07-25 [User ID not found] +sig 3 2A623F72 2005-07-25 [User ID not found] +sig 3 F8EA2967 2005-07-26 [User ID not found] +sig 3 C152431A 2005-07-27 Steve Loughran +sig DE885DD3 2005-11-25 Sander Striker +sig E222DE4F 2007-05-02 Mathias Herberts +sig 911203E4 2007-05-02 [User ID not found] +sig F12F6072 2007-05-05 [User ID not found] +sig 3 990ED4AA 2007-05-02 Knut Anders Hatlen +sig 3 311A3DE5 2007-05-05 Ruediger Pluem +sig 3 88817402 2007-05-06 Thomas Vandahl +sig 4CEED75F 2007-05-06 Nick Burch +sig 4358C584 2007-05-06 Vincent Hennebert +sig 0B7E6CFA 2007-05-06 Sami Siren +sig 3 DE8884A0 2007-05-07 Xavier Hanin +sig 3 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) +sig 40581837 2007-05-08 Nick Kew +uid Stefan Bodewig +sig 3 5F6B8B72 2005-05-31 Stefan Bodewig +sig 51898504 2005-06-21 Conor MacNeill +sig 2FE28BCF 2005-07-01 Harald Wilhelm (HAWI) +sig 5793498F 2005-07-21 Tim Ellison +sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 3 EE65E321 2005-07-20 Martin Kraemer +sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size +sig 3 21D0A71B 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 3 3642CB4B 2005-07-20 Martin Kraemer +sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) +sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size +sig 3 CC78C893 2005-07-22 Rich Bowen +sig 3 E2D774DF 2005-07-22 Sylvain Wallez +sig 3 E04F9A89 2005-07-22 Roy T. Fielding +sig 3 87315C31 2005-07-23 Raphal Luta +sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler +sig 3 F39B3750 2005-07-24 Colm MacCarthaigh +sig 1CD4861F 2005-07-25 Eran Chinthaka +sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) +sig 333E4E84 2005-07-26 Chathura Kamalanath Herath (Apachecon Europe 2005) +sig 152924AF 2005-07-29 Sander Temme +sig 3 9C85222B 2005-07-24 Henning Schmiedehausen +sig 3 9978AF86 2005-07-25 [User ID not found] +sig 3 2A623F72 2005-07-25 [User ID not found] +sig 3 F8EA2967 2005-07-26 [User ID not found] +sig 3 C152431A 2005-07-27 Steve Loughran +sig DE885DD3 2005-11-25 Sander Striker +sig E222DE4F 2007-05-02 Mathias Herberts +sig 911203E4 2007-05-02 [User ID not found] +sig F12F6072 2007-05-05 [User ID not found] +sig 3 990ED4AA 2007-05-02 Knut Anders Hatlen +sig 3 311A3DE5 2007-05-05 Ruediger Pluem +sig 3 88817402 2007-05-06 Thomas Vandahl +sig 4CEED75F 2007-05-06 Nick Burch +sig 4358C584 2007-05-06 Vincent Hennebert +sig 0B7E6CFA 2007-05-06 Sami Siren +sig 3 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) +sig 40581837 2007-05-08 Nick Kew +sub 1024g/24774157 2001-05-28 +sig 5F6B8B72 2001-05-28 Stefan Bodewig + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.2 (GNU/Linux) + +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 +b0zPjKjGuiwdKSnkFbNcFS3g +=UxMc +-----END PGP PUBLIC KEY BLOCK----- diff --git a/KEYS.txt b/KEYS.txt deleted file mode 100644 index d4180a29..00000000 --- a/KEYS.txt +++ /dev/null @@ -1,54 +0,0 @@ -This file contains the PGP keys of various Apache developers. -These keys are primarily used for code signing. - -These keys can be verified using any OpenPGP compatible system, -for example, http://www.gnupg.org. - -Developers: To add key information use: - gpg --list-keys UID - gpg --export -a UID - -(Where UID is your email address) - - -User: To import this key file into your keyring use: - gpg --import KEYS.txt - - - - - -pub 1024D/914A4D28 2005-03-07 -uid Nicko Cadell -sub 2048g/6923CBDA 2005-03-07 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.0 (MingW32) - -mQGiBEIsjHURBAC9JqRzMEh6pEZuuyqHGwfBkQZnvOuj0Yp88lDsJtNl62cRaQJk -7eP+kVxCbl12qr1EDz1z/ZON7/+vF9YoiRh7Cydck6wLe/kQcJtUevm00q35pUQJ -7c2TSY+QbTKWriUKueOyRR6p2lpscUHhbCPB9NOLfQmJvZsa47gDZSybCwCgh0+u -8KkkcovlV55K/WrSGg16o8kEAKFGmpDKDnv0Sg1rRnvBGJv5WZFR/57p1SArMXHi -oBkj71wlWz9Ia4tonfc12TXUwoVs3WbIFOoLz1Iw31cGnwUsNkvEclaZigG9iYhx -S6+2i7jrQIivO5iXJtTuePb4zFgLwZcaoFySvLIKRm8+X6KXvoslKAYM/F/Yd0jm -OebkA/4uwIt7cGOWGIaiH2n/80QgXN6FyOhNsgCihZZcPwXo7c/gtszpJ74CwtXD -SVghIwTQ0zK4wtWcHSjf7FelPmeDSga7dLgnxQmmhjIK+sBnPIcBrNiUc3jFnRzK -o3ZIBPsGoo0jUsemgkiQA4ptVybeak/SmrTsRgxWkT4Paw41zrQfTmlja28gQ2Fk -ZWxsIDxuaWNrb0BhcGFjaGUub3JnPoheBBMRAgAeBQJCLIx1AhsDBgsJCAcDAgMV -AgMDFgIBAh4BAheAAAoJEA3R7CqRSk0ooTIAnRZ+vUY+ZN8CgL0fvDbZv76kgQG+ -AJ9vp4BwPLU5jM+YOY3hJPp1bNw1RLkCDQRCLIx/EAgArSrXU4kkXNLCTBIAMaIx -diiVvQ2JqzrFkXf4yAlE+xiy19bqGewmslt+dLmLUEtt1UFMU5b2kAiZLNMvdBWQ -OStwK0SABRESjb5sAjAcFXUeqBzjVBDvsSGxJZZa5He1pQMjFzm4hG6GNl3+vOx6 -r6fly9W5Ddc8wqfDb8JU0c6gG8s10D4gthWWyJ2K1u3BcvpggoGyqyxisvF/QM68 -KnXf8/wp+5sOfl6glyluR/OyGMCU3c38eHYU2XMzlcT3fh1VcU5MvPastp+76vUy -ImrAfb7RhS3sDrmRd9ZS8FE5JRB3967hETRSLjHW+/TZeyvxaGMJkBPdv2BdwnD8 -6wADBQf+NaK8teolegPc1LdmX3bAhR2bhfqIpuUwPBRHqIU2OtWsMJ9sEsVZY4LC -OLOHMHI1spWHEo39mx3fz5MR4x2z3+HzZRq8tzMFn5PC3c7yb06CMfqRf8pvYWVP -0cMvEctViAc+xwSpZgXQGLkwZ37KtqWncfBVocxQMj4CVUx3PeyozWGEG+bpGSso -Mrvnch41AGL3NA9bA2cgTVuOYSXZLK9TOgh4gXCM4jWTI4BqTY5w0riDwqwt5+qH -e8/HBowGa4jNopl9kWaQuEoXH7GGOTJsc9eKMK+k++iqSWiqVXFTLd7/UhUPv6Oj -7Pqm7+oSumphn00rC2DVeAAWDt7umohJBBgRAgAJBQJCLIx/AhsMAAoJEA3R7CqR -Sk0ouF4An1sFuJ+/kJlvKRs+nNjFqrQdsuDCAJ9WDNgUqnAkdLVTRJq8UeK0AjOq -oQ== -=4aNz ------END PGP PUBLIC KEY BLOCK----- From 96eac7a5951b2bf705f0c9ba1aeeabfe312fa339 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 13:00:01 +0000 Subject: [PATCH 061/370] Add pointer to source of KEYS file git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169724 13f79535-47bb-0310-9956-ffa450edef68 --- KEYS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/KEYS b/KEYS index 58130c5f..f3be6ce7 100644 --- a/KEYS +++ b/KEYS @@ -10,6 +10,8 @@ Developers: To add key information use: (Where UID is your email address) +The original source of this file is +https://svn.apache.org/repos/asf/logging/log4net/trunk/KEYS User: To import this key file into your keyring use: gpg --import KEYS.txt From dd30f05133673bcc7eee1545707c36c0a98457f8 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 13:04:14 +0000 Subject: [PATCH 062/370] adapt to changed file name git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169726 13f79535-47bb-0310-9956-ffa450edef68 --- KEYS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KEYS b/KEYS index f3be6ce7..d8de1236 100644 --- a/KEYS +++ b/KEYS @@ -14,7 +14,7 @@ The original source of this file is https://svn.apache.org/repos/asf/logging/log4net/trunk/KEYS User: To import this key file into your keyring use: - gpg --import KEYS.txt + gpg --import KEYS From dc3ab547c88c2be5eeaa7006535af958eb4208ec Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 12 Sep 2011 14:57:12 +0000 Subject: [PATCH 063/370] Fix race-condition in XmlLayoutBase. LOG4NET-76 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1169783 13f79535-47bb-0310-9956-ffa450edef68 --- src/Layout/XMLLayoutBase.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/Layout/XMLLayoutBase.cs b/src/Layout/XMLLayoutBase.cs index 4a5cebcf..2ec0e8c9 100644 --- a/src/Layout/XMLLayoutBase.cs +++ b/src/Layout/XMLLayoutBase.cs @@ -197,10 +197,7 @@ override public void Format(TextWriter writer, LoggingEvent loggingEvent) throw new ArgumentNullException("loggingEvent"); } - // Attach the protected writer to the TextWriter passed in - m_protectCloseTextWriter.Attach(writer); - - XmlTextWriter xmlWriter = new XmlTextWriter(m_protectCloseTextWriter); + XmlTextWriter xmlWriter = new XmlTextWriter(new ProtectCloseTextWriter(writer)); xmlWriter.Formatting = Formatting.None; xmlWriter.Namespaces = false; @@ -212,9 +209,6 @@ override public void Format(TextWriter writer, LoggingEvent loggingEvent) // Close on xmlWriter will ensure xml is flushed // the protected writer will ignore the actual close xmlWriter.Close(); - - // detach from the writer - m_protectCloseTextWriter.Attach(null); } #endregion Override implementation of LayoutSkeleton @@ -244,11 +238,6 @@ override public void Format(TextWriter writer, LoggingEvent loggingEvent) /// private bool m_locationInfo = false; - /// - /// Writer adapter that ignores Close - /// - private readonly ProtectCloseTextWriter m_protectCloseTextWriter = new ProtectCloseTextWriter(null); - /// /// The string to replace invalid chars with /// From 73e066a1619824d648d1a0cc2fce3454f55f407c Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 13 Sep 2011 10:14:42 +0000 Subject: [PATCH 064/370] fix bounds-checks in NamedPatternConverter. LOG4NET-215 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1170104 13f79535-47bb-0310-9956-ffa450edef68 --- src/Layout/Pattern/NamedPatternConverter.cs | 43 +++--- tests/src/Layout/PatternLayoutTest.cs | 156 +++++++++++++++++++- 2 files changed, 177 insertions(+), 22 deletions(-) diff --git a/src/Layout/Pattern/NamedPatternConverter.cs b/src/Layout/Pattern/NamedPatternConverter.cs index 9d973261..8338706e 100644 --- a/src/Layout/Pattern/NamedPatternConverter.cs +++ b/src/Layout/Pattern/NamedPatternConverter.cs @@ -42,9 +42,9 @@ namespace log4net.Layout.Pattern /// /// /// Nicko Cadell - internal abstract class NamedPatternConverter : PatternLayoutConverter, IOptionHandler + public abstract class NamedPatternConverter : PatternLayoutConverter, IOptionHandler { - protected int m_precision = 0; + private int m_precision = 0; #region Implementation of IOptionHandler @@ -120,31 +120,37 @@ public void ActivateOptions() /// Render the to the precision /// specified by the property. /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) + sealed override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) { string name = GetFullyQualifiedName(loggingEvent); - if (m_precision <= 0) + if (m_precision <= 0 || name == null || name.Length < 2) { writer.Write(name); } else { int len = name.Length; + string trailingDot = string.Empty; + if (name.EndsWith(DOT)) + { + trailingDot = DOT; + name = name.Substring(0, len - 1); + len--; + } - // We subtract 1 from 'len' when assigning to 'end' to avoid out of - // bounds exception in return name.Substring(end+1, len). This can happen if - // precision is 1 and the logger name ends with a dot. - int end = len - 1; - for(int i=m_precision; i>0; i--) - { - end = name.LastIndexOf('.', end-1); - if (end == -1) - { - writer.Write(name); - return; - } - } - writer.Write(name.Substring(end+1, len-end-1)); + int end = name.LastIndexOf(DOT); + for(int i = 1; end > 0 && i < m_precision; i++) + { + end = name.LastIndexOf('.', end - 1); + } + if (end == -1) + { + writer.Write(name + trailingDot); + } + else + { + writer.Write(name.Substring(end + 1, len - end - 1) + trailingDot); + } } } @@ -159,6 +165,7 @@ override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) /// private readonly static Type declaringType = typeof(NamedPatternConverter); + private const string DOT = "."; #endregion Private Static Fields } } diff --git a/tests/src/Layout/PatternLayoutTest.cs b/tests/src/Layout/PatternLayoutTest.cs index dd3606c2..fcba7eab 100644 --- a/tests/src/Layout/PatternLayoutTest.cs +++ b/tests/src/Layout/PatternLayoutTest.cs @@ -33,10 +33,10 @@ namespace log4net.Tests.Layout { /// - /// Used for internal unit testing the class. + /// Used for internal unit testing the class. /// /// - /// Used for internal unit testing the class. + /// Used for internal unit testing the class. /// [TestFixture] public class PatternLayoutTest @@ -145,7 +145,147 @@ public void TestAddingCustomPattern() stringAppender.Reset(); } - /// + [Test] + public void NamedPatternConverterWithoutPrecisionShouldReturnFullName() + { + StringAppender stringAppender = new StringAppender(); + PatternLayout layout = new PatternLayout(); + layout.AddConverter("message-as-name", typeof(MessageAsNamePatternConverter)); + layout.ConversionPattern = "%message-as-name"; + layout.ActivateOptions(); + stringAppender.Layout = layout; + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern"); + + log1.Info("NoDots"); + Assert.AreEqual("NoDots", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("One.Dot"); + Assert.AreEqual("One.Dot", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("Tw.o.Dots"); + Assert.AreEqual("Tw.o.Dots", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("TrailingDot."); + Assert.AreEqual("TrailingDot.", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info(".LeadingDot"); + Assert.AreEqual(".LeadingDot", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + // empty string and other evil combinations as tests for of-by-one mistakes in index calculations + log1.Info(string.Empty); + Assert.AreEqual(string.Empty, stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("."); + Assert.AreEqual(".", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("x"); + Assert.AreEqual("x", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + } + + [Test] + public void NamedPatternConverterWithPrecision1ShouldStripLeadingStuffIfPresent() + { + StringAppender stringAppender = new StringAppender(); + PatternLayout layout = new PatternLayout(); + layout.AddConverter("message-as-name", typeof(MessageAsNamePatternConverter)); + layout.ConversionPattern = "%message-as-name{1}"; + layout.ActivateOptions(); + stringAppender.Layout = layout; + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern"); + + log1.Info("NoDots"); + Assert.AreEqual("NoDots", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("One.Dot"); + Assert.AreEqual("Dot", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("Tw.o.Dots"); + Assert.AreEqual("Dots", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("TrailingDot."); + Assert.AreEqual("TrailingDot.", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info(".LeadingDot"); + Assert.AreEqual("LeadingDot", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + // empty string and other evil combinations as tests for of-by-one mistakes in index calculations + log1.Info(string.Empty); + Assert.AreEqual(string.Empty, stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("x"); + Assert.AreEqual("x", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("."); + Assert.AreEqual(".", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + } + + [Test] + public void NamedPatternConverterWithPrecision2ShouldStripLessLeadingStuffIfPresent() { + StringAppender stringAppender = new StringAppender(); + PatternLayout layout = new PatternLayout(); + layout.AddConverter("message-as-name", typeof(MessageAsNamePatternConverter)); + layout.ConversionPattern = "%message-as-name{2}"; + layout.ActivateOptions(); + stringAppender.Layout = layout; + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + BasicConfigurator.Configure(rep, stringAppender); + ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern"); + + log1.Info("NoDots"); + Assert.AreEqual("NoDots", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("One.Dot"); + Assert.AreEqual("One.Dot", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("Tw.o.Dots"); + Assert.AreEqual("o.Dots", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("TrailingDot."); + Assert.AreEqual("TrailingDot.", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info(".LeadingDot"); + Assert.AreEqual("LeadingDot", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + // empty string and other evil combinations as tests for of-by-one mistakes in index calculations + log1.Info(string.Empty); + Assert.AreEqual(string.Empty, stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("x"); + Assert.AreEqual("x", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + + log1.Info("."); + Assert.AreEqual(".", stringAppender.GetString(), "%message-as-name not registered"); + stringAppender.Reset(); + } + + /// /// Converter to include event message /// private class TestMessagePatternConverter : PatternLayoutConverter @@ -181,5 +321,13 @@ public void TestExceptionPattern() stringAppender.Reset(); } - } + + private class MessageAsNamePatternConverter : NamedPatternConverter + { + protected override string GetFullyQualifiedName(LoggingEvent loggingEvent) + { + return loggingEvent.MessageObject.ToString(); + } + } + } } \ No newline at end of file From ded329f44bc69e4f15c2a1bd27e7ed6f74e2bd9a Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 13 Sep 2011 14:26:48 +0000 Subject: [PATCH 065/370] revert unintended whitespace change git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1170192 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/EventLogAppender.cs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs index 1c384074..892d9864 100644 --- a/src/Appender/EventLogAppender.cs +++ b/src/Appender/EventLogAppender.cs @@ -275,34 +275,41 @@ public short Category /// override public void ActivateOptions() { - try { + try + { base.ActivateOptions(); - if (m_securityContext == null) { + if (m_securityContext == null) + { m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); } bool sourceAlreadyExists = false; string currentLogName = null; - using (SecurityContext.Impersonate(this)) { + using (SecurityContext.Impersonate(this)) + { sourceAlreadyExists = EventLog.SourceExists(m_applicationName); if (sourceAlreadyExists) { currentLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); } } - if (sourceAlreadyExists && currentLogName != m_logName) { + if (sourceAlreadyExists && currentLogName != m_logName) + { LogLog.Debug(declaringType, "Changing event source [" + m_applicationName + "] from log [" + currentLogName + "] to log [" + m_logName + "]"); } - else if (!sourceAlreadyExists) { + else if (!sourceAlreadyExists) + { LogLog.Debug(declaringType, "Creating event source Source [" + m_applicationName + "] in log " + m_logName + "]"); } string registeredLogName = null; - using (SecurityContext.Impersonate(this)) { - if (sourceAlreadyExists && currentLogName != m_logName) { + using (SecurityContext.Impersonate(this)) + { + if (sourceAlreadyExists && currentLogName != m_logName) + { // // Re-register this to the current application if the user has changed // the application / logfile association @@ -312,7 +319,8 @@ override public void ActivateOptions() registeredLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); } - else if (!sourceAlreadyExists) { + else if (!sourceAlreadyExists) + { CreateEventSource(m_applicationName, m_logName, m_machineName); registeredLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); @@ -323,7 +331,8 @@ override public void ActivateOptions() LogLog.Debug(declaringType, "Source [" + m_applicationName + "] is registered to log [" + registeredLogName + "]"); } - catch (System.Security.SecurityException ex) { + catch (System.Security.SecurityException ex) + { ErrorHandler.Error("Caught a SecurityException trying to access the EventLog. Most likely the event source " + m_applicationName + " doesn't exist and must be created by a local administrator. Will disable EventLogAppender." From dfb6283b31d3cb24e1a671a3b6d0c33d7abe03b5 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 13 Sep 2011 15:14:30 +0000 Subject: [PATCH 066/370] exclude generated files and files expected to be without license from RAT report git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1170206 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pom.xml b/pom.xml index 0fd76c18..b0f86584 100644 --- a/pom.xml +++ b/pom.xml @@ -149,6 +149,22 @@ org.apache.rat apache-rat-plugin 0.7 + + + + bin/** + tests/bin/** + build/** + src/log4net.xml + **/obj/** + **/*.user + **/*.suo + + + *.snk.* + tests/lib/prerequisites.txt + + From d5f8eaed4bfa436e2acda7a4ad965282dc789483 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 14 Sep 2011 03:55:04 +0000 Subject: [PATCH 067/370] EventLogAppender doesn't throw a SecurityException on Linux git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1170428 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Appender/EventLogAppenderTest.cs | 2 +- tests/src/Appender/RollingFileAppenderTest.cs | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/src/Appender/EventLogAppenderTest.cs b/tests/src/Appender/EventLogAppenderTest.cs index 4d706664..7c424089 100644 --- a/tests/src/Appender/EventLogAppenderTest.cs +++ b/tests/src/Appender/EventLogAppenderTest.cs @@ -79,7 +79,7 @@ public void TestGetEntryTypeForExistingApplicationName() /// ActivateOption tries to create an event source if it doesn't exist but this is going to fail on more modern Windows versions unless the code is run with local administrator privileges. /// [Test] - [Platform(Exclude = "Win2K,WinXP")] + [Platform(Exclude = "Win2K,WinXP", Include="Win")] public void ActivateOptionsDisablesAppenderIfSourceDoesntExist() { EventLogAppender eventAppender = new EventLogAppender(); diff --git a/tests/src/Appender/RollingFileAppenderTest.cs b/tests/src/Appender/RollingFileAppenderTest.cs index 13338062..62af0c3a 100644 --- a/tests/src/Appender/RollingFileAppenderTest.cs +++ b/tests/src/Appender/RollingFileAppenderTest.cs @@ -62,17 +62,17 @@ public string Message public void Error(string message) { - m_buffer.Append(message + "\n"); + m_buffer.Append(message + Environment.NewLine); } public void Error(string message, Exception e) { - m_buffer.Append(message + "\n" + e.Message + "\n"); + m_buffer.Append(message + Environment.NewLine + e.Message + Environment.NewLine); } public void Error(string message, Exception e, ErrorCode errorCode) { - m_buffer.Append(message + "\n" + e.Message + "\n"); + m_buffer.Append(message + Environment.NewLine + e.Message + Environment.NewLine); } } @@ -498,16 +498,17 @@ private void RollFromTableEntries(string sBaseFileName, RollConditions[] entries } } + static readonly int s_LengthNL = Environment.NewLine.Length; + /// /// Returns the number of bytes logged per message, including - /// any CR/LF characters in addition to the message length. + /// any newline characters in addition to the message length. /// /// /// private static int TotalMessageLength(string sMessage) { - const int iLengthCRLF = 2; - return sMessage.Length + iLengthCRLF; + return sMessage.Length + s_LengthNL; } /// @@ -655,7 +656,7 @@ public int MaximumFileSize } /// - /// The length of a message, including any CR/LF characters. + /// The length of a message, including any newline characters. /// This length assumes all messages are a fixed length for /// test purposes. /// From 64a15f23ad5fb02785a4d41686b1f8ad8817d123 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 14 Sep 2011 03:59:40 +0000 Subject: [PATCH 068/370] committed work in progress by accident git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1170429 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Appender/RollingFileAppenderTest.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/src/Appender/RollingFileAppenderTest.cs b/tests/src/Appender/RollingFileAppenderTest.cs index 62af0c3a..13338062 100644 --- a/tests/src/Appender/RollingFileAppenderTest.cs +++ b/tests/src/Appender/RollingFileAppenderTest.cs @@ -62,17 +62,17 @@ public string Message public void Error(string message) { - m_buffer.Append(message + Environment.NewLine); + m_buffer.Append(message + "\n"); } public void Error(string message, Exception e) { - m_buffer.Append(message + Environment.NewLine + e.Message + Environment.NewLine); + m_buffer.Append(message + "\n" + e.Message + "\n"); } public void Error(string message, Exception e, ErrorCode errorCode) { - m_buffer.Append(message + Environment.NewLine + e.Message + Environment.NewLine); + m_buffer.Append(message + "\n" + e.Message + "\n"); } } @@ -498,17 +498,16 @@ private void RollFromTableEntries(string sBaseFileName, RollConditions[] entries } } - static readonly int s_LengthNL = Environment.NewLine.Length; - /// /// Returns the number of bytes logged per message, including - /// any newline characters in addition to the message length. + /// any CR/LF characters in addition to the message length. /// /// /// private static int TotalMessageLength(string sMessage) { - return sMessage.Length + s_LengthNL; + const int iLengthCRLF = 2; + return sMessage.Length + iLengthCRLF; } /// @@ -656,7 +655,7 @@ public int MaximumFileSize } /// - /// The length of a message, including any newline characters. + /// The length of a message, including any CR/LF characters. /// This length assumes all messages are a fixed length for /// test purposes. /// From 8fedc1a07437e0710c5d3c8c37b9553ae6fcfe4c Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 14 Sep 2011 09:11:49 +0000 Subject: [PATCH 069/370] explicitly set encoding to ASCII to avoid file name length mismatch because of BOMs git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1170486 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Appender/RollingFileAppenderTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/src/Appender/RollingFileAppenderTest.cs b/tests/src/Appender/RollingFileAppenderTest.cs index 13338062..faa6b4fe 100644 --- a/tests/src/Appender/RollingFileAppenderTest.cs +++ b/tests/src/Appender/RollingFileAppenderTest.cs @@ -251,6 +251,7 @@ private RollingFileAppender CreateAppender(FileAppender.LockingModelBase lockMod RollingFileAppender appender = new RollingFileAppender(); appender.Layout = layout; appender.File = c_fileName; + appender.Encoding = Encoding.ASCII; appender.MaximumFileSize = c_iMaximumFileSize.ToString(); appender.MaxSizeRollBackups = _MaxSizeRollBackups; appender.CountDirection = _iCountDirection; From bc97978d90e3b442213a752eb6b5a295b4ecb05f Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 14 Sep 2011 09:17:30 +0000 Subject: [PATCH 070/370] %newline is platform dependent git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1170489 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Appender/RollingFileAppenderTest.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/src/Appender/RollingFileAppenderTest.cs b/tests/src/Appender/RollingFileAppenderTest.cs index faa6b4fe..d767a74d 100644 --- a/tests/src/Appender/RollingFileAppenderTest.cs +++ b/tests/src/Appender/RollingFileAppenderTest.cs @@ -499,16 +499,17 @@ private void RollFromTableEntries(string sBaseFileName, RollConditions[] entries } } + private static readonly int s_Newline_Length = Environment.NewLine.Length; + /// /// Returns the number of bytes logged per message, including - /// any CR/LF characters in addition to the message length. + /// any newline characters in addition to the message length. /// /// /// private static int TotalMessageLength(string sMessage) { - const int iLengthCRLF = 2; - return sMessage.Length + iLengthCRLF; + return sMessage.Length + s_Newline_Length; } /// From 94f13abb3fce131e4080b07dda5445124eec5515 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 14 Sep 2011 09:28:27 +0000 Subject: [PATCH 071/370] At least for Mono on Linux Type.GetType is always case sensitive on assembly names. The caseInsensitive flag only seems to apply to the type name. git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1170497 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Util/SystemInfoTest.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/src/Util/SystemInfoTest.cs b/tests/src/Util/SystemInfoTest.cs index 84fa36fd..9400d41d 100644 --- a/tests/src/Util/SystemInfoTest.cs +++ b/tests/src/Util/SystemInfoTest.cs @@ -39,6 +39,18 @@ public void TestGetTypeFromStringFullyQualified() t = SystemInfo.GetTypeFromString("log4net.Tests.Util.SystemInfoTest,log4net.Tests", false, false); Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case sensitive type load"); + t = SystemInfo.GetTypeFromString("LOG4NET.TESTS.UTIL.SYSTEMINFOTEST,log4net.Tests", false, true); + Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case in-sensitive type load caps"); + + t = SystemInfo.GetTypeFromString("log4net.tests.util.systeminfotest,log4net.Tests", false, true); + Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case in-sensitive type load lower"); + } + + [Test][Platform(Include="Win")] + public void TestGetTypeFromStringCaseInsensitiveOnAssemblyName() + { + Type t; + t = SystemInfo.GetTypeFromString("LOG4NET.TESTS.UTIL.SYSTEMINFOTEST,LOG4NET.TESTS", false, true); Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case in-sensitive type load caps"); From f1e842a8e8facf01f1a4e7fc1e26d6756f5a7f7d Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 09:35:33 +0000 Subject: [PATCH 072/370] File.GetLastWriteTimeUtc is .NET 1.1+ git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171473 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/RollingFileAppender.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs index 830982fc..5844be2d 100644 --- a/src/Appender/RollingFileAppender.cs +++ b/src/Appender/RollingFileAppender.cs @@ -242,7 +242,7 @@ public RollingFileAppender() /// /// Gets or sets the strategy for determining the current date and time. The default /// implementation is to use LocalDateTime which internally calls through to DateTime.Now. - /// DateTime.UtcNow may be used by specifying + /// DateTime.UtcNow may be used on frameworks newer than .NET 1.0 by specifying /// . /// /// @@ -778,15 +778,19 @@ private void RollOverIfDateBoundaryCrossing() DateTime last; using(SecurityContext.Impersonate(this)) { +#if !NET_1_0 if (DateTimeStrategy is UniversalDateTime) { last = System.IO.File.GetLastWriteTimeUtc(m_baseFileName); } else { +#endif last = System.IO.File.GetLastWriteTime(m_baseFileName); +#if !NET_1_0 } - } +#endif + } LogLog.Debug(declaringType, "["+last.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo)+"] vs. ["+m_now.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo)+"]"); if (!(last.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo).Equals(m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo)))) @@ -1674,6 +1678,7 @@ public DateTime Now } } +#if !NET_1_0 /// /// Implementation of that returns the current time as the coordinated universal time (UTC). /// @@ -1693,7 +1698,8 @@ public DateTime Now get { return DateTime.UtcNow; } } } +#endif - #endregion DateTime + #endregion DateTime } } From d43c152948e66b57d2a578e95cb8e3e9d2d75d83 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 09:37:47 +0000 Subject: [PATCH 073/370] comment out crefs to UniversalDateTime for .NET 1.0 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171474 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/RollingFileAppender.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs index 5844be2d..2d89c8ac 100644 --- a/src/Appender/RollingFileAppender.cs +++ b/src/Appender/RollingFileAppender.cs @@ -242,8 +242,10 @@ public RollingFileAppender() /// /// Gets or sets the strategy for determining the current date and time. The default /// implementation is to use LocalDateTime which internally calls through to DateTime.Now. +#if !NET_1_0 /// DateTime.UtcNow may be used on frameworks newer than .NET 1.0 by specifying /// . +#endif /// /// /// An implementation of the interface which returns the current date and time. @@ -254,8 +256,11 @@ public RollingFileAppender() /// /// /// There are two built strategies for determining the current date and time, - /// and . - /// + /// +#if !NET_1_0 + /// and . +#endif + /// /// /// The default strategy is . /// From cc4c501355221eacf37d5dace73fa4999717a7c0 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 09:41:32 +0000 Subject: [PATCH 074/370] conditional blocks and XML comments don't mix as I would have expected them to git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171475 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/RollingFileAppender.cs | 30 +++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs index 2d89c8ac..8faba2aa 100644 --- a/src/Appender/RollingFileAppender.cs +++ b/src/Appender/RollingFileAppender.cs @@ -239,13 +239,12 @@ public RollingFileAppender() #region Public Instance Properties - /// +#if !NET_1_0 + /// /// Gets or sets the strategy for determining the current date and time. The default /// implementation is to use LocalDateTime which internally calls through to DateTime.Now. -#if !NET_1_0 /// DateTime.UtcNow may be used on frameworks newer than .NET 1.0 by specifying /// . -#endif /// /// /// An implementation of the interface which returns the current date and time. @@ -254,18 +253,33 @@ public RollingFileAppender() /// /// Gets or sets the used to return the current date and time. /// - /// - /// There are two built strategies for determining the current date and time, + /// + /// There are two built strategies for determining the current date and time, /// -#if !NET_1_0 /// and . -#endif /// + /// + /// The default strategy is . + /// + /// +#else + /// + /// Gets or sets the strategy for determining the current date and time. The default + /// implementation is to use LocalDateTime which internally calls through to DateTime.Now. + /// + /// + /// An implementation of the interface which returns the current date and time. + /// + /// /// + /// Gets or sets the used to return the current date and time. + /// + /// /// The default strategy is . /// /// - public IDateTime DateTimeStrategy +#endif + public IDateTime DateTimeStrategy { get { return m_dateTime; } set { m_dateTime = value; } From 50375cef00caff85785e0a90e3e0fdd75fbe797c Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 09:47:15 +0000 Subject: [PATCH 075/370] .NET 1.0 builds CLI 1.0 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171479 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/RollingFileAppender.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs index 8faba2aa..9b529a47 100644 --- a/src/Appender/RollingFileAppender.cs +++ b/src/Appender/RollingFileAppender.cs @@ -239,7 +239,7 @@ public RollingFileAppender() #region Public Instance Properties -#if !NET_1_0 +#if !NET_1_0 && !CLI_1_0 /// /// Gets or sets the strategy for determining the current date and time. The default /// implementation is to use LocalDateTime which internally calls through to DateTime.Now. @@ -795,10 +795,9 @@ private void RollOverIfDateBoundaryCrossing() if (FileExists(m_baseFileName)) { DateTime last; - using(SecurityContext.Impersonate(this)) - { -#if !NET_1_0 - if (DateTimeStrategy is UniversalDateTime) + using(SecurityContext.Impersonate(this)) { +#if !NET_1_0 && !CLI_1_0 + if (DateTimeStrategy is UniversalDateTime) { last = System.IO.File.GetLastWriteTimeUtc(m_baseFileName); } @@ -806,8 +805,8 @@ private void RollOverIfDateBoundaryCrossing() { #endif last = System.IO.File.GetLastWriteTime(m_baseFileName); -#if !NET_1_0 - } +#if !NET_1_0 && !CLI_1_0 + } #endif } LogLog.Debug(declaringType, "["+last.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo)+"] vs. ["+m_now.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo)+"]"); @@ -1697,8 +1696,8 @@ public DateTime Now } } -#if !NET_1_0 - /// +#if !NET_1_0 && !CLI_1_0 + /// /// Implementation of that returns the current time as the coordinated universal time (UTC). /// private class UniversalDateTime : IDateTime From caed474722846dc01410fc10c4ee518faef6e361 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 13:36:33 +0000 Subject: [PATCH 076/370] There is no StrackFrame type in Compact Framework git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171552 13f79535-47bb-0310-9956-ffa450edef68 --- src/Core/LocationInfo.cs | 2 ++ src/Layout/Pattern/StackTraceDetailPatternConverter.cs | 2 ++ src/Layout/Pattern/StackTracePatternConverter.cs | 3 ++- src/Layout/PatternLayout.cs | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Core/LocationInfo.cs b/src/Core/LocationInfo.cs index 7afc02fc..a43c4c31 100644 --- a/src/Core/LocationInfo.cs +++ b/src/Core/LocationInfo.cs @@ -271,6 +271,7 @@ public string FullInfo get { return m_fullInfo; } } +#if !NETCF /// /// Gets the stack frames from the stack trace of the caller making the log request /// @@ -278,6 +279,7 @@ public StackFrame[] StackFrames { get { return m_stackFrames; } } +#endif #endregion Public Instance Properties diff --git a/src/Layout/Pattern/StackTraceDetailPatternConverter.cs b/src/Layout/Pattern/StackTraceDetailPatternConverter.cs index 0351e3f1..4f60a83d 100644 --- a/src/Layout/Pattern/StackTraceDetailPatternConverter.cs +++ b/src/Layout/Pattern/StackTraceDetailPatternConverter.cs @@ -18,6 +18,7 @@ * under the License. * */ +#if !NETCF using System; using System.Collections; @@ -109,3 +110,4 @@ private string[] GetMethodParameterNames(System.Reflection.MethodBase methodBase #endregion Private Static Fields } } +#endif \ No newline at end of file diff --git a/src/Layout/Pattern/StackTracePatternConverter.cs b/src/Layout/Pattern/StackTracePatternConverter.cs index 1fa83d73..5839e651 100644 --- a/src/Layout/Pattern/StackTracePatternConverter.cs +++ b/src/Layout/Pattern/StackTracePatternConverter.cs @@ -16,7 +16,7 @@ // limitations under the License. // #endregion - +#if !NETCF using System; using System.IO; using System.Diagnostics; @@ -147,3 +147,4 @@ internal virtual string GetMethodInformation(System.Reflection.MethodBase method #endregion Private Static Fields } } +#endif \ No newline at end of file diff --git a/src/Layout/PatternLayout.cs b/src/Layout/PatternLayout.cs index 66ceb387..3741d9c5 100644 --- a/src/Layout/PatternLayout.cs +++ b/src/Layout/PatternLayout.cs @@ -860,8 +860,10 @@ static PatternLayout() s_globalRulesRegistry.Add("r", typeof(RelativeTimePatternConverter)); s_globalRulesRegistry.Add("timestamp", typeof(RelativeTimePatternConverter)); +#if !NETCF s_globalRulesRegistry.Add("stacktrace", typeof(StackTracePatternConverter)); s_globalRulesRegistry.Add("stacktracedetail", typeof(StackTraceDetailPatternConverter)); +#endif s_globalRulesRegistry.Add("t", typeof(ThreadPatternConverter)); s_globalRulesRegistry.Add("thread", typeof(ThreadPatternConverter)); From 9f8d7589e8b92878323de64b3739015b05a21f3d Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 13:37:47 +0000 Subject: [PATCH 077/370] There is no StrackFrame type in Compact Framework, overlooked one reference git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171554 13f79535-47bb-0310-9956-ffa450edef68 --- src/Core/LocationInfo.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Core/LocationInfo.cs b/src/Core/LocationInfo.cs index a43c4c31..e0c4e6a2 100644 --- a/src/Core/LocationInfo.cs +++ b/src/Core/LocationInfo.cs @@ -290,7 +290,9 @@ public StackFrame[] StackFrames private readonly string m_lineNumber; private readonly string m_methodName; private readonly string m_fullInfo; +#if !NETCF private readonly StackFrame[] m_stackFrames; +#endif #endregion Private Instance Fields From 1d8ea7c571728c599a96d77b3c3f8475c112a1b7 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 13:42:09 +0000 Subject: [PATCH 078/370] There is no SecurityPermission type in Compact Framework git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171557 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/OutputDebugStringAppender.cs | 3 ++- src/Util/NativeError.cs | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Appender/OutputDebugStringAppender.cs b/src/Appender/OutputDebugStringAppender.cs index f61dc480..5b44b6e0 100644 --- a/src/Appender/OutputDebugStringAppender.cs +++ b/src/Appender/OutputDebugStringAppender.cs @@ -77,8 +77,9 @@ public OutputDebugStringAppender() /// #if NET_4_0 [System.Security.SecuritySafeCritical] -#endif +#elif !NETFC [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] +#endif override protected void Append(LoggingEvent loggingEvent) { OutputDebugString(RenderLoggingEvent(loggingEvent)); diff --git a/src/Util/NativeError.cs b/src/Util/NativeError.cs index dbb904a9..8f240d19 100644 --- a/src/Util/NativeError.cs +++ b/src/Util/NativeError.cs @@ -116,8 +116,9 @@ public string Message /// #if NET_4_0 [System.Security.SecuritySafeCritical] -#endif +#elif !NETFC [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode=true)] +#endif public static NativeError GetLastError() { int number = Marshal.GetLastWin32Error(); @@ -158,8 +159,9 @@ public static NativeError GetError(int number) /// #if NET_4_0 [System.Security.SecuritySafeCritical] -#endif +#elif !NETFC [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] +#endif public static string GetErrorMessage(int messageId) { // Win32 constants From a8109d1dccdd84ef3736d46a89f64e8ca00817e2 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 13:43:23 +0000 Subject: [PATCH 079/370] typo git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171558 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/OutputDebugStringAppender.cs | 2 +- src/Util/NativeError.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Appender/OutputDebugStringAppender.cs b/src/Appender/OutputDebugStringAppender.cs index 5b44b6e0..326e5d36 100644 --- a/src/Appender/OutputDebugStringAppender.cs +++ b/src/Appender/OutputDebugStringAppender.cs @@ -77,7 +77,7 @@ public OutputDebugStringAppender() /// #if NET_4_0 [System.Security.SecuritySafeCritical] -#elif !NETFC +#elif !NETCF [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] #endif override protected void Append(LoggingEvent loggingEvent) diff --git a/src/Util/NativeError.cs b/src/Util/NativeError.cs index 8f240d19..3c9d51af 100644 --- a/src/Util/NativeError.cs +++ b/src/Util/NativeError.cs @@ -116,7 +116,7 @@ public string Message /// #if NET_4_0 [System.Security.SecuritySafeCritical] -#elif !NETFC +#elif !NETCF [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode=true)] #endif public static NativeError GetLastError() @@ -159,7 +159,7 @@ public static NativeError GetError(int number) /// #if NET_4_0 [System.Security.SecuritySafeCritical] -#elif !NETFC +#elif !NETCF [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] #endif public static string GetErrorMessage(int messageId) From d6d7d303704222a5e624576570a2fc13eac89f18 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 13:45:32 +0000 Subject: [PATCH 080/370] Compact framework doesn't have GetlastWriteTimeUtc either git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171559 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/RollingFileAppender.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs index 9b529a47..48ad5ff2 100644 --- a/src/Appender/RollingFileAppender.cs +++ b/src/Appender/RollingFileAppender.cs @@ -239,7 +239,7 @@ public RollingFileAppender() #region Public Instance Properties -#if !NET_1_0 && !CLI_1_0 +#if !NET_1_0 && !CLI_1_0 && !NETCF /// /// Gets or sets the strategy for determining the current date and time. The default /// implementation is to use LocalDateTime which internally calls through to DateTime.Now. @@ -796,7 +796,7 @@ private void RollOverIfDateBoundaryCrossing() { DateTime last; using(SecurityContext.Impersonate(this)) { -#if !NET_1_0 && !CLI_1_0 +#if !NET_1_0 && !CLI_1_0 && !NETCF if (DateTimeStrategy is UniversalDateTime) { last = System.IO.File.GetLastWriteTimeUtc(m_baseFileName); @@ -805,7 +805,7 @@ private void RollOverIfDateBoundaryCrossing() { #endif last = System.IO.File.GetLastWriteTime(m_baseFileName); -#if !NET_1_0 && !CLI_1_0 +#if !NET_1_0 && !CLI_1_0 && !NETCF } #endif } @@ -1696,7 +1696,7 @@ public DateTime Now } } -#if !NET_1_0 && !CLI_1_0 +#if !NET_1_0 && !CLI_1_0 && !NETCF /// /// Implementation of that returns the current time as the coordinated universal time (UTC). /// From 3ad20afaab984d6cda2e051ef30b75a93c4391b5 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 16 Sep 2011 13:54:56 +0000 Subject: [PATCH 081/370] No named Mutex in Compact Framework git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171564 13f79535-47bb-0310-9956-ffa450edef68 --- src/Appender/FileAppender.cs | 2 ++ tests/src/Appender/RollingFileAppenderTest.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Appender/FileAppender.cs b/src/Appender/FileAppender.cs index ff5993d4..fd96a5ee 100644 --- a/src/Appender/FileAppender.cs +++ b/src/Appender/FileAppender.cs @@ -583,6 +583,7 @@ public override void ReleaseLock() } } +#if !NETCF /// /// Provides cross-process file locking. /// @@ -686,6 +687,7 @@ public override void ReleaseLock() } } } +#endif #endregion Locking Models diff --git a/tests/src/Appender/RollingFileAppenderTest.cs b/tests/src/Appender/RollingFileAppenderTest.cs index d767a74d..5ff7166c 100644 --- a/tests/src/Appender/RollingFileAppenderTest.cs +++ b/tests/src/Appender/RollingFileAppenderTest.cs @@ -1605,6 +1605,7 @@ public void TestMinimalLockUnlocks() Assert.AreEqual("", sh.Message, "Unexpected error message"); } +#if !NETCF /// /// Verifies that attempting to log to a locked file fails gracefully /// @@ -1671,6 +1672,7 @@ public void TestMutexLockUnlocks() { AssertFileEquals(filename, "This is a message" + Environment.NewLine + "Test" + Environment.NewLine + "This is a message 2" + Environment.NewLine); Assert.AreEqual("", sh.Message, "Unexpected error message"); } +#endif /// /// Verify that the default LockModel is ExclusiveLock, to maintain backwards compatibility with previous behaviour From 275c1c3453913c19ba696a21972021d5bf7bcc0f Mon Sep 17 00:00:00 2001 From: Curtis William Arnold Date: Sat, 17 Sep 2011 03:25:25 +0000 Subject: [PATCH 082/370] Stefan's added to the recipients list, Curt's old key replaced with new one git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171887 13f79535-47bb-0310-9956-ffa450edef68 --- old-log4net.snk.gpg | Bin 2260 -> 2535 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/old-log4net.snk.gpg b/old-log4net.snk.gpg index 626e4e1af01bca05399dffa9387e180cafd6e57a..57126212f156159fe1855a8c49e6fc742c4dd790 100644 GIT binary patch literal 2535 zcmVIwKeVLnvAD$At;IZrg&+c%Imyjp)a z-DJDI+I0AIJuSWd!bOd&b@_CEkj6x;$r_Ft#MvYB=0X|M<_aCkne+z$72^HinO8jc z_s}rAA13d=Etfj~9&fB55K%JSHGKa6$0Hwxo{p0UEa3_Jot>_qtrmN8pq`3u9-wRY zROT4Hbb9Q07{j<&1E`V0#oh<~5m)U>MfJa{l7XEHIJ@2}BW!Y6`Y=_FzCU^p@qa)t z9+;RwaR?eCpS_I8OmknT*je+_|I4xCRp2srCvH)?xN;+l|CrV6K@|87l=9%S^t~b} zAF2NVcz7xkUeP}Cl;vk{?oQwD4qh8tX5&DN{<%{{iIjsD0=}*cRTMI#LMAQ-O?Lqj zHK$vp#LPWQC6M5VVDBy)bVUmlN1_pyg&*fyCNlL==lA#MwQbqf+BK{cS^-@{g0g28 z*rN5f^jCt zqsu}B0H7Dsy;N(4hou@=@F!lpKVsC676d-=IMaHx?B7VnIy&>()whW01dqbE+U!$3dX$|x7k`bm9?&S^GP z>3{3j908#6+M5UZ_f7xudIO!K9Zrecji%_rTVrnFjxzA+DJ?LjgCY+ZiVIdX1a;*c z_OOdSH(j%uKZOouJxib~b;{5bLWTFue_p=aAoq<{i9RHla4}c;t-gH7b>6ieM1s*g zz~SvzjwL;BV_bbAU+(osgRD^wuBv@5E}YtZ?P$p-#bFM!4FW?%d!7}B88B;yOXjP! zKv_bH2yDg0NBg37j`}}W5pM~0bedWbueBX=^|eYLK?e#kX+kZdqt($eOT@e!>&WL4 zhMtdEE%f2eH~gU_kfHu$wgr{rl~T8hcAh#mNz{v?!CD~QtnuC|2mpW}`R(>5|Dky6 zsYPq=Le&K?^Cz`HoV0VMh5Q81!(bl%r$|c~6qz+oxPQ;5!4!FcQ6fPJUAK#zhNs9)KB+)r!d$nq)lKKT z$=e!iGHedsk8#Sm5s%YndCDRum-Yc=4NFefv5lX#9!BVcgDn+?3m?CKD7J><5Nz~7 zS(r(Nq8dSdA7!>OVKJk%15cl8=tI8d=u?gQBkmPiQJWP|NXn>+(Lv#19Ya-Ib+}N^ z3r#>~OZ6~|mhM5;g_m3!14*Jej8C5+kRu;bV8i~=8*S-QOM729P8=6IEC*SLtvWXwlr z7&Hd^fw5Xsq|f98Y6#Qc22;erNX++L2<`nIha`O&gQFQ5fL3Ig_8v(_d zzs?I9h-#{EmgFJpWlwGoMRUJy*|(Tv9K=K=q#++VxgUD=&gZ{@XF3uTJvPW|6Q3hC z`gAD5RJA4qSGrjI0-K@7y!(nF=~X2mfm~m$X;80R0wi^SuAv!-nL*%#NXm~V)V`D{ zu6lCKQfFrz~p&@qFhqezCP z|0XJ273CiRqX4e@lOEP233;4ZVy83`m`Y?}j}yr(I*-#3uWcf{YBW-LrAt}RLQERn zdgGia^g$!?{oTT%BlzbY_N1TP^Ip}$>J_<2(9f4ve3SME7x1YRFGOh9n@ue0ucrQ; zv%PS~h%w?`nk~IhtSK8`2P4EN);*EN?D)oJzI`N!ys zUe!YPinib`tU1o)R4+QBjswvfN2=QaRuBN{J@Q=koI6y&s<|CQ8k7336|OKpzRlu- zM#|P~1uElByzgGRX@%6Q{{fkFBuUWavpQ_z}W6hOTft ze=e%|;2q}pX3$GY*jpNKt0%x$HR>L>#Oe0;GRtI2SdjES-7cF7eFT_2sKSfxJ^GNrQ zJ8hyX2Uuker03ffOi+O!Z^1Ek$-%ai`iPlA3wM4OOk{{Y7p7XG&AjW!-Jt}31taY^ zF4@Tth2Y;6Nj$1Qv4>3wG_s1Y0_$DY~6EG*ZKg9`ZjpI zczrVR&)%9+NCZ=eKz@_YVo2LVA5m$pe|v5Qc_hlD=H~k;Y;{0@RC`XUr)I<;?7}pf xwds#Ca;zQ$k_e_xq4$XqMUVSnu%uZzzH~lLasRXy)QS96X^t)z^aZ&a&482O&#eFe literal 2260 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 From dd8ca308dfbc9ca66f1caf97d20fed621a0218c1 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sat, 17 Sep 2011 05:10:42 +0000 Subject: [PATCH 083/370] unlike the .NET cscs the mono versions don't create the target directory if needed git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1171895 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/log4net.build b/log4net.build index 1e8212e9..21e0beff 100644 --- a/log4net.build +++ b/log4net.build @@ -1085,6 +1085,9 @@ limitations under the License. + + + @@ -1173,6 +1176,9 @@ limitations under the License. + + + From c76083f906c8dc6635665d3ff69e0447ab959645 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 19 Sep 2011 08:35:03 +0000 Subject: [PATCH 084/370] try to strong name assemblies on .NET 1.0 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172515 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/log4net.build b/log4net.build index 21e0beff..4e85eb6b 100644 --- a/log4net.build +++ b/log4net.build @@ -471,22 +471,24 @@ limitations under the License. - + - - - + + - - - + + + - + @@ -505,6 +507,27 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + From b736146b5aa34de0d39db9525fc3887ac805c6fd Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 19 Sep 2011 08:40:32 +0000 Subject: [PATCH 085/370] fix target directory git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172519 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/log4net.build b/log4net.build index 4e85eb6b..3e2487fa 100644 --- a/log4net.build +++ b/log4net.build @@ -488,7 +488,7 @@ limitations under the License. - + From 5a161a53aa5389ce8410c7dd2f3a442c29f16392 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 19 Sep 2011 08:57:08 +0000 Subject: [PATCH 086/370] try to enable old and new key strong naming on all platforms I can currently build git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172524 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 101 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 21 deletions(-) diff --git a/log4net.build b/log4net.build index 3e2487fa..e1d20fd4 100644 --- a/log4net.build +++ b/log4net.build @@ -422,10 +422,6 @@ limitations under the License. - - - - @@ -446,6 +442,23 @@ limitations under the License. + + + + + + + + + + + + + + + + + @@ -536,22 +549,24 @@ limitations under the License. - + - - - + + - - - + + + - + @@ -570,6 +585,27 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + @@ -1338,24 +1374,26 @@ limitations under the License. - + - + - - - + + - - - + + + - + @@ -1374,6 +1412,27 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + From 6508e17e31a622711b8a4f296b94c4d690084522 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 19 Sep 2011 09:11:31 +0000 Subject: [PATCH 087/370] remove targets that deal with obsolete site generation git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172529 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 72 --------------------------------------------------- 1 file changed, 72 deletions(-) diff --git a/log4net.build b/log4net.build index e1d20fd4..8b96d126 100644 --- a/log4net.build +++ b/log4net.build @@ -21,11 +21,6 @@ limitations under the License. - - - - - @@ -1691,71 +1686,4 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From fc765a06a7ec061079cd4c94bc81a29b4133d026 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 19 Sep 2011 09:14:50 +0000 Subject: [PATCH 088/370] warning 1058 has been addressed in code now git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172530 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 88 --------------------------------------------------- 1 file changed, 88 deletions(-) diff --git a/log4net.build b/log4net.build index 8b96d126..62adb7bb 100644 --- a/log4net.build +++ b/log4net.build @@ -620,10 +620,6 @@ limitations under the License. - - - - @@ -644,10 +640,6 @@ limitations under the License. - - - - @@ -667,10 +659,6 @@ limitations under the License. - - - - @@ -708,10 +696,6 @@ limitations under the License. - - - - @@ -732,10 +716,6 @@ limitations under the License. - - - - @@ -755,10 +735,6 @@ limitations under the License. - - - - @@ -796,10 +772,6 @@ limitations under the License. - - - - @@ -820,10 +792,6 @@ limitations under the License. - - - - @@ -843,10 +811,6 @@ limitations under the License. - - - - @@ -884,10 +848,6 @@ limitations under the License. - - - - @@ -907,10 +867,6 @@ limitations under the License. - - - - @@ -929,10 +885,6 @@ limitations under the License. - - - - @@ -969,10 +921,6 @@ limitations under the License. - - - - @@ -993,10 +941,6 @@ limitations under the License. - - - - @@ -1016,10 +960,6 @@ limitations under the License. - - - - @@ -1057,10 +997,6 @@ limitations under the License. - - - - @@ -1080,10 +1016,6 @@ limitations under the License. - - - - @@ -1102,10 +1034,6 @@ limitations under the License. - - - - @@ -1145,12 +1073,6 @@ limitations under the License. - - - - - - @@ -1172,8 +1094,6 @@ limitations under the License. - - @@ -1195,8 +1115,6 @@ limitations under the License. - - @@ -1239,8 +1157,6 @@ limitations under the License. - - @@ -1263,8 +1179,6 @@ limitations under the License. - - @@ -1286,8 +1200,6 @@ limitations under the License. - - From 7de57a57aec194860d2132e5627faf29dc6f1311 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 19 Sep 2011 09:17:40 +0000 Subject: [PATCH 089/370] whitespace changes only, but lots of it git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172533 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 2520 +++++++++++++++++++++++++------------------------ 1 file changed, 1261 insertions(+), 1259 deletions(-) diff --git a/log4net.build b/log4net.build index 62adb7bb..86f68a68 100644 --- a/log4net.build +++ b/log4net.build @@ -16,686 +16,374 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - + + + + + + + - + @@ -707,15 +395,31 @@ limitations under the License. - - - + + + + + + + + + + + + + + + + + + + @@ -727,14 +431,72 @@ limitations under the License. - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -748,30 +510,58 @@ limitations under the License. - + + + + + + + + + + + + + + + + + + + + - + - - + + - + + + + + - + @@ -785,32 +575,51 @@ limitations under the License. - - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -829,8 +638,47 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -859,14 +707,71 @@ limitations under the License. + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -878,13 +783,71 @@ limitations under the License. + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -902,6 +865,43 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -938,9 +938,65 @@ limitations under the License. - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -952,14 +1008,71 @@ limitations under the License. - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -968,18 +1081,59 @@ limitations under the License. - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -994,9 +1148,16 @@ limitations under the License. + + + - + + + + + @@ -1005,17 +1166,81 @@ limitations under the License. - + - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1026,14 +1251,58 @@ limitations under the License. - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1045,557 +1314,290 @@ limitations under the License. + - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From fddeb33c69a3a8bfca18429011271d84796e5fc6 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 19 Sep 2011 09:46:37 +0000 Subject: [PATCH 090/370] Generate SDK docs for the website git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172543 13f79535-47bb-0310-9956-ffa450edef68 --- log4net.build | 19 +++++++++++++++++-- pom.xml | 11 ++++++----- src/site/xdoc/release/building.xml | 13 ++++++++++++- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/log4net.build b/log4net.build index 86f68a68..9e240023 100644 --- a/log4net.build +++ b/log4net.build @@ -1370,7 +1370,7 @@ limitations under the License. - + @@ -1410,7 +1410,9 @@ limitations under the License. - + + + @@ -1418,6 +1420,19 @@ limitations under the License. + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index b0f86584..04a6e405 100644 --- a/pom.xml +++ b/pom.xml @@ -152,16 +152,17 @@ + **/*.suo + **/*.user + **/obj/** bin/** - tests/bin/** build/** + doc/sdk/** src/log4net.xml - **/obj/** - **/*.user - **/*.suo + tests/bin/** - *.snk.* + *.snk* tests/lib/prerequisites.txt diff --git a/src/site/xdoc/release/building.xml b/src/site/xdoc/release/building.xml index b66f79ea..d28b2a42 100644 --- a/src/site/xdoc/release/building.xml +++ b/src/site/xdoc/release/building.xml @@ -164,7 +164,11 @@ sn -k log4net.snk

    - NDoc 1.3 is used to build the log4net SDK documentation. + NDoc 1.3 is used to build the log4net SDK + documentation using the generate-sdkdoc target in + log4net's Nant build file. + NDoc is available from ndoc.sourceforge.net.

    @@ -176,6 +180,13 @@ sn -k log4net.snk Building the documentation requires Java 5 or newer and Maven 2.2.1 or newer. Run mvn from within the root directory.

    +

    SDK documentation for the site is built using the + generate-sdkdoc-for-site target in + log4net's NAnt build file.

    +

    It is not recommended to use mvn's site:deploy goal but rather to + deploy the site generated to target/site manually.

    From b9952946676a33245b1c2877b650575d8928ce03 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 19 Sep 2011 10:44:51 +0000 Subject: [PATCH 091/370] start updating site docs for 1.2.11 git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172561 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 2 +- src/site/apt/download.apt | 53 ++++++++++++++++++++++-------- src/site/xdoc/release/features.xml | 40 +++++++++++++++++----- 3 files changed, 72 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index 04a6e405..231816e5 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ log4net apache-log4net pom - 1.2.11-SNAPSHOT + 1.2.11 Apache log4net Logging framework for Microsoft .NET Framework. http://logging.apache.org/log4net/ diff --git a/src/site/apt/download.apt b/src/site/apt/download.apt index 0522d31f..0c106340 100644 --- a/src/site/apt/download.apt +++ b/src/site/apt/download.apt @@ -13,39 +13,66 @@ ~~ See the License for the specific language governing permissions and ~~ limitations under the License. ------ -Download Apache log4net 1.2.10 +Download Apache log4net ------ ------ ------ -Download Apache log4net™ 1.2.10 +Download Apache log4net™ - Apache log4net 1.2.10 is distributed under the {{{http://www.apache.org/licenses/LICENSE-2.0.html} Apache License, version 2.0}}. + Apache log4net is distributed under the {{{http://www.apache.org/licenses/LICENSE-2.0.html} Apache License, version 2.0}}. - log4net has graduated from the Incubator project, however at the time the following releases were made, - log4net was still undergoing incubation, therefore these releases are not officially endorsed by the ASF. - Future releases of log4net will be officially endorsed by the ASF. + Starting with log4net 1.2.11 log4net is available as source only or + binary only release. - The link in the Mirrors column should display a list of available mirrors with a - default selection based on your inferred location. If you do not see that page, - try a different browser. The checksum and signature are links to - the originals on the main distribution server. + There are two different binary releases, <<>> and + <<>>. Both contain assemblies built for all supported + platforms and have been built from the same code base, they only + differ in the strong name key used to sign the assemblies. + + The <<>> distribution contains assemblies signed with the + same strong name key that was used to sign the assemblies of log4net + 1.2.10 and earlier. This strong name key is only available to + log4net developers. + + The <<>> distribution contains assemblies signed with the + strong name key available from + {{{https://svn.apache.org/repos/asf/logging/log4net/trunk/log4net.snk}log4net's svn area}}. + Everybody can create assemblies that have the same strong name which + is important if you want to use your own patched version of log4net. + + We recommend you use the assemblies signed with the "new" key + whenever possible. + + The link in the Mirrors column will lead you to a list of available + mirrors with a default selection based on your inferred location. + If you do not see that page, try a different browser. The checksum + and signature are links to the originals on the main distribution + server. *------------------------+---------+----------+-----------+ | Mirrors | Checksum | Signature | *------------------------+---------+----------+-----------+ *------------------------+---------+----------+-----------+ - log4net 1.2.10 (zip) | {{{http://archive.apache.org/dist/incubator/log4net/1.2.10/incubating-log4net-1.2.10.zip} incubating-log4net-1.2.10.zip}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.10/incubating-log4net-1.2.10.zip.md5} incubating-log4net-1.2.10.zip.md5}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.10/incubating-log4net-1.2.10.zip.asc} incubating-log4net-1.2.10.zip.asc}}| + log4net 1.2.10 Source Distribution | {{{http://www.apache.org/dyn/closer.cgi/logging/log4net/1.2.11/source/log4net-src-1.2.11.zip} log4net-src-1.2.11.zip}} | {{{http://www.apache.org/dist/logging/log4net/1.2.11/source/log4net-src-1.2.11.zip.md5} log4net-src-1.2.11.zip.md5}} | {{{http://www.apache.org/dist/logging/log4net/1.2.11/source/log4net-src-1.2.11.zip.asc} log4net-src-1.2.11.zip.asc}}| +*------------------------+---------+----------+-----------+ + log4net 1.2.10 Binary Distribution New Strong Name | {{{http://www.apache.org/dyn/closer.cgi/logging/log4net/1.2.11/binaries/log4net-bin-newkey-1.2.11.zip} log4net-bin-newkey-1.2.11.zip}} | {{{http://www.apache.org/dist/logging/log4net/1.2.11/binaries/log4net-bin-newkey-1.2.11.zip.md5} log4net-bin-newkey-1.2.11.zip.md5}} | {{{http://www.apache.org/dist/logging/log4net/1.2.11/binaries/log4net-bin-newkey-1.2.11.zip.asc} log4net-bin-newkey-1.2.11.zip.asc}}| *------------------------+---------+----------+-----------+ - log4net 1.2.9-beta (zip) | {{{http://archive.apache.org/dist/incubator/log4net/1.2.9/incubating-log4net-1.2.9-beta.zip} incubating-log4net-1.2.9-beta.zip}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.9/incubating-log4net-1.2.9-beta.zip.md5} incubating-log4net-1.2.9-beta.zip.md5}} | {{{http://archive.apache.org/dist/incubator/log4net/1.2.9/incubating-log4net-1.2.9-beta.zip.asc} incubating-log4net-1.2.9-beta.zip.asc}}| + log4net 1.2.10 Binary Distribution Old Strong Name | {{{http://www.apache.org/dyn/closer.cgi/logging/log4net/1.2.11/binaries/log4net-bin-oldkey-1.2.11.zip} log4net-bin-oldkey-1.2.11.zip}} | {{{http://www.apache.org/dist/logging/log4net/1.2.11/binaries/log4net-bin-oldkey-1.2.11.zip.md5} log4net-bin-oldkey-1.2.11.zip.md5}} | {{{http://www.apache.org/dist/logging/log4net/1.2.11/binaries/log4net-bin-oldkey-1.2.11.zip.asc} log4net-bin-oldkey-1.2.11.zip.asc}}| *------------------------+---------+----------+-----------+ Please read {{{http://httpd.apache.org/dev/verification.html}Verifying Apache HTTP Server Releases}} for more information on why you should verify our releases. The PGP keys used to sign our distributions are part of the - {{{http://www.apache.org/dist/logging/KEYS} KEYS file}}. + {{{http://www.apache.org/dist/logging/log4net/KEYS} KEYS file}}. * Previous Releases + The 1.2.10 and 1.2.9 releases have been created while log4net was + still undergoing incubation and those releases are available from + the Apache Software Foundation's + {{{http://archive.apache.org/dist/incubator/log4net/}distribution archive}}} + for the Incubator project. + Previous releases of log4net are available from the {{{http://sourceforge.net/project/showfiles.php?group_id=31983&release_id=171808}SourceForge Project Site}}. diff --git a/src/site/xdoc/release/features.xml b/src/site/xdoc/release/features.xml index 9de147a4..1e9bf6e1 100644 --- a/src/site/xdoc/release/features.xml +++ b/src/site/xdoc/release/features.xml @@ -69,20 +69,25 @@ limitations under the License. log4net has specific builds for the following frameworks:

      -
    • Microsoft .NET Framework 1.0 (1.0.3705)
    • -
    • Microsoft .NET Framework 1.1 (1.1.4322)
    • -
    • Microsoft .NET Framework 2.0 (2.0.50727)
    • +
    • Microsoft .NET Framework 1.0
    • +
    • Microsoft .NET Framework 1.1
    • +
    • Microsoft .NET Framework 2.0
    • +
    • Microsoft .NET Framework 3.5
    • +
    • Microsoft .NET Framework 4.0
    • +
    • Microsoft .NET Framework 3.5 Client Profile
    • +
    • Microsoft .NET Framework 4.0 Client Profile
    • Microsoft .NET Compact Framework 1.0
    • - +
    • Microsoft .NET Compact Framework 2.0
    • Mono 1.0
    • Mono 2.0
    • Microsoft Shared Source CLI 1.0
    • CLI 1.0 Compatible
    -

    - Note: Due to the .NET frameworks support for backward compatibility - log4net will run on future versions of the runtimes listed above. -

    +

    The "Client Profile" builds are stripped down + versions of the "normal" builds that don't contain any + ASP.NET releated code - which for example means the + %aspnet-* patterns and the + AspNetTraceAppender are not available.

    @@ -130,6 +135,12 @@ limitations under the License. the standard our stream or the standard error stream. + + log4net.Appender.DebugAppender + + Writes logging events to the .NET system. + + log4net.Appender.EventLogAppender @@ -195,6 +206,15 @@ limitations under the License. Sends logging events to an email address. + + log4net.Appender.SmtpPickupDirAppender + + Sends logging events to an email + address but writes the emails to a + configurable directory rather than + sending them directly via SMTP. + + log4net.Appender.TelnetAppender @@ -216,7 +236,9 @@ limitations under the License. -

    +

    A special log4net.Appender.ForwardingAppender can + be used to wrap another appender, for example to + attach additional filters.

    From dcfbed79eb9dbf505600f5494c152a9b11055eee Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 20 Sep 2011 04:07:31 +0000 Subject: [PATCH 092/370] Mono 2.0 doesn't like catch blocks without an exception either git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172969 13f79535-47bb-0310-9956-ffa450edef68 --- src/Repository/Hierarchy/Logger.cs | 6 +++--- src/Util/SystemStringFormat.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Repository/Hierarchy/Logger.cs b/src/Repository/Hierarchy/Logger.cs index 750e2bb5..f1013d0f 100644 --- a/src/Repository/Hierarchy/Logger.cs +++ b/src/Repository/Hierarchy/Logger.cs @@ -432,7 +432,7 @@ virtual public void Log(Type callerStackBoundaryDeclaringType, Level level, obje { log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); } -#if !NET_2_0 +#if !NET_2_0 && !MONO_2_0 catch { log4net.Util.LogLog.Error(declaringType, "Exception while logging"); @@ -469,7 +469,7 @@ virtual public void Log(LoggingEvent logEvent) { log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); } -#if !NET_2_0 +#if !NET_2_0 && !MONO_2_0 catch { log4net.Util.LogLog.Error(declaringType, "Exception while logging"); @@ -509,7 +509,7 @@ virtual public bool IsEnabledFor(Level level) { log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); } -#if !NET_2_0 +#if !NET_2_0 && !MONO_2_0 catch { log4net.Util.LogLog.Error(declaringType, "Exception while logging"); diff --git a/src/Util/SystemStringFormat.cs b/src/Util/SystemStringFormat.cs index 353708a9..82404b95 100644 --- a/src/Util/SystemStringFormat.cs +++ b/src/Util/SystemStringFormat.cs @@ -109,7 +109,7 @@ private static string StringFormat(IFormatProvider provider, string format, para log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]", ex); return StringFormatError(ex, format, args); } -#if !NET_2_0 +#if !NET_2_0 && !MONO_2_0 catch { log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]"); @@ -148,7 +148,7 @@ private static string StringFormatError(Exception formatException, string format log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex); return "Exception during StringFormat. See Internal Log."; } -#if !NET_2_0 +#if !NET_2_0 && !MONO_2_0 catch { log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling"); @@ -210,7 +210,7 @@ private static void RenderObject(Object obj, StringBuilder buffer) { buffer.Append(""); } -#if !NET_2_0 +#if !NET_2_0 && !MONO_2_0 catch { buffer.Append(""); From d17cc74cbd0354d97f87e5e708afd5a665e028cc Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 20 Sep 2011 04:22:16 +0000 Subject: [PATCH 093/370] skip failing message comparison on Mono/Linux git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1172973 13f79535-47bb-0310-9956-ffa450edef68 --- tests/src/Appender/RollingFileAppenderTest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/src/Appender/RollingFileAppenderTest.cs b/tests/src/Appender/RollingFileAppenderTest.cs index 5ff7166c..3e2d6ee9 100644 --- a/tests/src/Appender/RollingFileAppenderTest.cs +++ b/tests/src/Appender/RollingFileAppenderTest.cs @@ -1530,7 +1530,9 @@ public void TestExclusiveLockLocks() DestroyLogger(); Assert.IsTrue(locked, "File was not locked"); +#if !MONO // at least on Linux with Mono 2.4 exclusive locking doesn't work as one would expect AssertFileEquals(filename, "This is a message" + Environment.NewLine + "This is a message 2" + Environment.NewLine); +#endif Assert.AreEqual("", sh.Message, "Unexpected error message"); } From 8c7823e2a452b96a791c7e2edfaac5cc97c96009 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 20 Sep 2011 08:22:05 +0000 Subject: [PATCH 094/370] Update site pages for 1.2.11 release git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1173017 13f79535-47bb-0310-9956-ffa450edef68 --- src/site/resources/js/blockLocalOnlyLinks.js | 39 ---- src/site/xdoc/release/building.xml | 87 ++------ src/site/xdoc/release/example-apps.xml | 79 ++++--- src/site/xdoc/release/faq.xml | 12 +- src/site/xdoc/release/framework-support.xml | 197 ++++++++++++++++-- src/site/xdoc/release/manual/introduction.xml | 17 +- 6 files changed, 259 insertions(+), 172 deletions(-) delete mode 100644 src/site/resources/js/blockLocalOnlyLinks.js diff --git a/src/site/resources/js/blockLocalOnlyLinks.js b/src/site/resources/js/blockLocalOnlyLinks.js deleted file mode 100644 index 21a010a4..00000000 --- a/src/site/resources/js/blockLocalOnlyLinks.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - 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. - -*/ -function getElementsByClass(node,searchClass,tag) { - var classElements = new Array(); - var els = node.getElementsByTagName(tag); - var elsLen = els.length; - var pattern = new RegExp("\\b"+searchClass+"\\b"); - for (i = 0, j = 0; i < elsLen; i++) { - if ( pattern.test(els[i].className) ) { - classElements[j] = els[i]; - j++; - } - } - return classElements; -} -function BlockLocalOnlyLinks() { - if (window.location.protocol!="file:") { - var links = getElementsByClass(document, "localOnly", "a"); - for(var i=0; i < links.length; i++) { - links[i].href = "#overview"; - } - } -} -BlockLocalOnlyLinks(); diff --git a/src/site/xdoc/release/building.xml b/src/site/xdoc/release/building.xml index d28b2a42..448c149d 100644 --- a/src/site/xdoc/release/building.xml +++ b/src/site/xdoc/release/building.xml @@ -28,22 +28,18 @@ limitations under the License.

    The log4net release builds are built using NAnt. Log4net can also be built - using Visual Studio .NET 2002, 2003, or 2005. -

    -

    - To build a release build of log4net you will need to create a strong - name key file. See the Strong Name section below. + using Visual Studio .NET 2008 or 2010.

    - Visual Studio .NET 2002, 2003 and 2005 are supported build platforms for log4net. + Visual Studio .NET 2008 and 2010 are supported build platforms for log4net.

    -
    +

    The log4net distribution includes a solution and project file - for Visual Studio .NET 2002. Open the log4net.sln + for Visual Studio .NET 2008. Open the log4net.vs2008.sln from the src directory in the distribution.

    @@ -51,69 +47,36 @@ limitations under the License.

    • System
    • +
    • System.Configuration
    • System.Data
    • System.Web
    • System.XML
    -
    -

    - Open the Visual Studio .NET 2002 solution file as above. - Visual Studio will convert the solution and project files - to Visual Studio .NET 2003 format. -

    -

    - After converting the log4net project you must change the - Conditional Compilation Constants specified for the - log4net project. Open the project properties dialog and - select the Configuration Properties/Build sheet. - Replace the NET_1_0 constant with NET_1_1. - Remember to do this for both Debug and Release configurations. -

    -

    - The log4net project file is not suitable for building log4net - for the .NET Compact Framework. To build for the Compact Framework - you must create a new C# project for Smart Devices. Configure the - project as a library project. Add all the C# files from the - src directory in the distribution. -

    -
    - -
    -

    - Open the Visual Studio .NET 2002 solution file as above. - Visual Studio will convert the solution and project files - to Visual Studio .NET 2003 format. -

    +

    - After converting the log4net project you must change the - Conditional compilation symbols specified for the - log4net project. Open the project properties page and - select the Build sheet. - Replace the NET_1_0 symbol with NET_2_0. - Remember to do this for both Debug and Release configurations. + The log4net distribution includes a solution and project file + for Visual Studio .NET 2010. Open the log4net.vs2010.sln + from the src directory in the distribution.

    - In addition the log4net project requires the following new references: + The log4net project requires only the following references:

      +
    • System
    • System.Configuration
    • +
    • System.Data
    • +
    • System.Web
    • +
    • System.XML
    -

    - The log4net project file is not suitable for building log4net - for the .NET Compact Framework. To build for the Compact Framework - you must create a new C# project for Smart Devices. Configure the - project as a library project. Add all the C# files from the - src directory in the distribution. -

    - +

    The log4net distribution is built using the NAnt tool. - A recent NAnt version 0.85 nightly build is required to build log4net, this is + A recent NAnt version 0.91 alph2 is required to build log4net, this is available from nant.sourceforge.net.

    @@ -144,24 +107,6 @@ nant -buildfile:log4net.build -projecthelp build.cmd compile-all

    -
    -

    - In order to build the Release builds of log4net a Strong - Name key is required. -

    -

    - Use the sn.exe tool in the - .NET Framework SDK to generate a strong name key pair. -

    -
    -sn -k log4net.snk
    -

    - The log4net.snk file should be placed in the root of the - log4net distribution, in the same folder as the log4net.build - file. -

    -
    -

    NDoc 1.3 is used to build the log4net SDK diff --git a/src/site/xdoc/release/example-apps.xml b/src/site/xdoc/release/example-apps.xml index df4f0af3..b6fce366 100644 --- a/src/site/xdoc/release/example-apps.xml +++ b/src/site/xdoc/release/example-apps.xml @@ -29,8 +29,8 @@ limitations under the License.

    - The following examples are only available in the log4net release download, not - on-line. To obtain the examples download one of the log4net releases. + The following examples are only available in the log4net source download, not + on-line. To obtain the examples download the log4net source release.

    @@ -69,12 +69,12 @@ limitations under the License.

    There are Visual Studio .NET 2002 project files for the .NET 1.0 framework. - The solution files for C# and VB are in the examples\net\1.0 + The solution files for C# and VB are in the examples\net\1.0 folder.

    For the Managed C++ project there is a Visual Studio .NET 2003 project file - in the examples\net\1.1 folder. + in the examples\net\1.1 folder.

    @@ -94,26 +94,26 @@ limitations under the License.
    • MONO 1.0: - C# + C#
    • .NET 1.0: - C#, - VB + C#, + VB
    • .NET 1.1: - C++, - JScript.NET + C++, + JScript.NET
    • .NET Compact Framework 1.0: - C#, - VB + C#, + VB
    • SSCLI 1.0: - JScript.NET + JScript.NET

    @@ -134,8 +134,8 @@ limitations under the License.

    • .NET 1.0: - C#, - VB + C#, + VB

    @@ -162,7 +162,7 @@ limitations under the License.

    • .NET 1.0: - C# + C#

    @@ -185,7 +185,7 @@ limitations under the License.

    • .NET 1.0: - C# + C#

    @@ -210,20 +210,20 @@ limitations under the License.

    • MONO 1.0: - C# + C#
    • .NET 1.0: - C#, - VB + C#, + VB
    • .NET 1.1: - JScript.NET + JScript.NET
    • SSCLI 1.0: - C# + C#

    @@ -245,20 +245,20 @@ limitations under the License.

    • MONO 1.0: - C# + C#
    • .NET 1.0: - C#, - VB + C#, + VB
    • .NET 1.1: - JScript.NET + JScript.NET
    • SSCLI 1.0: - C# + C#

    @@ -280,20 +280,20 @@ limitations under the License.

    • MONO 1.0: - C# + C#
    • .NET 1.0: - C#, - VB + C#, + VB
    • .NET 1.1: - JScript.NET + JScript.NET
    • SSCLI 1.0: - C# + C#

    @@ -315,7 +315,7 @@ limitations under the License.

    • .NET 1.0: - C# + C#

    @@ -337,7 +337,7 @@ limitations under the License.

    • .NET 1.0: - C# + C#

    @@ -383,7 +383,7 @@ limitations under the License.

    • .NET 1.0: - C# + C#

    @@ -411,7 +411,7 @@ limitations under the License.

    • .NET 1.0: - C# + C#

    @@ -432,12 +432,12 @@ limitations under the License.

    • MONO 1.0: - C# + C#
    • .NET 1.0: - C#, - VB + C#, + VB

    @@ -457,7 +457,7 @@ limitations under the License.

    • .NET 1.0: - C# + C#

    @@ -467,6 +467,5 @@ limitations under the License.

    - - #end -#end -## - - - - $title - - -#foreach( $author in $authors ) - -#end -#if ( $dateCreation ) - -#end -#if ( $dateRevision ) - -#end -#if ( $locale ) - -#end - #if ( $decoration.body.head ) - #foreach( $item in $decoration.body.head.getChildren() ) - ## Workaround for DOXIA-150 due to a non-desired behaviour in p-u - ## @see org.codehaus.plexus.util.xml.Xpp3Dom#toString() - ## @see org.codehaus.plexus.util.xml.Xpp3Dom#toUnescapedString() - #set ( $documentHeader = '' ) - #if ( $item.name == "script" ) - $StringUtils.replace( $item.toUnescapedString(), $documentHeader, "" ) - #else - $StringUtils.replace( $item.toString(), $documentHeader, "" ) - #end - #end - #end - $headContent - #googleAnalytics( $decoration.googleAnalyticsAccountId ) - - - - -
    - -
    -
    -
    - $bodyContent -
    -
    -
    -
    -
    -
    - /// The logger to wrap - /// The wrapper for the logger specified - private static ILoggerWrapper WrapperCreationHandler(ILogger logger) - { - return new EventIDLogImpl(logger); - } - - #endregion - } -} diff --git a/src/extensions/log4net.Ext.EventID/IEventIDLog.cs b/src/extensions/log4net.Ext.EventID/IEventIDLog.cs deleted file mode 100644 index fb275bbd..00000000 --- a/src/extensions/log4net.Ext.EventID/IEventIDLog.cs +++ /dev/null @@ -1,45 +0,0 @@ -#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 - -/* - * Custom Logging Classes to support Event IDs. - */ - -using System; - -using log4net; - -namespace log4net.Ext.EventID -{ - public interface IEventIDLog : ILog - { - void Info(int eventId, object message); - void Info(int eventId, object message, Exception t); - - void Warn(int eventId, object message); - void Warn(int eventId, object message, Exception t); - - void Error(int eventId, object message); - void Error(int eventId, object message, Exception t); - - void Fatal(int eventId, object message); - void Fatal(int eventId, object message, Exception t); - } -} - diff --git a/src/extensions/log4net.Ext.EventID/log4net.Ext.EventID.vs2003.csproj b/src/extensions/log4net.Ext.EventID/log4net.Ext.EventID.vs2003.csproj deleted file mode 100644 index 3fc92b4a..00000000 --- a/src/extensions/log4net.Ext.EventID/log4net.Ext.EventID.vs2003.csproj +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/extensions/log4net.Ext.EventID/log4net.Ext.EventID.vs2012.csproj b/src/extensions/log4net.Ext.EventID/log4net.Ext.EventID.vs2012.csproj deleted file mode 100644 index f124f5c6..00000000 --- a/src/extensions/log4net.Ext.EventID/log4net.Ext.EventID.vs2012.csproj +++ /dev/null @@ -1,158 +0,0 @@ - - - - - Local - 7.0.9466 - 1.0 - {CB985027-C009-4C0F-88C1-8CF11912EE4C} - Debug - AnyCPU - - - log4net.Ext.EventID - - JScript - Grid - IE50 - false - Library - log4net.Ext.EventID - OnBuildSuccess - - - - v4.5 - - - 0.0 - veröffentlichen\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - ..\..\..\build\bin\extensions\log4net.Ext.EventID\net\4.5\debug\ - false - 285212672 - false - - DEBUG;TRACE - - true - 4096 - false - - false - false - false - false - 4 - full - prompt - false - - - ..\..\..\build\bin\extensions\log4net.Ext.EventID\net\4.5\release\ - false - 285212672 - false - - TRACE;STRONG - - true - 4096 - false - - true - false - false - false - 4 - pdbonly - prompt - false - - - - System - - - System.Data - - - System.XML - - - - - AssemblyVersionInfo.cs - - - Code - - - Code - - - Code - - - Code - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - - - {181fe707-e161-4722-9f38-6aaab6faa106} - log4net.vs2012 - - - - - - - - diff --git a/src/extensions/log4net.Ext.MarshalByRef/AssemblyInfo.cs b/src/extensions/log4net.Ext.MarshalByRef/AssemblyInfo.cs deleted file mode 100644 index a8055ddc..00000000 --- a/src/extensions/log4net.Ext.MarshalByRef/AssemblyInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -#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.Reflection; -using System.Runtime.CompilerServices; - -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// -[assembly: AssemblyTitle("log4net.Ext.MarshalByRef")] -[assembly: AssemblyDescription("log4net MarshalByRef Extension")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyProduct("log4net.Ext.MarshalByRef")] -[assembly: AssemblyCulture("")] - -// -// In order to sign your assembly you must specify a key to use. Refer to the -// Microsoft .NET Framework documentation for more information on assembly signing. -// -// Use the attributes below to control which key is used for signing. -// -// Notes: -// (*) If no key is specified, the assembly is not signed. -// (*) KeyName refers to a key that has been installed in the Crypto Service -// Provider (CSP) on your machine. KeyFile refers to a file which contains -// a key. -// (*) If the KeyFile and the KeyName values are both specified, the -// following processing occurs: -// (1) If the KeyName can be found in the CSP, that key is used. -// (2) If the KeyName does not exist and the KeyFile does exist, the key -// in the KeyFile is installed into the CSP and used. -// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. -// When specifying the KeyFile, the location of the KeyFile should be -// relative to the project output directory which is -// %Project Directory%\obj\. For example, if your KeyFile is -// located in the project directory, you would specify the AssemblyKeyFile -// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] -// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework -// documentation for more information on this. -// -#if STRONG -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile(@"..\..\..\..\log4net.snk")] -[assembly: AssemblyKeyName("")] -#endif diff --git a/src/extensions/log4net.Ext.MarshalByRef/MarshalByRefLogImpl.cs b/src/extensions/log4net.Ext.MarshalByRef/MarshalByRefLogImpl.cs deleted file mode 100644 index 237856a0..00000000 --- a/src/extensions/log4net.Ext.MarshalByRef/MarshalByRefLogImpl.cs +++ /dev/null @@ -1,437 +0,0 @@ -#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 System.Globalization; - -using log4net.Core; -using log4net.Repository; -using log4net.Util; - -namespace log4net.Ext.MarshalByRef -{ - /// - /// Marshal By Reference implementation of - /// - /// - /// - /// Logger wrapper that is . These objects - /// can be passed by reference across a remoting boundary. - /// - /// - public sealed class MarshalByRefLogImpl : MarshalByRefObject, ILog - { - private readonly static Type ThisDeclaringType = typeof(MarshalByRefLogImpl); - private readonly ILogger m_logger; - private Level m_levelTrace; - private Level m_levelDebug; - private Level m_levelInfo; - private Level m_levelWarn; - private Level m_levelError; - private Level m_levelFatal; - - #region Public Instance Constructors - - public MarshalByRefLogImpl(ILogger logger) - { - m_logger = logger; - - // Listen for changes to the repository - logger.Repository.ConfigurationChanged += new LoggerRepositoryConfigurationChangedEventHandler(LoggerRepositoryConfigurationChanged); - - // load the current levels - ReloadLevels(logger.Repository); - } - - #endregion Public Instance Constructors - - private void ReloadLevels(ILoggerRepository repository) - { - LevelMap levelMap = repository.LevelMap; - - m_levelTrace = levelMap.LookupWithDefault(Level.Trace); - m_levelDebug = levelMap.LookupWithDefault(Level.Debug); - m_levelInfo = levelMap.LookupWithDefault(Level.Info); - m_levelWarn = levelMap.LookupWithDefault(Level.Warn); - m_levelError = levelMap.LookupWithDefault(Level.Error); - m_levelFatal = levelMap.LookupWithDefault(Level.Fatal); - } - - private void LoggerRepositoryConfigurationChanged(object sender, EventArgs e) - { - ILoggerRepository repository = sender as ILoggerRepository; - if (repository != null) - { - ReloadLevels(repository); - } - } - - #region Implementation of ILog - - public void Trace(object message) - { - Logger.Log(ThisDeclaringType, m_levelTrace, message, null); - } - - public void Trace(object message, Exception t) - { - Logger.Log(ThisDeclaringType, m_levelTrace, message, t); - } - - public void TraceFormat(string format, params object[] args) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - public void TraceFormat(string format, object arg0) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - public void TraceFormat(string format, object arg0, object arg1) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - public void TraceFormat(string format, object arg0, object arg1, object arg2) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - public void TraceFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(provider, format, args), null); - } - } - - public void Debug(object message) - { - Logger.Log(ThisDeclaringType, m_levelDebug, message, null); - } - - public void Debug(object message, Exception t) - { - Logger.Log(ThisDeclaringType, m_levelDebug, message, t); - } - - public void DebugFormat(string format, params object[] args) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - public void DebugFormat(string format, object arg0) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - public void DebugFormat(string format, object arg0, object arg1) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - public void DebugFormat(string format, object arg0, object arg1, object arg2) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - public void DebugFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(provider, format, args), null); - } - } - - public void Info(object message) - { - Logger.Log(ThisDeclaringType, m_levelInfo, message, null); - } - - public void Info(object message, Exception t) - { - Logger.Log(ThisDeclaringType, m_levelInfo, message, t); - } - - public void InfoFormat(string format, params object[] args) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - public void InfoFormat(string format, object arg0) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - public void InfoFormat(string format, object arg0, object arg1) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - public void InfoFormat(string format, object arg0, object arg1, object arg2) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - public void InfoFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(provider, format, args), null); - } - } - - public void Warn(object message) - { - Logger.Log(ThisDeclaringType, m_levelWarn, message, null); - } - - public void Warn(object message, Exception t) - { - Logger.Log(ThisDeclaringType, m_levelWarn, message, t); - } - - public void WarnFormat(string format, params object[] args) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - public void WarnFormat(string format, object arg0) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - public void WarnFormat(string format, object arg0, object arg1) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - public void WarnFormat(string format, object arg0, object arg1, object arg2) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - public void WarnFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(provider, format, args), null); - } - } - - public void Error(object message) - { - Logger.Log(ThisDeclaringType, m_levelError, message, null); - } - - public void Error(object message, Exception t) - { - Logger.Log(ThisDeclaringType, m_levelError, message, t); - } - - public void ErrorFormat(string format, params object[] args) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - public void ErrorFormat(string format, object arg0) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - public void ErrorFormat(string format, object arg0, object arg1) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - public void ErrorFormat(string format, object arg0, object arg1, object arg2) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - public void ErrorFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(provider, format, args), null); - } - } - - public void Fatal(object message) - { - Logger.Log(ThisDeclaringType, m_levelFatal, message, null); - } - - public void Fatal(object message, Exception t) - { - Logger.Log(ThisDeclaringType, m_levelFatal, message, t); - } - - public void FatalFormat(string format, params object[] args) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - public void FatalFormat(string format, object arg0) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - public void FatalFormat(string format, object arg0, object arg1) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - public void FatalFormat(string format, object arg0, object arg1, object arg2) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - public void FatalFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(provider, format, args), null); - } - } - - public bool IsTraceEnabled - { - get { return Logger.IsEnabledFor(m_levelTrace); } - } - - public bool IsDebugEnabled - { - get { return Logger.IsEnabledFor(m_levelDebug); } - } - - public bool IsInfoEnabled - { - get { return Logger.IsEnabledFor(m_levelInfo); } - } - - public bool IsWarnEnabled - { - get { return Logger.IsEnabledFor(m_levelWarn); } - } - - public bool IsErrorEnabled - { - get { return Logger.IsEnabledFor(m_levelError); } - } - - public bool IsFatalEnabled - { - get { return Logger.IsEnabledFor(m_levelFatal); } - } - - #endregion Implementation of ILog - - #region Implementation of ILoggerWrapper - - public ILogger Logger - { - get { return m_logger; } - } - - #endregion - - /// - /// Live forever - /// - /// null - public override object InitializeLifetimeService() - { - return null; - } - } -} diff --git a/src/extensions/log4net.Ext.MarshalByRef/MarshalByRefLogManager.cs b/src/extensions/log4net.Ext.MarshalByRef/MarshalByRefLogManager.cs deleted file mode 100644 index b88692c3..00000000 --- a/src/extensions/log4net.Ext.MarshalByRef/MarshalByRefLogManager.cs +++ /dev/null @@ -1,292 +0,0 @@ -#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 System.Reflection; -using System.Collections; - -using log4net; -using log4net.Core; -using log4net.Repository; -using log4net.Repository.Hierarchy; - -/* - * Custom Logging Classes to support Remoting by reference. - */ -namespace log4net.Ext.MarshalByRef -{ - /// - /// LogManager that returns loggers. - /// - public class MarshalByRefLogManager - { - #region Static Member Variables - - /// - /// The wrapper map to use to hold the objects - /// - private static readonly WrapperMap s_wrapperMap = new WrapperMap(new WrapperCreationHandler(WrapperCreationHandler)); - - #endregion - - #region Constructor - - /// - /// Private constructor to prevent object creation - /// - private MarshalByRefLogManager() { } - - #endregion - - #region Type Specific Manager Methods - - /// - /// Returns the named logger if it exists - /// - /// - /// If the named logger exists (in the default hierarchy) then it - /// returns a reference to the logger, otherwise it returns - /// null. - /// - /// The fully qualified logger name to look for - /// The logger found, or null - public static ILog Exists(string name) - { - return Exists(Assembly.GetCallingAssembly(), name); - } - - /// - /// Returns the named logger if it exists - /// - /// - /// If the named logger exists (in the specified domain) then it - /// returns a reference to the logger, otherwise it returns - /// null. - /// - /// the domain to lookup in - /// The fully qualified logger name to look for - /// The logger found, or null - public static ILog Exists(string domain, string name) - { - return WrapLogger(LoggerManager.Exists(domain, name)); - } - - /// - /// Returns the named logger if it exists - /// - /// - /// If the named logger exists (in the specified assembly's domain) then it - /// returns a reference to the logger, otherwise it returns - /// null. - /// - /// the assembly to use to lookup the domain - /// The fully qualified logger name to look for - /// The logger found, or null - public static ILog Exists(Assembly assembly, string name) - { - return WrapLogger(LoggerManager.Exists(assembly, name)); - } - - /// - /// Returns all the currently defined loggers in the default domain. - /// - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers - public static ILog[] GetCurrentLoggers() - { - return GetCurrentLoggers(Assembly.GetCallingAssembly()); - } - - /// - /// Returns all the currently defined loggers in the specified domain. - /// - /// the domain to lookup in - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers - public static ILog[] GetCurrentLoggers(string domain) - { - return WrapLoggers(LoggerManager.GetCurrentLoggers(domain)); - } - - /// - /// Returns all the currently defined loggers in the specified assembly's domain. - /// - /// the assembly to use to lookup the domain - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers - public static ILog[] GetCurrentLoggers(Assembly assembly) - { - return WrapLoggers(LoggerManager.GetCurrentLoggers(assembly)); - } - - /// - /// Retrieve or create a named logger. - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// The name of the logger to retrieve. - /// the logger with the name specified - public static ILog GetLogger(string name) - { - return GetLogger(Assembly.GetCallingAssembly(), name); - } - - /// - /// Retrieve or create a named logger. - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// the domain to lookup in - /// The name of the logger to retrieve. - /// the logger with the name specified - public static ILog GetLogger(string domain, string name) - { - return WrapLogger(LoggerManager.GetLogger(domain, name)); - } - - /// - /// Retrieve or create a named logger. - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// the assembly to use to lookup the domain - /// The name of the logger to retrieve. - /// the logger with the name specified - public static ILog GetLogger(Assembly assembly, string name) - { - return WrapLogger(LoggerManager.GetLogger(assembly, name)); - } - - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// The full name of will - /// be used as the name of the logger to retrieve. - /// the logger with the name specified - public static ILog GetLogger(Type type) - { - return GetLogger(Assembly.GetCallingAssembly(), type.FullName); - } - - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// the domain to lookup in - /// The full name of will - /// be used as the name of the logger to retrieve. - /// the logger with the name specified - public static ILog GetLogger(string domain, Type type) - { - return WrapLogger(LoggerManager.GetLogger(domain, type)); - } - - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// the assembly to use to lookup the domain - /// The full name of will - /// be used as the name of the logger to retrieve. - /// the logger with the name specified - public static ILog GetLogger(Assembly assembly, Type type) - { - return WrapLogger(LoggerManager.GetLogger(assembly, type)); - } - - #endregion - - #region Extension Handlers - - /// - /// Lookup the wrapper object for the logger specified - /// - /// the logger to get the wrapper for - /// the wrapper for the logger specified - public static ILog WrapLogger(ILogger logger) - { - return (ILog)s_wrapperMap.GetWrapper(logger); - } - - /// - /// Lookup the wrapper objects for the loggers specified - /// - /// the loggers to get the wrappers for - /// Lookup the wrapper objects for the loggers specified - public static ILog[] WrapLoggers(ILogger[] loggers) - { - ILog[] results = new ILog[loggers.Length]; - for(int i=0; i - /// Method to create the objects used by - /// this manager. - ///
    - /// The logger to wrap - /// The wrapper for the logger specified - private static ILoggerWrapper WrapperCreationHandler(ILogger logger) - { - return new MarshalByRefLogImpl(logger); - } - - #endregion - } -} diff --git a/src/extensions/log4net.Ext.MarshalByRef/log4net.Ext.MarshalByRef.vs2003.csproj b/src/extensions/log4net.Ext.MarshalByRef/log4net.Ext.MarshalByRef.vs2003.csproj deleted file mode 100644 index 16c3394d..00000000 --- a/src/extensions/log4net.Ext.MarshalByRef/log4net.Ext.MarshalByRef.vs2003.csproj +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/extensions/log4net.Ext.MarshalByRef/log4net.Ext.MarshalByRef.vs2012.csproj b/src/extensions/log4net.Ext.MarshalByRef/log4net.Ext.MarshalByRef.vs2012.csproj deleted file mode 100644 index ccab2ed9..00000000 --- a/src/extensions/log4net.Ext.MarshalByRef/log4net.Ext.MarshalByRef.vs2012.csproj +++ /dev/null @@ -1,152 +0,0 @@ - - - - - Local - 7.0.9466 - 1.0 - {CB985027-C009-4C0F-88C1-8CF11912AE4C} - Debug - AnyCPU - - - log4net.Ext.MarshalByRef - - JScript - Grid - IE50 - false - Library - log4net.Ext.MarshalByRef - OnBuildSuccess - - - - v4.5 - - - 0.0 - - veröffentlichen\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - ..\..\..\build\bin\extensions\log4net.Ext.MarschalByRef\net\4.5\debug\ - false - 285212672 - false - - DEBUG;TRACE - - true - 4096 - false - - false - false - false - false - 4 - full - prompt - false - - - ..\..\..\build\bin\extensions\log4net.Ext.MarschalByRef\net\4.5\release\ - false - 285212672 - false - - TRACE;STRONG - - true - 4096 - false - - true - false - false - false - 4 - pdbonly - prompt - false - - - - System - - - System.Data - - - - - AssemblyVersionInfo.cs - - - Code - - - Code - - - Code - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - - - {181fe707-e161-4722-9f38-6aaab6faa106} - log4net.vs2012 - - - - - - - - diff --git a/src/log4net.Tests/Appender/AdoNet/Log4NetCommand.cs b/src/log4net.Tests/Appender/AdoNet/Log4NetCommand.cs deleted file mode 100644 index 98beb8e2..00000000 --- a/src/log4net.Tests/Appender/AdoNet/Log4NetCommand.cs +++ /dev/null @@ -1,144 +0,0 @@ -/* - * - * 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; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetCommand : IDbCommand - { - #region AdoNetAppender - - private static Log4NetCommand mostRecentInstance; - - private IDbTransaction transaction; - private string commandText; - private readonly IDataParameterCollection parameters; - private CommandType commandType; - private int executeNonQueryCount; - - public Log4NetCommand() - { - mostRecentInstance = this; - - parameters = new Log4NetParameterCollection(); - } - - public void Dispose() - { - // empty - } - - public IDbTransaction Transaction - { - get { return transaction; } - set { transaction = value; } - } - - public int ExecuteNonQuery() - { - executeNonQueryCount++; - return 0; - } - - public int ExecuteNonQueryCount - { - get { return executeNonQueryCount; } - } - - public IDbDataParameter CreateParameter() - { - return new Log4NetParameter(); - } - - public string CommandText - { - get { return commandText; } - set { commandText = value; } - } - - public CommandType CommandType - { - get { return commandType; } - set { commandType = value; } - } - - public void Prepare() - { - // empty - } - - public IDataParameterCollection Parameters - { - get { return parameters; } - } - - public static Log4NetCommand MostRecentInstance - { - get { return mostRecentInstance; } - } - - #endregion - - #region Not Implemented - - public void Cancel() - { - throw new NotImplementedException(); - } - - public IDataReader ExecuteReader() - { - throw new NotImplementedException(); - } - - public IDataReader ExecuteReader(CommandBehavior behavior) - { - throw new NotImplementedException(); - } - - public object ExecuteScalar() - { - throw new NotImplementedException(); - } - - public IDbConnection Connection - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - public int CommandTimeout - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - public UpdateRowSource UpdatedRowSource - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - #endregion - } -} diff --git a/src/log4net.Tests/Appender/AdoNet/Log4NetConnection.cs b/src/log4net.Tests/Appender/AdoNet/Log4NetConnection.cs deleted file mode 100644 index 33bbcce0..00000000 --- a/src/log4net.Tests/Appender/AdoNet/Log4NetConnection.cs +++ /dev/null @@ -1,111 +0,0 @@ -/* - * - * 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; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetConnection : IDbConnection - { - #region AdoNetAppender - - private static Log4NetConnection mostRecentInstance; - - private bool open; - private string connectionString; - - public Log4NetConnection() - { - mostRecentInstance = this; - } - - public void Close() - { - open = false; - } - - public ConnectionState State - { - get - { - return open ? ConnectionState.Open : ConnectionState.Closed; - } - } - - public string ConnectionString - { - get { return connectionString; } - set { connectionString = value; } - } - - public IDbTransaction BeginTransaction() - { - return new Log4NetTransaction(); - } - - public IDbCommand CreateCommand() - { - return new Log4NetCommand(); - } - - public void Open() - { - open = true; - } - - public static Log4NetConnection MostRecentInstance - { - get { return mostRecentInstance; } - } - - #endregion - - #region Not Implemented - - public IDbTransaction BeginTransaction(IsolationLevel il) - { - throw new NotImplementedException(); - } - - public void ChangeDatabase(string databaseName) - { - throw new NotImplementedException(); - } - - public int ConnectionTimeout - { - get { throw new NotImplementedException(); } - } - - public string Database - { - get { throw new NotImplementedException(); } - } - - public void Dispose() - { - throw new NotImplementedException(); - } - - #endregion - } -} diff --git a/src/log4net.Tests/Appender/AdoNet/Log4NetParameter.cs b/src/log4net.Tests/Appender/AdoNet/Log4NetParameter.cs deleted file mode 100644 index 4eb038d3..00000000 --- a/src/log4net.Tests/Appender/AdoNet/Log4NetParameter.cs +++ /dev/null @@ -1,103 +0,0 @@ -/* - * - * 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; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetParameter : IDbDataParameter - { - #region AdoNetAppender - - private string parameterName; - private byte precision; - private byte scale; - private int size; - private DbType dbType; - private object value; - - public string ParameterName - { - get { return parameterName; } - set { parameterName = value; } - } - - public byte Precision - { - get { return precision; } - set { precision = value; } - } - - public byte Scale - { - get { return scale; } - set { scale = value; } - } - - public int Size - { - get { return size; } - set { size = value; } - } - - public DbType DbType - { - get { return dbType; } - set { dbType = value; } - } - - public object Value - { - get { return value; } - set { this.value = value; } - } - - #endregion - - #region Not Implemented - - public ParameterDirection Direction - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - public bool IsNullable - { - get { throw new NotImplementedException(); } - } - - public string SourceColumn - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - public DataRowVersion SourceVersion - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - #endregion - } -} diff --git a/src/log4net.Tests/Appender/AdoNet/Log4NetParameterCollection.cs b/src/log4net.Tests/Appender/AdoNet/Log4NetParameterCollection.cs deleted file mode 100644 index 8b0d0415..00000000 --- a/src/log4net.Tests/Appender/AdoNet/Log4NetParameterCollection.cs +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * 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.Collections; -using System.Data; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetParameterCollection : CollectionBase, IDataParameterCollection - { - #region AdoNetAppender - - private readonly Hashtable parameterNameToIndex = new Hashtable(); - - protected override void OnInsertComplete(int index, object value) - { - base.OnInsertComplete(index, value); - - IDataParameter param = (IDataParameter)value; - parameterNameToIndex[param.ParameterName] = index; - } - - public int IndexOf(string parameterName) - { - return (int)parameterNameToIndex[parameterName]; - } - - public object this[string parameterName] - { - get { return InnerList[IndexOf(parameterName)]; } - set { InnerList[IndexOf(parameterName)] = value; } - } - - #endregion - - #region Not Implemented - - public void RemoveAt(string parameterName) - { - throw new NotImplementedException(); - } - - public bool Contains(string parameterName) - { - throw new NotImplementedException(); - } - - #endregion - } -} diff --git a/src/log4net.Tests/Appender/AdoNet/Log4NetTransaction.cs b/src/log4net.Tests/Appender/AdoNet/Log4NetTransaction.cs deleted file mode 100644 index d52e3643..00000000 --- a/src/log4net.Tests/Appender/AdoNet/Log4NetTransaction.cs +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * 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; - -namespace log4net.Tests.Appender.AdoNet -{ - public class Log4NetTransaction : IDbTransaction - { - #region AdoNetAppender - - public void Commit() - { - // empty - } - - public void Rollback() - { - // empty - } - - #endregion - - #region Not Implemented - - public IDbConnection Connection - { - get { throw new NotImplementedException(); } - } - - public IsolationLevel IsolationLevel - { - get { throw new NotImplementedException(); } - } - - public void Dispose() - { - throw new NotImplementedException(); - } - - #endregion - } -} diff --git a/src/log4net.Tests/Appender/AdoNetAppenderTest.cs b/src/log4net.Tests/Appender/AdoNetAppenderTest.cs deleted file mode 100644 index 624f1c40..00000000 --- a/src/log4net.Tests/Appender/AdoNetAppenderTest.cs +++ /dev/null @@ -1,213 +0,0 @@ -/* - * - * 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.Tests.Appender.AdoNet; -using log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.Appender -{ - [TestFixture] - public class AdoNetAppenderTest - { - [Test] - public void NoBufferingTest() - { - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - - AdoNetAppender adoNetAppender = new AdoNetAppender(); - adoNetAppender.BufferSize = -1; - adoNetAppender.ConnectionType = "log4net.Tests.Appender.AdoNet.Log4NetConnection"; - adoNetAppender.ActivateOptions(); - - BasicConfigurator.Configure(rep, adoNetAppender); - - ILog log = LogManager.GetLogger(rep.Name, "NoBufferingTest"); - log.Debug("Message"); - Assert.AreEqual(1, Log4NetCommand.MostRecentInstance.ExecuteNonQueryCount); - } - - [Test] - public void WebsiteExample() - { - XmlDocument log4netConfig = new XmlDocument(); - #region Load log4netConfig - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "); - #endregion - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - ILog log = LogManager.GetLogger(rep.Name, "WebsiteExample"); - log.Debug("Message"); - - IDbCommand command = Log4NetCommand.MostRecentInstance; - - Assert.AreEqual( - "INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)", - command.CommandText); - - Assert.AreEqual(6, command.Parameters.Count); - - IDbDataParameter param = (IDbDataParameter)command.Parameters["@message"]; - Assert.AreEqual("Message", param.Value); - - param = (IDbDataParameter)command.Parameters["@log_level"]; - Assert.AreEqual(Level.Debug.ToString(), param.Value); - - param = (IDbDataParameter)command.Parameters["@logger"]; - Assert.AreEqual("WebsiteExample", param.Value); - - param = (IDbDataParameter)command.Parameters["@exception"]; - Assert.IsEmpty((string)param.Value); - } - - [Test] - public void NullPropertyXmlConfig() - { - XmlDocument log4netConfig = new XmlDocument(); - #region Load log4netConfig - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - - - "); - #endregion - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - ILog log = LogManager.GetLogger(rep.Name, "NullPropertyXmlConfig"); - - log.Debug("Message"); - IDbCommand command = Log4NetCommand.MostRecentInstance; - IDbDataParameter param = (IDbDataParameter)command.Parameters["@productId"]; - Assert.AreNotEqual(SystemInfo.NullText, param.Value); - Assert.AreEqual(DBNull.Value, param.Value); - } - - [Test] - public void NullPropertyProgmaticConfig() - { - AdoNetAppenderParameter productIdParam = new AdoNetAppenderParameter(); - productIdParam.ParameterName = "@productId"; - productIdParam.DbType = DbType.String; - productIdParam.Size = 50; - RawPropertyLayout rawPropertyLayout = new RawPropertyLayout(); - rawPropertyLayout.Key = "ProductId"; - productIdParam.Layout = rawPropertyLayout; - - AdoNetAppender appender = new AdoNetAppender(); - appender.ConnectionType = typeof(Log4NetConnection).FullName; - appender.BufferSize = -1; - appender.CommandText = "INSERT INTO Log ([productId]) VALUES (@productId)"; - appender.AddParameter(productIdParam); - appender.ActivateOptions(); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, appender); - ILog log = LogManager.GetLogger(rep.Name, "NullPropertyProgmaticConfig"); - - log.Debug("Message"); - IDbCommand command = Log4NetCommand.MostRecentInstance; - IDbDataParameter param = (IDbDataParameter)command.Parameters["@productId"]; - Assert.AreNotEqual(SystemInfo.NullText, param.Value); - Assert.AreEqual(DBNull.Value, param.Value); - } - } -} diff --git a/src/log4net.Tests/Appender/AppenderCollectionTest.cs b/src/log4net.Tests/Appender/AppenderCollectionTest.cs deleted file mode 100644 index 16bbacb5..00000000 --- a/src/log4net.Tests/Appender/AppenderCollectionTest.cs +++ /dev/null @@ -1,65 +0,0 @@ -#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 log4net.Appender; -using NUnit.Framework; - -namespace log4net.Tests.Appender -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - /// Carlos Muñoz - [TestFixture] - public class AppenderCollectionTest - { - /// - /// Verifies that ToArray returns the elements of the - /// - [Test] - public void ToArrayTest() - { - AppenderCollection appenderCollection = new AppenderCollection(); - IAppender appender = new MemoryAppender(); - appenderCollection.Add(appender); - - IAppender[] appenderArray = appenderCollection.ToArray(); - - Assert.AreEqual(1, appenderArray.Length); - Assert.AreEqual(appender, appenderArray[0]); - } - - [Test] - public void ReadOnlyToArrayTest() - { - AppenderCollection appenderCollection = new AppenderCollection(); - IAppender appender = new MemoryAppender(); - appenderCollection.Add(appender); - AppenderCollection readonlyAppenderCollection = AppenderCollection.ReadOnly(appenderCollection); - - IAppender[] appenderArray = readonlyAppenderCollection.ToArray(); - - Assert.AreEqual(1, appenderArray.Length); - Assert.AreEqual(appender, appenderArray[0]); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/AsyncAppenderTest.cs b/src/log4net.Tests/Appender/AsyncAppenderTest.cs deleted file mode 100644 index fbe43f84..00000000 --- a/src/log4net.Tests/Appender/AsyncAppenderTest.cs +++ /dev/null @@ -1,116 +0,0 @@ -#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 System.Threading; -using log4net.Appender; -using log4net.Config; -using log4net.Core; -using log4net.Layout; - -using NUnit.Framework; - -namespace log4net.Tests.Appender -{ - - [TestFixture] - public class AsyncAppenderTest - { - private AsyncAppender asyncAppender; - private StringAppender stringAppender; - private Repository.Hierarchy.Hierarchy hierarchy; - - [SetUp] - public void SetupRepository() - { - hierarchy = new Repository.Hierarchy.Hierarchy(); - - stringAppender = new StringAppender(); - stringAppender.Layout = new SimpleLayout(); - stringAppender.ActivateOptions(); - - asyncAppender = new AsyncAppender(); - asyncAppender.AddAppender(stringAppender); - asyncAppender.ActivateOptions(); - - BasicConfigurator.Configure(hierarchy, asyncAppender); - } - - [TearDown] - public void ResetRepository() - { - hierarchy.ResetConfiguration(); - hierarchy.Shutdown(); - hierarchy.Clear(); - } - - [Test] - public void ShouldLogSingleEvent() - { - ILogger logger = hierarchy.GetLogger("test"); - logger.Log(GetType(), Level.Warn, "foo", null); - string log = WaitSomeTimeAndReturnLogWithLineFeedsStripped(); - Assert.AreEqual("WARN - foo", log); - } - - [Test] - public void ShouldMaintainOrderOfEvents() - { - ILogger logger = hierarchy.GetLogger("test"); - logger.Log(GetType(), Level.Warn, "foo", null); - logger.Log(GetType(), Level.Warn, "bar", null); - logger.Log(GetType(), Level.Warn, "baz", null); - logger.Log(GetType(), Level.Warn, "xyzzy", null); - string log = WaitSomeTimeAndReturnLogWithLineFeedsStripped(); - Assert.AreEqual("WARN - fooWARN - barWARN - bazWARN - xyzzy", log); - } - - [Test] - public void ShouldForwardBulkOfEvents() - { - LoggingEvent[] events = new LoggingEvent[] { - new LoggingEvent(GetType(), hierarchy, "test", Level.Warn, "foo", null), - new LoggingEvent(GetType(), hierarchy, "test", Level.Warn, "bar", null), - new LoggingEvent(GetType(), hierarchy, "test", Level.Warn, "baz", null), - new LoggingEvent(GetType(), hierarchy, "test", Level.Warn, "xyzzy", null) - }; - asyncAppender.DoAppend(events); - string log = WaitSomeTimeAndReturnLogWithLineFeedsStripped(); - Assert.AreEqual("WARN - fooWARN - barWARN - bazWARN - xyzzy", log); - } - - [Test] - public void ShouldNotLogAfterClose() - { - ILogger logger = hierarchy.GetLogger("test"); - logger.Log(GetType(), Level.Warn, "foo", null); - Thread.Sleep(200); - hierarchy.Shutdown(); - logger.Log(GetType(), Level.Warn, "bar", null); - string log = WaitSomeTimeAndReturnLogWithLineFeedsStripped(); - Assert.AreEqual("WARN - foo", log); - } - - private string WaitSomeTimeAndReturnLogWithLineFeedsStripped() - { - Thread.Sleep(200); - return stringAppender.GetString().Replace(Environment.NewLine, string.Empty); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/BufferingAppenderTest.cs b/src/log4net.Tests/Appender/BufferingAppenderTest.cs deleted file mode 100644 index ca656630..00000000 --- a/src/log4net.Tests/Appender/BufferingAppenderTest.cs +++ /dev/null @@ -1,112 +0,0 @@ -#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 log4net.Appender; -using log4net.Config; -using log4net.Core; - -using NUnit.Framework; - -namespace log4net.Tests.Appender -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class BufferingAppenderTest - { - private BufferingForwardingAppender m_bufferingForwardingAppender; - private CountingAppender m_countingAppender; - private Repository.Hierarchy.Hierarchy m_hierarchy; - - - private void SetupRepository() - { - m_hierarchy = new Repository.Hierarchy.Hierarchy(); - - m_countingAppender = new CountingAppender(); - m_countingAppender.ActivateOptions(); - - m_bufferingForwardingAppender = new BufferingForwardingAppender(); - m_bufferingForwardingAppender.AddAppender(m_countingAppender); - - m_bufferingForwardingAppender.BufferSize = 0; - m_bufferingForwardingAppender.ClearFilters(); - m_bufferingForwardingAppender.Evaluator = null; - m_bufferingForwardingAppender.Fix = FixFlags.Partial; - m_bufferingForwardingAppender.Lossy = false; - m_bufferingForwardingAppender.LossyEvaluator = null; - m_bufferingForwardingAppender.Threshold = Level.All; - - m_bufferingForwardingAppender.ActivateOptions(); - - BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - } - - /// - /// - [Test] - public void TestSetupAppender() - { - SetupRepository(); - - Assert.AreEqual(0, m_countingAppender.Counter, "Test empty appender"); - - ILogger logger = m_hierarchy.GetLogger("test"); - logger.Log(typeof(BufferingAppenderTest), Level.Warn, "Message logged", null); - - Assert.AreEqual(1, m_countingAppender.Counter, "Test 1 event logged"); - } - - /// - /// - [Test] - public void TestBufferSize5() - { - SetupRepository(); - - m_bufferingForwardingAppender.BufferSize = 5; - m_bufferingForwardingAppender.ActivateOptions(); - - Assert.AreEqual(m_countingAppender.Counter, 0); - - ILogger logger = m_hierarchy.GetLogger("test"); - - logger.Log(typeof(BufferingAppenderTest), Level.Warn, "Message 1", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 1 event in buffer"); - logger.Log(typeof(BufferingAppenderTest), Level.Warn, "Message 2", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 event in buffer"); - logger.Log(typeof(BufferingAppenderTest), Level.Warn, "Message 3", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 3 event in buffer"); - logger.Log(typeof(BufferingAppenderTest), Level.Warn, "Message 4", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 4 event in buffer"); - logger.Log(typeof(BufferingAppenderTest), Level.Warn, "Message 5", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 5 event in buffer"); - logger.Log(typeof(BufferingAppenderTest), Level.Warn, "Message 6", null); - Assert.AreEqual(6, m_countingAppender.Counter, "Test 0 event in buffer. 6 event sent"); - logger.Log(typeof(BufferingAppenderTest), Level.Warn, "Message 7", null); - Assert.AreEqual(6, m_countingAppender.Counter, "Test 1 event in buffer. 6 event sent"); - logger.Log(typeof(BufferingAppenderTest), Level.Warn, "Message 8", null); - Assert.AreEqual(6, m_countingAppender.Counter, "Test 2 event in buffer. 6 event sent"); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/CountingAppender.cs b/src/log4net.Tests/Appender/CountingAppender.cs deleted file mode 100644 index 0e0aa15f..00000000 --- a/src/log4net.Tests/Appender/CountingAppender.cs +++ /dev/null @@ -1,85 +0,0 @@ -#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 log4net.Appender; -using log4net.Core; - -namespace log4net.Tests.Appender -{ - /// - /// Implements an Appender for test purposes that counts the - /// number of output calls to . - /// - /// - /// This appender is used in the unit tests. - /// - /// Nicko Cadell - /// Gert Driesen - public class CountingAppender : AppenderSkeleton - { - #region Public Instance Constructors - /// - /// Initializes a new instance of the class. - /// - public CountingAppender() - { - m_counter = 0; - } - #endregion Public Instance Constructors - - #region Public Instance Properties - /// - /// Returns the number of times has been called. - /// - /// - /// The number of times has been called. - /// - public int Counter - { - get { return m_counter; } - } - #endregion Public Instance Properties - - /// - /// Reset the counter to zero - /// - public void ResetCounter() - { - m_counter = 0; - } - - #region Override implementation of AppenderSkeleton - /// - /// Registers how many times the method has been called. - /// - /// The logging event. - protected override void Append(LoggingEvent logEvent) - { - m_counter++; - } - #endregion Override implementation of AppenderSkeleton - - #region Private Instance Fields - /// - /// The number of times has been called. - /// - private int m_counter; - #endregion Private Instance Fields - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/EventLogAppenderTest.cs b/src/log4net.Tests/Appender/EventLogAppenderTest.cs deleted file mode 100644 index 5d7ad296..00000000 --- a/src/log4net.Tests/Appender/EventLogAppenderTest.cs +++ /dev/null @@ -1,88 +0,0 @@ -#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.Diagnostics; - -using log4net.Appender; -using log4net.Core; - -using NUnit.Framework; - -namespace log4net.Tests.Appender -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class EventLogAppenderTest - { - /// - /// Verifies that for each event log level, the correct system - /// event log enumeration is returned - /// - [Test] - public void TestGetEntryTypeForExistingApplicationName() - { - EventLogAppender eventAppender = new EventLogAppender(); - eventAppender.ApplicationName = "Winlogon"; - eventAppender.ActivateOptions(); - - Assert.AreEqual( - EventLogEntryType.Information, - GetEntryType(eventAppender, Level.All)); - - Assert.AreEqual( - EventLogEntryType.Information, - GetEntryType(eventAppender, Level.Debug)); - - Assert.AreEqual( - EventLogEntryType.Information, - GetEntryType(eventAppender, Level.Info)); - - Assert.AreEqual( - EventLogEntryType.Warning, - GetEntryType(eventAppender, Level.Warn)); - - Assert.AreEqual( - EventLogEntryType.Error, - GetEntryType(eventAppender, Level.Error)); - - Assert.AreEqual( - EventLogEntryType.Error, - GetEntryType(eventAppender, Level.Fatal)); - - Assert.AreEqual( - EventLogEntryType.Error, - GetEntryType(eventAppender, Level.Off)); - } - - // - // Helper functions to dig into the appender - // - - private static EventLogEntryType GetEntryType(EventLogAppender appender, Level level) - { - return (EventLogEntryType)Utils.InvokeMethod(appender, "GetEntryType", level); - } - - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/MemoryAppenderTest.cs b/src/log4net.Tests/Appender/MemoryAppenderTest.cs deleted file mode 100644 index c2e5461f..00000000 --- a/src/log4net.Tests/Appender/MemoryAppenderTest.cs +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * 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. - * -*/ - -#if FRAMEWORK_3_5_OR_ABOVE - -using System; -using System.Linq; -using System.Threading; -using NUnit.Framework; -using log4net; -using log4net.Appender; -using log4net.Config; -using log4net.Core; -using log4net.Layout; -using log4net.Repository; - -namespace log4net.Tests.Appender -{ - [TestFixture] - public class MemoryAppenderTest - { - private static int cThreadsRunning; - private const int cThreadsMax = 10; - private const int cLogEntriesPerThread = 100; - private const long cEventsExpected = cLogEntriesPerThread * cThreadsMax; - - [Test] - public void TestThreadSafety() - { - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - var memoryAppender = new MemoryAppender(); - var patternLayout = new PatternLayout(); - memoryAppender.Layout = patternLayout; - memoryAppender.ActivateOptions(); - BasicConfigurator.Configure(rep, memoryAppender); - - cThreadsRunning = cThreadsMax; - var threads = Enumerable.Range(0, cThreadsMax) - .Select(i => new Thread(LogMessages(rep.Name))) - .ToList(); - - foreach (var thread in threads) - { - thread.Start(); - } - - long cEventsRead = 0; - while (cThreadsRunning > 0) - { - var events = memoryAppender.PopAllEvents(); - cEventsRead += events.Length; - } - foreach (var thread in threads) - { - thread.Join(); - } - cEventsRead += memoryAppender.PopAllEvents().Length; - Assert.AreEqual(cEventsExpected, cEventsRead, "Log events were lost."); - } - - private static ThreadStart LogMessages(string repository) - { - return () => { - var logger = LogManager.GetLogger(repository, "LoggerThread"); - for (var i = 0; i < cLogEntriesPerThread; i++) - { - logger.InfoFormat("Logging message {0}", i); - } - Interlocked.Decrement(ref cThreadsRunning); - }; - } - } -} -#endif \ No newline at end of file diff --git a/src/log4net.Tests/Appender/RemotingAppenderTest.cs b/src/log4net.Tests/Appender/RemotingAppenderTest.cs deleted file mode 100644 index 9d88e17f..00000000 --- a/src/log4net.Tests/Appender/RemotingAppenderTest.cs +++ /dev/null @@ -1,426 +0,0 @@ -#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 System.Collections; -using System.Reflection; -using System.Runtime.Remoting; -using System.Runtime.Remoting.Channels; -using System.Runtime.Remoting.Channels.Tcp; -using System.Threading; - -using log4net.Appender; -using log4net.Core; -using log4net.Repository.Hierarchy; -using log4net.Tests.Appender.Remoting.Data; -using log4net.Tests.Appender.Remoting.UserInterfaces; - -using NUnit.Framework; - -namespace log4net.Tests.Appender -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class RemotingAppenderTest - { - private IChannel m_remotingChannel = null; - - /// - /// Test that the Message property is correctly remoted - /// - [Test] - public void TestRemotedMessage() - { - // Setup the remoting appender - ConfigureRootAppender(FixFlags.Partial); - - RemoteLoggingSinkImpl.Instance.Reset(); - - Logger root; - root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root; - - string testMessage = string.Format("test message [ {0} ]", (new Random()).Next()); - - // Log a message that will be remoted - root.Log(Level.Debug, testMessage, null); - - // Wait for the remoted object to be delivered - Thread.Sleep(2000); - - LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events; - Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event"); - - Assert.AreEqual(testMessage, events[0].RenderedMessage, "Expect Message match after remoting event"); - } - - /// - /// Test that the LocationInfo property is not remoted when doing a Fix.Partial - /// - [Test] - public void TestPartialFix() - { - // Setup the remoting appender - ConfigureRootAppender(FixFlags.Partial); - - RemoteLoggingSinkImpl.Instance.Reset(); - - Logger root; - root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root; - - // Log a message that will be remoted - root.Log(Level.Debug, "test message", null); - - // Wait for the remoted object to be delivered - Thread.Sleep(2000); - - LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events; - Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event"); - - // Grab the event data - LoggingEventData eventData = GetLoggingEventData(events[0]); - - Assert.IsNull(eventData.LocationInfo, "Expect LocationInfo to be null because only doing a partial fix"); - } - - /// - /// Test that the LocationInfo property is remoted when doing a Fix.All - /// - [Test] - public void TestFullFix() - { - // Setup the remoting appender - ConfigureRootAppender(FixFlags.All); - - RemoteLoggingSinkImpl.Instance.Reset(); - - Logger root; - root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root; - - // Log a message that will be remoted - root.Log(Level.Debug, "test message", null); - - // Wait for the remoted object to be delivered - Thread.Sleep(2000); - - LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events; - Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event"); - - // Grab the event data - LoggingEventData eventData = GetLoggingEventData(events[0]); - - Assert.IsNotNull(eventData.LocationInfo, "Expect LocationInfo to not be null because doing a full fix"); - } - - /// - /// Test that the Message property is correctly remoted - /// - [Test] - public void TestRemotedMessageNdcPushPop() - { - // Setup the remoting appender - ConfigureRootAppender(FixFlags.Partial); - - RemoteLoggingSinkImpl.Instance.Reset(); - - Logger root; - root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root; - - string testMessage = string.Format("test message [ {0} ]", (new Random()).Next()); - - using(NDC.Push("value")) - { - } - - // Log a message that will be remoted - root.Log(Level.Debug, testMessage, null); - - // Wait for the remoted object to be delivered - Thread.Sleep(2000); - - LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events; - Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event"); - - Assert.AreEqual(testMessage, events[0].RenderedMessage, "Expect Message match after remoting event"); - } - - [Test] - public void TestNestedNdc() - { - // This test can suffer from timing and ordering issues as the RemotingAppender does dispatch events asynchronously - - // Setup the remoting appender - ConfigureRootAppender(FixFlags.Partial); - - RemoteLoggingSinkImpl.Instance.Reset(); - - TestService t; - t = new TestService(); - t.Test(); - - // Wait for the remoted objects to be delivered - Thread.Sleep(3000); - - LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events; - Assert.AreEqual(5, events.Length, "Expect to receive 5 remoted event"); - - Assert.AreEqual("begin test", events[0].RenderedMessage, "Verify event 1 RenderedMessage"); - Assert.AreEqual("feature", events[1].RenderedMessage, "Verify event 2 RenderedMessage"); - Assert.AreEqual("return", events[2].RenderedMessage, "Verify event 3 RenderedMessage"); - Assert.AreEqual("return", events[3].RenderedMessage, "Verify event 4 RenderedMessage"); - Assert.AreEqual("end test", events[4].RenderedMessage, "Verify event 5 RenderedMessage"); - - Assert.IsNull(events[0].Properties["NDC"], "Verify event 1 Properties"); - Assert.AreEqual("test1", events[1].Properties["NDC"], "Verify event 2 Properties"); - Assert.AreEqual("test1 test2", events[2].Properties["NDC"], "Verify event 3 Properties"); - Assert.AreEqual("test1", events[3].Properties["NDC"], "Verify event 4 Properties"); - Assert.IsNull(events[4].Properties["NDC"], "Verify event 5 Properties"); - } - - - private void RegisterRemotingServerChannel() - { - if (m_remotingChannel == null) - { - m_remotingChannel = new TcpChannel(8085); - - // Setup remoting server - try - { -#if !NETCF - ChannelServices.RegisterChannel(m_remotingChannel, false); -#else - ChannelServices.RegisterChannel(m_remotingChannel); -#endif - } - catch(Exception ex) - { - Assert.Fail("Failed to set up LoggingSink: {0}", ex); - } - - // Marshal the sink object - RemotingServices.Marshal(RemoteLoggingSinkImpl.Instance, "LoggingSink", typeof(RemotingAppender.IRemoteLoggingSink)); - } - } - - /// - /// Shuts down any loggers in the hierarchy, along - /// with all appenders. - /// - private static void ResetRepository() - { - // Regular users should not use the clear method lightly! - LogManager.GetRepository().ResetConfiguration(); - LogManager.GetRepository().Shutdown(); - ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Clear(); - } - - /// - /// Any initialization that happens before each test can - /// go here - /// - [SetUp] - public void SetUp() - { - ResetRepository(); - RegisterRemotingServerChannel(); - } - - /// - /// Any steps that happen after each test go here - /// - [TearDown] - public void TearDown() - { - ResetRepository(); - } - - /// - /// Close down remoting infrastructure - /// - [TestFixtureTearDown] - public void UnregisterRemotingServerChannel() { - if (m_remotingChannel != null) { - ((TcpChannel) m_remotingChannel).StopListening(null); - try { - ChannelServices.UnregisterChannel(m_remotingChannel); - } - catch (Exception) { - } - m_remotingChannel = null; - } - } - - /// - /// Configures the root appender for counting and rolling - /// - private static void ConfigureRootAppender(FixFlags fixFlags) - { - Logger root; - root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root; - root.Level = Level.Debug; - root.AddAppender(CreateAppender(fixFlags)); - root.Repository.Configured = true; - } - - private static RemotingAppender CreateAppender(FixFlags fixFlags) - { - RemotingAppender appender = new RemotingAppender(); - appender.Sink = "tcp://localhost:8085/LoggingSink"; - appender.Lossy = false; - appender.BufferSize = 1; - appender.Fix = fixFlags; - - appender.ActivateOptions(); - - return appender; - } - - public class RemoteLoggingSinkImpl : MarshalByRefObject, RemotingAppender.IRemoteLoggingSink - { - public static readonly RemoteLoggingSinkImpl Instance = new RemoteLoggingSinkImpl(); - - private ArrayList m_events = new ArrayList(); - - #region Public Instance Constructors - private RemoteLoggingSinkImpl() - { - } - #endregion Public Instance Constructors - - #region Implementation of IRemoteLoggingSink - /// - /// Logs the events to to an internal buffer - /// - /// The events to log. - /// - /// Logs the events to to an internal buffer. The logged events can - /// be retrieved via the property. To clear - /// the buffer call the method. - /// - public void LogEvents(LoggingEvent[] events) - { - m_events.AddRange(events); - } - #endregion Implementation of IRemoteLoggingSink - - #region Override implementation of MarshalByRefObject - /// - /// Obtains a lifetime service object to control the lifetime - /// policy for this instance. - /// - /// - /// null to indicate that this instance should live - /// forever. - /// - public override object InitializeLifetimeService() - { - return null; - } - #endregion Override implementation of MarshalByRefObject - - public void Reset() - { - m_events.Clear(); - } - - public LoggingEvent[] Events - { - get { return (LoggingEvent[])m_events.ToArray(typeof(LoggingEvent)); } - } - } - - // - // Helper functions to dig into the appender - // - - private static LoggingEventData GetLoggingEventData(LoggingEvent loggingEvent) - { - return (LoggingEventData)Utils.GetField(loggingEvent, "m_data"); - } - } -} - -// helper for TestNestedNdc - -namespace log4net.Tests.Appender.Remoting.UserInterfaces -{ - public class TestService - { - private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public void Test() - { - log.Info("begin test"); - Thread.Sleep(100); - - Feature f = new Feature(); - f.Test(); - log.Info("end test"); - Thread.Sleep(100); - } - } -} - -// helper for TestNestedNdc - -namespace log4net.Tests.Appender.Remoting -{ - public class Feature - { - private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public void Test() - { - using(NDC.Push("test1")) - { - log.Info("feature"); - Thread.Sleep(100); - - Dal d = new Dal(); - d.Test(); - log.Info("return"); - Thread.Sleep(100); - } - } - } -} - -// helper for TestNestedNdc - -namespace log4net.Tests.Appender.Remoting.Data -{ - public class Dal - { - private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public void Test() - { - using(NDC.Push("test2")) - { - log.Info("return"); - Thread.Sleep(100); - } - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/RollingFileAppenderTest.cs b/src/log4net.Tests/Appender/RollingFileAppenderTest.cs deleted file mode 100644 index c814169e..00000000 --- a/src/log4net.Tests/Appender/RollingFileAppenderTest.cs +++ /dev/null @@ -1,1961 +0,0 @@ -#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 System.Collections; -using System.Diagnostics; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; - -using log4net.Appender; -using log4net.Core; -using log4net.Layout; -using log4net.Repository.Hierarchy; -using log4net.Util; - -using NUnit.Framework; -using System.Globalization; - -namespace log4net.Tests.Appender -{ - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class RollingFileAppenderTest - { - private const string c_fileName = "test_41d3d834_4320f4da.log"; - private const string c_testMessage98Chars = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567"; - private const string c_testMessage99Chars = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678"; - private const int c_iMaximumFileSize = 450; // in bytes - private int _iMessagesLoggedThisFile = 0; - private int _iMessagesLogged = 0; - private int _iCountDirection = 0; - private int _MaxSizeRollBackups = 3; - private CountingAppender _caRoot; - private Logger _root; - private CultureInfo _currentCulture; - private CultureInfo _currentUICulture; - - private class SilentErrorHandler : IErrorHandler - { - private StringBuilder m_buffer = new StringBuilder(); - - public string Message - { - get { return m_buffer.ToString(); } - } - - public void Error(string message) - { - m_buffer.Append(message + "\n"); - } - - public void Error(string message, Exception e) - { - m_buffer.Append(message + "\n" + e.Message + "\n"); - } - - public void Error(string message, Exception e, ErrorCode errorCode) - { - m_buffer.Append(message + "\n" + e.Message + "\n"); - } - } - - /// - /// Sets up variables used for the tests - /// - private void InitializeVariables() - { - _iMessagesLoggedThisFile = 0; - _iMessagesLogged = 0; - _iCountDirection = +1; // Up - _MaxSizeRollBackups = 3; - } - - /// - /// Shuts down any loggers in the hierarchy, along - /// with all appenders, and deletes any test files used - /// for logging. - /// - private static void ResetAndDeleteTestFiles() - { - // Regular users should not use the clear method lightly! - LogManager.GetRepository().ResetConfiguration(); - LogManager.GetRepository().Shutdown(); - ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Clear(); - - DeleteTestFiles(); - } - - /// - /// Any initialization that happens before each test can - /// go here - /// - [SetUp] - public void SetUp() - { - ResetAndDeleteTestFiles(); - InitializeVariables(); - - // set correct thread culture - _currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture; - _currentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture; - System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; - } - - /// - /// Any steps that happen after each test go here - /// - [TearDown] - public void TearDown() - { - ResetAndDeleteTestFiles(); - - // restore previous culture - System.Threading.Thread.CurrentThread.CurrentCulture = _currentCulture; - System.Threading.Thread.CurrentThread.CurrentUICulture = _currentUICulture; - } - - /// - /// Finds the number of files that match the base file name, - /// and matches the result against an expected count - /// - /// - private static void VerifyFileCount(int iExpectedCount) - { - ArrayList alFiles = GetExistingFiles(c_fileName); - Assert.IsNotNull(alFiles); - Assert.AreEqual(iExpectedCount, alFiles.Count); - } - - /// - /// Creates a file with the given number, and the shared base file name - /// - /// - private static void CreateFile(int iFileNumber) - { - FileInfo fileInfo = new FileInfo(MakeFileName(c_fileName, iFileNumber)); - - FileStream fileStream = null; - try - { - fileStream = fileInfo.Create(); - } - finally - { - if (null != fileStream) - { - try - { - fileStream.Close(); - } - catch - { - } - } - } - } - - /// - /// Verifies that the code correctly loads all filenames - /// - [Test] - public void TestGetExistingFiles() - { - VerifyFileCount(0); - CreateFile(0); - VerifyFileCount(1); - CreateFile(1); - VerifyFileCount(2); - } - - /// - /// Removes all test files that exist - /// - private static void DeleteTestFiles() - { - ArrayList alFiles = GetExistingFiles(c_fileName); - foreach(string sFile in alFiles) - { - try - { - Debug.WriteLine("Deleting test file " + sFile); - File.Delete(sFile); - } - catch(Exception ex) - { - Debug.WriteLine("Exception while deleting test file " + ex); - } - } - } - - ///// - ///// Generates a file name associated with the count. - ///// - ///// - ///// - //private string MakeFileName(int iFileCount) - //{ - // return MakeFileName(_fileName, iFileCount); - //} - - /// - /// Generates a file name associated with the count, using - /// the base file name. - /// - /// - /// - /// - private static string MakeFileName(string sBaseFile, int iFileCount) - { - if (0 == iFileCount) - { - return sBaseFile; - } - return sBaseFile + "." + iFileCount; - } - - /// - /// Returns a RollingFileAppender using all the internal settings for maximum - /// file size and number of backups - /// - /// - private RollingFileAppender CreateAppender() - { - return CreateAppender(new FileAppender.ExclusiveLock()); - } - - /// - /// Returns a RollingFileAppender using all the internal settings for maximum - /// file size and number of backups - /// - /// The locking model to test - /// - private RollingFileAppender CreateAppender(FileAppender.LockingModelBase lockModel) - { - // - // Use a basic pattern that - // includes just the message and a CR/LF. - // - PatternLayout layout = new PatternLayout("%m%n"); - - // - // Create the new appender - // - RollingFileAppender appender = new RollingFileAppender(); - appender.Layout = layout; - appender.File = c_fileName; - appender.Encoding = Encoding.ASCII; - appender.MaximumFileSize = c_iMaximumFileSize.ToString(); - appender.MaxSizeRollBackups = _MaxSizeRollBackups; - appender.CountDirection = _iCountDirection; - appender.RollingStyle = RollingFileAppender.RollingMode.Size; - appender.LockingModel = lockModel; - - appender.ActivateOptions(); - - return appender; - } - - /// - /// Used for test purposes, a table of these objects can be used to identify - /// any existing files and their expected length. - /// - public class RollFileEntry - { - /// - /// Stores the name of the file - /// - private string m_fileName; - - /// - /// The expected length of the file - /// - private long m_fileLength; - - /// - /// Default constructor - /// - public RollFileEntry() - { - } - - /// - /// Constructor used when the fileInfo and expected length are known - /// - /// - /// - public RollFileEntry(string fileName, long fileLength) - { - m_fileName = fileName; - m_fileLength = fileLength; - } - - /// - /// Stores the name of the file - /// - public string FileName - { - get { return m_fileName; } - } - - /// - /// The expected length of the file - /// - public long FileLength - { - get { return m_fileLength; } - } - } - - /// - /// Used for table-driven testing. This class holds information that can be used - /// for testing of file rolling. - /// - public class RollConditions - { - /// - /// A table of entries showing files that should exist and their expected sizes - /// before logging is called - /// - private RollFileEntry[] m_preLogFileEntries; - - /// - /// A table of entries showing files that should exist and their expected sizes - /// after a message is logged - /// - private RollFileEntry[] m_postLogFileEntries; - - /// - /// Constructor, taking all required parameters - /// - /// - /// - public RollConditions(RollFileEntry[] preLogFileEntries, RollFileEntry[] postLogFileEntries) - { - m_preLogFileEntries = preLogFileEntries; - m_postLogFileEntries = postLogFileEntries; - } - - /// - /// A table of entries showing files that should exist and their expected sizes - /// before logging is called - /// - public RollFileEntry[] GetPreLogFileEntries() - { - return m_preLogFileEntries; - } - - /// - /// A table of entries showing files that should exist and their expected sizes - /// after a message is logged - /// - public RollFileEntry[] GetPostLogFileEntries() - { - return m_postLogFileEntries; - } - } - - private static void VerifyExistenceAndRemoveFromList(ArrayList alExisting, string sFileName, FileInfo file, RollFileEntry entry) - { - Assert.IsTrue(alExisting.Contains(sFileName), "filename {0} not found in test directory", sFileName); - Assert.AreEqual(entry.FileLength, file.Length, "file length mismatch"); - // Remove this file from the list - alExisting.Remove(sFileName); - } - - /// - /// Checks that all the expected files exist, and only the expected files. Also - /// verifies the length of all files against the expected length - /// - /// - /// - private static void VerifyFileConditions(string sBaseFileName, RollFileEntry[] fileEntries) - { - ArrayList alExisting = GetExistingFiles(sBaseFileName); - if (null != fileEntries) - { - // AssertEquals( "File count mismatch", alExisting.Count, fileEntries.Length ); - foreach(RollFileEntry rollFile in fileEntries) - { - string sFileName = rollFile.FileName; - FileInfo file = new FileInfo(sFileName); - - if (rollFile.FileLength > 0) - { - Assert.IsTrue(file.Exists, "filename {0} does not exist", sFileName); - VerifyExistenceAndRemoveFromList(alExisting, sFileName, file, rollFile); - } - else - { - // If length is 0, file may not exist yet. If file exists, make sure length - // is zero. If file doesn't exist, this is OK - - if (file.Exists) - { - VerifyExistenceAndRemoveFromList(alExisting, sFileName, file, rollFile); - } - } - } - } - else - { - Assert.AreEqual(0, alExisting.Count); - } - - // This check ensures no extra files matching the wildcard pattern exist. - // We only want the files we expect, and no others - Assert.AreEqual(0, alExisting.Count); - } - - /// - /// Called before logging a message to check that all the expected files exist, - /// and only the expected files. Also verifies the length of all files against - /// the expected length - /// - /// - /// - private static void VerifyPreConditions(string sBaseFileName, RollConditions entry) - { - VerifyFileConditions(sBaseFileName, entry.GetPreLogFileEntries()); - } - - /// - /// Called after logging a message to check that all the expected files exist, - /// and only the expected files. Also verifies the length of all files against - /// the expected length - /// - /// - /// - private static void VerifyPostConditions(string sBaseFileName, RollConditions entry) - { - VerifyFileConditions(sBaseFileName, entry.GetPostLogFileEntries()); - } - - /// - /// Logs a message, verifying the expected message counts against the - /// current running totals. - /// - /// - /// - private void LogMessage(RollConditions entry, string sMessageToLog) - { - Assert.AreEqual(_caRoot.Counter, _iMessagesLogged++); - _root.Log(Level.Debug, sMessageToLog, null); - Assert.AreEqual(_caRoot.Counter, _iMessagesLogged); - _iMessagesLoggedThisFile++; - } - - //private void DumpFileEntry( RollFileEntry entry ) - //{ - // System.Diagnostics.Debug.WriteLine( "\tfile name: " + entry.FileName ); - // System.Diagnostics.Debug.WriteLine( "\tfile length: " + entry.FileLength ); - //} - - //private void DumpTableEntry( RollConditions entry ) - //{ - // System.Diagnostics.Debug.WriteLine( "Pre-Conditions" ); - // foreach( RollFileEntry file in entry.GetPreLogFileEntries() ) - // { - // DumpFileEntry( file ); - // } - // System.Diagnostics.Debug.WriteLine( "Post-Conditions" ); - // foreach( RollFileEntry file in entry.GetPostLogFileEntries() ) - // { - // DumpFileEntry( file ); - // } - // // System.Diagnostics.Debug.WriteLine(""); - //} - - /// - /// Runs through all table entries, logging messages. Before each message is logged, - /// pre-conditions are checked to ensure the expected files exist and they are the - /// expected size. After logging, verifies the same. - /// - /// - /// - /// - private void RollFromTableEntries(string sBaseFileName, RollConditions[] entries, string sMessageToLog) - { - for(int i = 0; i < entries.Length; i++) - { - RollConditions entry = entries[i]; - - // System.Diagnostics.Debug.WriteLine( i + ": Entry " + i + " pre/post conditions"); - // DumpTableEntry( entry ); - // System.Diagnostics.Debug.WriteLine( i + ": Testing entry pre-conditions"); - VerifyPreConditions(sBaseFileName, entry); - // System.Diagnostics.Debug.WriteLine( i + ": Logging message"); - LogMessage(entry, sMessageToLog); - // System.Diagnostics.Debug.WriteLine( i + ": Testing entry post-conditions"); - VerifyPostConditions(sBaseFileName, entry); - // System.Diagnostics.Debug.WriteLine( i + ": Finished validating entry\n"); - } - } - - private static readonly int s_Newline_Length = Environment.NewLine.Length; - - /// - /// Returns the number of bytes logged per message, including - /// any newline characters in addition to the message length. - /// - /// - /// - private static int TotalMessageLength(string sMessage) - { - return sMessage.Length + s_Newline_Length; - } - - /// - /// Determines how many messages of a fixed length can be logged - /// to a single file before the file rolls. - /// - /// - /// - private static int MessagesPerFile(int iMessageLength) - { - int iMessagesPerFile = c_iMaximumFileSize / iMessageLength; - - // - // RollingFileAppender checks for wrap BEFORE logging, - // so we will actually get one more message per file than - // we would otherwise. - // - if (iMessagesPerFile * iMessageLength < c_iMaximumFileSize) - { - iMessagesPerFile++; - } - - return iMessagesPerFile; - } - - /// - /// Determines the name of the current file - /// - /// - private static string GetCurrentFile() - { - // Current file name is always the base file name when - // counting. Dates will need a different approach - return c_fileName; - } - - /// - /// Turns a group of file names into an array of file entries that include the name - /// and a size. This is useful for assigning the properties of backup files, when - /// the length of the files are all the same size due to a fixed message length. - /// - /// - /// - /// - private static RollFileEntry[] MakeBackupFileEntriesFromBackupGroup(string sBackupGroup, int iBackupFileLength) - { - string[] sFiles = sBackupGroup.Split(' '); - - ArrayList alEntries = new ArrayList(); - - for(int i = 0; i < sFiles.Length; i++) - { - // Weed out any whitespace entries from the array - if (sFiles[i].Trim().Length > 0) - { - alEntries.Add(new RollFileEntry(sFiles[i], iBackupFileLength)); - } - } - - return (RollFileEntry[])alEntries.ToArray(typeof(RollFileEntry)); - } - - /// - /// Finds the iGroup group in the string (comma separated groups) - /// - /// - /// - /// - private static string GetBackupGroup(string sBackupGroups, int iGroup) - { - string[] sGroups = sBackupGroups.Split(','); - return sGroups[iGroup]; - } - - ///// - ///// Builds a collection of file entries based on the file names - ///// specified in a groups string and the max file size from the - ///// stats object - ///// - ///// - ///// - ///// - //private RollFileEntry[] MakeBackupFileEntriesForPreCondition( string sBackupGroups, RollingStats stats ) - //{ - // if (0 == stats.NumberOfFileRolls ) - // { - // return null; // first round has no previous backups - // } - // string sGroup; - // if (0 == stats.MessagesThisFile ) - // { - // // first file has special pattern...since rolling doesn't occur when message - // // is logged, rather before next message is logged. - // if (stats.NumberOfFileRolls <= 1 ) - // { - // return null; - // } - // // Use backup files from previous round. The minus 2 is because we have already - // // rolled, and the first round uses null instead of the string - // sGroup = GetBackupGroup( sBackupGroups, stats.NumberOfFileRolls-2 ); - // } - // else - // { - // sGroup = GetBackupGroup( sBackupGroups, stats.NumberOfFileRolls-1 ); - // } - // return MakeBackupFileEntriesFromBackupGroup( sGroup, stats.MaximumFileSize ); - //} - - /// - /// Builds a collection of file entries based on the file names - /// specified in a groups string and the max file size from the - /// stats object - /// - /// - /// - /// - private static RollFileEntry[] MakeBackupFileEntriesForPostCondition(string sBackupGroups, RollingStats stats) - { - if (0 == stats.NumberOfFileRolls) - { - return null; // first round has no previous backups - } - string sGroup = GetBackupGroup(sBackupGroups, stats.NumberOfFileRolls - 1); - return MakeBackupFileEntriesFromBackupGroup(sGroup, stats.MaximumFileSize); - } - - - /// - /// This class holds information that is used while we are generating - /// test data sets - /// - public class RollingStats - { - private int iTotalMessageLength; - private int iMessagesPerFile; - private int iMessagesThisFile; - private int iNumberOfFileRolls; - - /// - /// Number of total bytes a log file can reach. - /// - public int MaximumFileSize - { - get { return TotalMessageLength * MessagesPerFile; } - } - - /// - /// The length of a message, including any CR/LF characters. - /// This length assumes all messages are a fixed length for - /// test purposes. - /// - public int TotalMessageLength - { - get { return iTotalMessageLength; } - set { iTotalMessageLength = value; } - } - - /// - /// A count of the number of messages that are logged to each - /// file. - /// - public int MessagesPerFile - { - get { return iMessagesPerFile; } - set { iMessagesPerFile = value; } - } - - /// - /// Counts how many messages have been logged to the current file - /// - public int MessagesThisFile - { - get { return iMessagesThisFile; } - set { iMessagesThisFile = value; } - } - - /// - /// Counts how many times a file roll has occurred - /// - public int NumberOfFileRolls - { - get { return iNumberOfFileRolls; } - set { iNumberOfFileRolls = value; } - } - } - - /// - /// The stats are used to keep track of progress while we are algorithmically - /// generating a table of pre/post condition tests for file rolling. - /// - /// - /// - private static RollingStats InitializeStats(string sTestMessage) - { - RollingStats rollingStats = new RollingStats(); - - rollingStats.TotalMessageLength = TotalMessageLength(sTestMessage); - rollingStats.MessagesPerFile = MessagesPerFile(rollingStats.TotalMessageLength); - rollingStats.MessagesThisFile = 0; - rollingStats.NumberOfFileRolls = 0; - - return rollingStats; - } - - /// - /// Takes an existing array of RollFileEntry objects, creates a new array one element - /// bigger, and appends the final element to the end. If the existing entries are - /// null (no entries), then a one-element array is returned with the final element - /// as the only entry. - /// - /// - /// - /// - private static RollFileEntry[] AddFinalElement(RollFileEntry[] existing, RollFileEntry final) - { - int iLength = 1; - if (null != existing) - { - iLength += existing.Length; - } - RollFileEntry[] combined = new RollFileEntry[iLength]; - if (null != existing) - { - Array.Copy(existing, 0, combined, 0, existing.Length); - } - combined[iLength - 1] = final; - return combined; - } - - /// - /// Generates the pre and post condition arrays from an array of backup files and the - /// current file / next file. - /// - /// - /// - /// - /// - /// - /// - private static RollConditions BuildTableEntry(string sBackupFiles, RollConditions preCondition, RollFileEntry current, RollFileEntry currentNext, RollingStats rollingStats) - { - RollFileEntry[] backupsPost = MakeBackupFileEntriesForPostCondition(sBackupFiles, rollingStats); - RollFileEntry[] post = AddFinalElement(backupsPost, currentNext); - if (null == preCondition) - { - return new RollConditions(AddFinalElement(null, current), post); - } - return new RollConditions(preCondition.GetPostLogFileEntries(), post); - } - - /// - /// Returns a RollFileEntry that represents the next state of the current file, - /// based on the current state. When the current state would roll, the next - /// entry is the current file wrapped to 0 bytes. Otherwise, the next state - /// is the post-condition passed in as the currentNext parameter - /// - /// - /// - /// - private static RollFileEntry MoveNextEntry(RollingStats rollingStats, RollFileEntry currentNext) - { - rollingStats.MessagesThisFile = rollingStats.MessagesThisFile + 1; - if (rollingStats.MessagesThisFile >= rollingStats.MessagesPerFile) - { - rollingStats.MessagesThisFile = 0; - rollingStats.NumberOfFileRolls = rollingStats.NumberOfFileRolls + 1; - - return new RollFileEntry(GetCurrentFile(), 0); - } - else - { - return currentNext; - } - } - - /// - /// Callback point for the regular expression parser. Turns - /// the number into a file name. - /// - /// - /// - private static string NumberedNameMaker(Match match) - { - Int32 iValue = Int32.Parse(match.Value); - return MakeFileName(c_fileName, iValue); - } - - /// - /// Parses a numeric list of files, turning them into file names. - /// Calls back to a method that does the actual replacement, turning - /// the numeric value into a filename. - /// - /// - /// - /// - private static string ConvertToFiles(string sBackupInfo, MatchEvaluator evaluator) - { - Regex regex = new Regex(@"\d+"); - return regex.Replace(sBackupInfo, evaluator); - } - - /// - /// Makes test entries used for verifying counted file names - /// - /// A message to log repeatedly - /// Filename groups used to indicate backup file name progression - /// that results after each message is logged - /// How many times the test message will be repeatedly logged - /// - private static RollConditions[] MakeNumericTestEntries(string sTestMessage, string sBackupInfo, int iMessagesToLog) - { - return MakeTestEntries( - sTestMessage, - sBackupInfo, - iMessagesToLog, - new MatchEvaluator(NumberedNameMaker)); - } - - /// - /// This routine takes a list of backup file names and a message that will be logged - /// repeatedly, and generates a collection of objects containing pre-condition and - /// post-condition information. This pre/post information shows the names and expected - /// file sizes for all files just before and just after a message is logged. - /// - /// A message to log repeatedly - /// Filename groups used to indicate backup file name progression - /// that results after each message is logged - /// How many times the test message will be repeatedly logged - /// Function that can turn a number into a filename - /// - private static RollConditions[] MakeTestEntries(string sTestMessage, string sBackupInfo, int iMessagesToLog, MatchEvaluator evaluator) - { - string sBackupFiles = ConvertToFiles(sBackupInfo, evaluator); - - RollConditions[] table = new RollConditions[iMessagesToLog]; - - RollingStats rollingStats = InitializeStats(sTestMessage); - - RollConditions preCondition = null; - rollingStats.MessagesThisFile = 0; - - RollFileEntry currentFile = new RollFileEntry(GetCurrentFile(), 0); - for(int i = 0; i < iMessagesToLog; i++) - { - RollFileEntry currentNext = new RollFileEntry( - GetCurrentFile(), - (1 + rollingStats.MessagesThisFile) * rollingStats.TotalMessageLength); - - table[i] = BuildTableEntry(sBackupFiles, preCondition, currentFile, currentNext, rollingStats); - preCondition = table[i]; - - //System.Diagnostics.Debug.WriteLine( "Message " + i ); - //DumpTableEntry( table[i] ); - - currentFile = MoveNextEntry(rollingStats, currentNext); - } - - return table; - } - - /// - /// Uses the externally defined rolling table to verify rolling names/sizes - /// - /// - /// Pattern is: check pre-conditions. Log messages, checking size of current file. - /// when size exceeds limit, check post conditions. Can determine from message the - /// number of messages N that will cause a roll to occur. Challenge is to verify the - /// expected files, their sizes, and the names. For a message of length L, the backups - /// will be of size (N * L), and the current file will be of size (K * L), where K is - /// the number of messages that have been logged to this file. - /// - /// File sizes can be checked algorithmically. - /// - /// File names are generated using a table driven algorithm, where a number is turned into - /// the actual filename. - /// - /// The entries are comma-separated, with spaces between the names. Each comma indicates - /// a 'roll', and the group between commas indicates the numbers for all backup files that - /// occur as a result of the roll. It is assumed that no backup files exist before a roll - /// occurs - /// - /// - private void VerifyRolling(RollConditions[] table) - { - ConfigureRootAppender(); - RollFromTableEntries(c_fileName, table, GetTestMessage()); - } - - /// - /// Validates rolling using a fixed number of backup files, with - /// count direction set to up, so that newer files have higher counts. - /// Newest = N, Oldest = N-K, where K is the number of backups to allow - /// and N is the number of times rolling has occurred. - /// - [Test] - public void TestRollingCountUpFixedBackups() - { - // - // Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the - // oldest, and 3 is the newest - // - string sBackupInfo = "1, 1 2, 1 2 3, 2 3 4, 3 4 5"; - - // - // Count Up - // - _iCountDirection = +1; - - // - // Log 30 messages. This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500 - // bytes for current file as messages are logged. - // - int iMessagesToLog = 30; - - VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog)); - } - - /// - /// Validates rolling using an infinite number of backup files, with - /// count direction set to up, so that newer files have higher counts. - /// Newest = N, Oldest = 1, where N is the number of times rolling has - /// occurred. - /// - [Test] - public void TestRollingCountUpInfiniteBackups() - { - // - // Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the - // oldest, and 3 is the newest - // - string sBackupInfo = "1, 1 2, 1 2 3, 1 2 3 4, 1 2 3 4 5"; - - // - // Count Up - // - _iCountDirection = +1; - - // - // Infinite backups - // - _MaxSizeRollBackups = -1; - - // - // Log 30 messages. This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500 - // bytes for current file as messages are logged. - // - int iMessagesToLog = 30; - - VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog)); - } - - /// - /// Validates rolling with no backup files, with count direction set to up. - /// Only the current file should be present, wrapping to 0 bytes once the - /// previous file fills up. - /// - [Test] - public void TestRollingCountUpZeroBackups() - { - // - // Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the - // oldest, and 3 is the newest - // - string sBackupInfo = ", , , , "; - - // - // Count Up - // - _iCountDirection = +1; - - // - // No backups - // - _MaxSizeRollBackups = 0; - - // - // Log 30 messages. This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500 - // bytes for current file as messages are logged. - // - int iMessagesToLog = 30; - - VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog)); - } - - - /// - /// Validates rolling using a fixed number of backup files, with - /// count direction set to down, so that older files have higher counts. - /// Newest = 1, Oldest = N, where N is the number of backups to allow - /// - [Test] - public void TestRollingCountDownFixedBackups() - { - // - // Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the - // oldest, and 3 is the newest - // - string sBackupInfo = "1, 1 2, 1 2 3, 1 2 3, 1 2 3"; - - // - // Count Up - // - _iCountDirection = -1; - - // - // Log 30 messages. This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500 - // bytes for current file as messages are logged. - // - int iMessagesToLog = 30; - - VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog)); - } - - /// - /// Validates rolling using an infinite number of backup files, with - /// count direction set to down, so that older files have higher counts. - /// Newest = 1, Oldest = N, where N is the number of times rolling has - /// occurred - /// - [Test] - public void TestRollingCountDownInfiniteBackups() - { - // - // Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the - // oldest, and 3 is the newest - // - string sBackupInfo = "1, 1 2, 1 2 3, 1 2 3 4, 1 2 3 4 5"; - - // - // Count Down - // - _iCountDirection = -1; - - // - // Infinite backups - // - _MaxSizeRollBackups = -1; - - // - // Log 30 messages. This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500 - // bytes for current file as messages are logged. - // - int iMessagesToLog = 30; - - VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog)); - } - - /// - /// Validates rolling with no backup files, with count direction set to down. - /// Only the current file should be present, wrapping to 0 bytes once the - /// previous file fills up. - /// - [Test] - public void TestRollingCountDownZeroBackups() - { - // - // Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the - // oldest, and 3 is the newest - // - string sBackupInfo = ", , , , "; - - // - // Count Up - // - _iCountDirection = -1; - - // - // No backups - // - _MaxSizeRollBackups = 0; - - // - // Log 30 messages. This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500 - // bytes for current file as messages are logged. - // - int iMessagesToLog = 30; - - VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog)); - } - - /// - /// Configures the root appender for counting and rolling - /// - private void ConfigureRootAppender() - { - _root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root; - _root.Level = Level.Debug; - _caRoot = new CountingAppender(); - _root.AddAppender(_caRoot); - Assert.AreEqual(_caRoot.Counter, 0); - - // - // Set the root appender with a RollingFileAppender - // - _root.AddAppender(CreateAppender()); - - _root.Repository.Configured = true; - } - - /// - /// Verifies that the current backup index is detected correctly when initializing - /// - /// - /// - /// - private static void VerifyInitializeRollBackupsFromBaseFile(string sBaseFile, ArrayList alFiles, int iExpectedCurSizeRollBackups) - { - InitializeAndVerifyExpectedValue(alFiles, sBaseFile, CreateRollingFileAppender("5,0,1"), iExpectedCurSizeRollBackups); - } - - /// - /// Tests that the current backup index is 0 when no - /// existing files are seen - /// - [Test] - public void TestInitializeRollBackups1() - { - string sBaseFile = "LogFile.log"; - ArrayList arrFiles = new ArrayList(); - arrFiles.Add("junk1"); - arrFiles.Add("junk1.log"); - arrFiles.Add("junk2.log"); - arrFiles.Add("junk.log.1"); - arrFiles.Add("junk.log.2"); - - int iExpectedCurSizeRollBackups = 0; - VerifyInitializeRollBackupsFromBaseFile(sBaseFile, arrFiles, iExpectedCurSizeRollBackups); - } - - /// - /// Verifies that files are detected when the base file is specified - /// - /// - private static void VerifyInitializeRollBackupsFromBaseFile(string sBaseFile) - { - ArrayList alFiles = MakeTestDataFromString(sBaseFile, "0,1,2"); - - int iExpectedCurSizeRollBackups = 2; - VerifyInitializeRollBackupsFromBaseFile(sBaseFile, alFiles, iExpectedCurSizeRollBackups); - } - - /// - /// Verifies that count goes to the highest when counting up - /// - [Test] - public void TestInitializeCountUpFixed() - { - ArrayList alFiles = MakeTestDataFromString("3,4,5"); - int iExpectedValue = 5; - InitializeAndVerifyExpectedValue(alFiles, c_fileName, CreateRollingFileAppender("3,0,1"), iExpectedValue); - } - - /// - /// Verifies that count goes to the highest when counting up - /// - [Test] - public void TestInitializeCountUpFixed2() - { - ArrayList alFiles = MakeTestDataFromString("0,3"); - int iExpectedValue = 3; - InitializeAndVerifyExpectedValue(alFiles, c_fileName, CreateRollingFileAppender("3,0,1"), iExpectedValue); - } - - /// - /// Verifies that count stays at 0 for the zero backups case - /// when counting up - /// - [Test] - public void TestInitializeCountUpZeroBackups() - { - ArrayList alFiles = MakeTestDataFromString("0,3"); - int iExpectedValue = 0; - InitializeAndVerifyExpectedValue(alFiles, c_fileName, CreateRollingFileAppender("0,0,1"), iExpectedValue); - } - - /// - /// Verifies that count stays at 0 for the zero backups case - /// when counting down - /// - [Test] - public void TestInitializeCountDownZeroBackups() - { - ArrayList alFiles = MakeTestDataFromString("0,3"); - int iExpectedValue = 0; - InitializeAndVerifyExpectedValue(alFiles, c_fileName, CreateRollingFileAppender("0,0,-1"), iExpectedValue); - } - - - /// - /// Verifies that count goes to the highest when counting up - /// - [Test] - public void TestInitializeCountDownFixed() - { - ArrayList alFiles = MakeTestDataFromString("4,5,6"); - VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 0); - } - - /// - /// Verifies that count goes to the highest when counting up - /// - [Test] - public void TestInitializeCountDownFixed2() - { - ArrayList alFiles = MakeTestDataFromString("1,5,6"); - VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 1); - } - - /// - /// Verifies that count goes to the highest when counting up - /// - [Test] - public void TestInitializeCountDownFixed3() - { - ArrayList alFiles = MakeTestDataFromString("2,5,6"); - VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 2); - } - - /// - /// Verifies that count goes to the highest when counting up - /// - [Test] - public void TestInitializeCountDownFixed4() - { - ArrayList alFiles = MakeTestDataFromString("3,5,6"); - VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 3); - } - - /// - /// Verifies that count goes to the highest when counting up - /// - [Test] - public void TestInitializeCountDownFixed5() - { - ArrayList alFiles = MakeTestDataFromString("1,2,3"); - VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 3); - } - - /// - /// Verifies that count goes to the highest when counting up - /// - [Test] - public void TestInitializeCountDownFixed6() - { - ArrayList alFiles = MakeTestDataFromString("1,2"); - VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 2); - } - - /// - /// Verifies that count goes to the highest when counting up - /// - [Test] - public void TestInitializeCountDownFixed7() - { - ArrayList alFiles = MakeTestDataFromString("2,3"); - VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 3); - } - - private static void InitializeAndVerifyExpectedValue(ArrayList alFiles, string sBaseFile, RollingFileAppender rfa, int iExpectedValue) - { - InitializeRollBackups(rfa, sBaseFile, alFiles); - Assert.AreEqual(iExpectedValue, GetFieldCurSizeRollBackups(rfa)); - } - - /// - /// Tests the count down case, with infinite max backups, to see that - /// initialization of the rolling file appender results in the expected value - /// - /// - /// - /// - private static void VerifyInitializeDownInfiniteExpectedValue(ArrayList alFiles, string sBaseFile, int iExpectedValue) - { - InitializeAndVerifyExpectedValue(alFiles, sBaseFile, CreateRollingFileAppender("-1,0,-1"), iExpectedValue); - } - - /// - /// Creates a RollingFileAppender with the desired values, where the - /// values are passed as a comma separated string, with 3 parameters, - /// m_maxSizeRollBackups, m_curSizeRollBackups, CountDirection - /// - /// - /// - private static RollingFileAppender CreateRollingFileAppender(string sParams) - { - string[] asParams = sParams.Split(','); - if (null == asParams || asParams.Length != 3) - { - throw new ArgumentOutOfRangeException(sParams, sParams, "Must have 3 comma separated params: MaxSizeRollBackups, CurSizeRollBackups, CountDirection"); - } - - RollingFileAppender rfa = new RollingFileAppender(); - rfa.RollingStyle = RollingFileAppender.RollingMode.Size; - SetFieldMaxSizeRollBackups(rfa, Int32.Parse(asParams[0].Trim())); - SetFieldCurSizeRollBackups(rfa, Int32.Parse(asParams[1].Trim())); - rfa.CountDirection = Int32.Parse(asParams[2].Trim()); - - return rfa; - } - - /// - /// Verifies that count goes to the highest when counting down - /// and infinite backups are selected - /// - [Test] - public void TestInitializeCountDownInfinite() - { - ArrayList alFiles = MakeTestDataFromString("2,3"); - VerifyInitializeDownInfiniteExpectedValue(alFiles, c_fileName, 3); - } - - /// - /// Verifies that count goes to the highest when counting down - /// and infinite backups are selected - /// - [Test] - public void TestInitializeCountDownInfinite2() - { - ArrayList alFiles = MakeTestDataFromString("2,3,4,5,6,7,8,9,10"); - VerifyInitializeDownInfiniteExpectedValue(alFiles, c_fileName, 10); - } - - /// - /// Verifies that count goes to the highest when counting down - /// and infinite backups are selected - /// - [Test] - public void TestInitializeCountDownInfinite3() - { - ArrayList alFiles = MakeTestDataFromString("9,10,3,4,5,7,9,6,1,2,8"); - VerifyInitializeDownInfiniteExpectedValue(alFiles, c_fileName, 10); - } - - /// - /// Verifies that count goes to the highest when counting up - /// and infinite backups are selected - /// - [Test] - public void TestInitializeCountUpInfinite() - { - ArrayList alFiles = MakeTestDataFromString("2,3"); - VerifyInitializeUpInfiniteExpectedValue(alFiles, c_fileName, 3); - } - - /// - /// Verifies that count goes to the highest when counting up - /// and infinite backups are selected - /// - [Test] - public void TestInitializeCountUpInfinite2() - { - ArrayList alFiles = MakeTestDataFromString("2,3,4,5,6,7,8,9,10"); - VerifyInitializeUpInfiniteExpectedValue(alFiles, c_fileName, 10); - } - - /// - /// Verifies that count goes to the highest when counting up - /// and infinite backups are selected - /// - [Test] - public void TestInitializeCountUpInfinite3() - { - ArrayList alFiles = MakeTestDataFromString("9,10,3,4,5,7,9,6,1,2,8"); - VerifyInitializeUpInfiniteExpectedValue(alFiles, c_fileName, 10); - } - - /// - /// Creates a logger hierarchy, configures a rolling file appender and returns an ILogger - /// - /// The filename to log to - /// The locking model to use. - /// The error handler to use. - /// A configured ILogger - private static ILogger CreateLogger(string filename, FileAppender.LockingModelBase lockModel, IErrorHandler handler) - { - Repository.Hierarchy.Hierarchy h = (Repository.Hierarchy.Hierarchy)LogManager.CreateRepository("TestRepository"); - - RollingFileAppender appender = new RollingFileAppender(); - appender.File = filename; - appender.AppendToFile = false; - appender.CountDirection = 0; - appender.RollingStyle = RollingFileAppender.RollingMode.Size; - appender.MaxFileSize = 100000; - appender.Encoding = Encoding.ASCII; - appender.ErrorHandler = handler; - if (lockModel != null) - { - appender.LockingModel = lockModel; - } - - PatternLayout layout = new PatternLayout(); - layout.ConversionPattern = "%m%n"; - layout.ActivateOptions(); - - appender.Layout = layout; - appender.ActivateOptions(); - - h.Root.AddAppender(appender); - h.Configured = true; - - ILogger log = h.GetLogger("Logger"); - return log; - } - - /// - /// Destroys the logger hierarchy created by - /// - private static void DestroyLogger() - { - Repository.Hierarchy.Hierarchy h = (Repository.Hierarchy.Hierarchy)LogManager.GetRepository("TestRepository"); - h.ResetConfiguration(); - //Replace the repository selector so that we can recreate the hierarchy with the same name if necessary - LoggerManager.RepositorySelector = new DefaultRepositorySelector(typeof(log4net.Repository.Hierarchy.Hierarchy)); - } - - private static void AssertFileEquals(string filename, string contents) - { - StreamReader sr = new StreamReader(filename); - string logcont = sr.ReadToEnd(); - sr.Close(); - - Assert.AreEqual(contents, logcont, "Log contents is not what is expected"); - - File.Delete(filename); - } - - /// - /// Verifies that logging a message actually produces output - /// - [Test] - public void TestLogOutput() - { - String filename = "test.log"; - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.ExclusiveLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - - AssertFileEquals(filename, "This is a message" + Environment.NewLine + "This is a message 2" + Environment.NewLine); - Assert.AreEqual("", sh.Message, "Unexpected error message"); - } - - /// - /// Verifies that attempting to log to a locked file fails gracefully - /// - [Test] - public void TestExclusiveLockFails() - { - String filename = "test.log"; - - FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None); - fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4); - - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.ExclusiveLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - fs.Close(); - - AssertFileEquals(filename, "Test"); - Assert.AreEqual(sh.Message.Substring(0, 30), "Unable to acquire lock on file", "Expecting an error message"); - } - - /// - /// Verifies that attempting to log to a locked file recovers if the lock is released - /// - [Test] - public void TestExclusiveLockRecovers() - { - String filename = "test.log"; - - FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None); - fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4); - - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.ExclusiveLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - fs.Close(); - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - - AssertFileEquals(filename, "This is a message 2" + Environment.NewLine); - Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message"); - } - - /// - /// Verifies that attempting to log to a file with ExclusiveLock really locks the file - /// - [Test] - public void TestExclusiveLockLocks() - { - String filename = "test.log"; - bool locked = false; - - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.ExclusiveLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - - try - { - FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None); - fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4); - fs.Close(); - } - catch(IOException e1) - { -#if DOTNET - Assert.AreEqual("The process cannot access the file ", e1.Message.Substring(0, 35), "Unexpected exception"); -#else - Assert.AreEqual("Sharing violation on path ", e1.Message.Substring(0, 26), "Unexpected exception"); -#endif - locked = true; - } - - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - - Assert.IsTrue(locked, "File was not locked"); -#if !MONO || !FRAMEWORK_3_5_OR_ABOVE // at least on Linux with Mono 2.4 exclusive locking doesn't work as one would expect - AssertFileEquals(filename, "This is a message" + Environment.NewLine + "This is a message 2" + Environment.NewLine); -#endif - Assert.AreEqual("", sh.Message, "Unexpected error message"); - } - - - /// - /// Verifies that attempting to log to a locked file fails gracefully - /// - [Test] - public void TestMinimalLockFails() - { - String filename = "test.log"; - - FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None); - fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4); - - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.MinimalLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - fs.Close(); - - AssertFileEquals(filename, "Test"); - Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message"); - } - - /// - /// Verifies that attempting to log to a locked file recovers if the lock is released - /// - [Test] - public void TestMinimalLockRecovers() - { - String filename = "test.log"; - - FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None); - fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4); - - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.MinimalLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - fs.Close(); - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - - AssertFileEquals(filename, "This is a message 2" + Environment.NewLine); - Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message"); - } - - /// - /// Verifies that attempting to log to a file with MinimalLock doesn't lock the file - /// - [Test] - public void TestMinimalLockUnlocks() - { - String filename = "test.log"; - bool locked; - - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.MinimalLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - - locked = true; - FileStream fs = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None); - fs.Write(Encoding.ASCII.GetBytes("Test" + Environment.NewLine), 0, 4 + Environment.NewLine.Length); - fs.Close(); - - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - - Assert.IsTrue(locked, "File was not locked"); - AssertFileEquals(filename, "This is a message" + Environment.NewLine + "Test" + Environment.NewLine + "This is a message 2" + Environment.NewLine); - Assert.AreEqual("", sh.Message, "Unexpected error message"); - } - -#if !NETCF - /// - /// Verifies that attempting to log to a locked file fails gracefully - /// - [Test] - public void TestInterProcessLockFails() { - String filename = "test.log"; - - FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None); - fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4); - - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - fs.Close(); - - AssertFileEquals(filename, "Test"); - Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message"); - } - - /// - /// Verifies that attempting to log to a locked file recovers if the lock is released - /// - [Test] - public void TestInterProcessLockRecovers() { - String filename = "test.log"; - - FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None); - fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4); - - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - fs.Close(); - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - - AssertFileEquals(filename, "This is a message 2" + Environment.NewLine); - Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message"); - } - - /// - /// Verifies that attempting to log to a file with InterProcessLock really locks the file - /// - [Test] - public void TestInterProcessLockUnlocks() { - String filename = "test.log"; - bool locked; - - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh); - log.Log(GetType(), Level.Info, "This is a message", null); - - locked = true; - FileStream fs = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); - fs.Write(Encoding.ASCII.GetBytes("Test" + Environment.NewLine), 0, 4 + Environment.NewLine.Length); - fs.Close(); - - log.Log(GetType(), Level.Info, "This is a message 2", null); - DestroyLogger(); - - Assert.IsTrue(locked, "File was not locked"); - AssertFileEquals(filename, "This is a message" + Environment.NewLine + "Test" + Environment.NewLine + "This is a message 2" + Environment.NewLine); - Assert.AreEqual("", sh.Message, "Unexpected error message"); - } -#endif - - /// - /// Verify that the default LockModel is ExclusiveLock, to maintain backwards compatibility with previous behaviour - /// - [Test] - public void TestDefaultLockingModel() - { - String filename = "test.log"; - SilentErrorHandler sh = new SilentErrorHandler(); - ILogger log = CreateLogger(filename, null, sh); - - IAppender[] appenders = log.Repository.GetAppenders(); - Assert.AreEqual(1, appenders.Length, "The wrong number of appenders are configured"); - - RollingFileAppender rfa = (RollingFileAppender)(appenders[0]); - Assert.AreEqual(typeof(log4net.Appender.FileAppender.ExclusiveLock), rfa.LockingModel.GetType(), "The LockingModel is of an unexpected type"); - - DestroyLogger(); - } - - /// - /// Tests the count up case, with infinite max backups , to see that - /// initialization of the rolling file appender results in the expected value - /// - /// - /// - /// - private static void VerifyInitializeUpInfiniteExpectedValue(ArrayList alFiles, string sBaseFile, int iExpectedValue) - { - InitializeAndVerifyExpectedValue(alFiles, sBaseFile, CreateRollingFileAppender("-1,0,1"), iExpectedValue); - } - - - /// - /// Tests the count down case, with max backups limited to 3, to see that - /// initialization of the rolling file appender results in the expected value - /// - /// - /// - /// - private static void VerifyInitializeDownFixedExpectedValue(ArrayList alFiles, string sBaseFile, int iExpectedValue) - { - InitializeAndVerifyExpectedValue(alFiles, sBaseFile, CreateRollingFileAppender("3,0,-1"), iExpectedValue); - } - - /// - /// Turns a string of comma separated numbers into a collection of filenames - /// generated from the numbers. - /// - /// Defaults to filename in _fileName variable. - /// - /// - /// Comma separated list of numbers for counted file names - /// - private static ArrayList MakeTestDataFromString(string sFileNumbers) - { - return MakeTestDataFromString(c_fileName, sFileNumbers); - } - - /// - /// Turns a string of comma separated numbers into a collection of filenames - /// generated from the numbers - /// - /// Uses the input filename. - /// - /// Name of file to combine with numbers when generating counted file names - /// Comma separated list of numbers for counted file names - /// - private static ArrayList MakeTestDataFromString(string sFileName, string sFileNumbers) - { - ArrayList alFiles = new ArrayList(); - - string[] sNumbers = sFileNumbers.Split(','); - foreach(string sNumber in sNumbers) - { - Int32 iValue = Int32.Parse(sNumber.Trim()); - alFiles.Add(MakeFileName(sFileName, iValue)); - } - - return alFiles; - } - - /// - /// Tests that the current backup index is correctly detected - /// for a file with no extension - /// - [Test] - public void TestInitializeRollBackups2() - { - VerifyInitializeRollBackupsFromBaseFile("LogFile"); - } - - /// - /// Tests that the current backup index is correctly detected - /// for a file with a .log extension - /// - [Test] - public void TestInitializeRollBackups3() - { - VerifyInitializeRollBackupsFromBaseFile("LogFile.log"); - } - - /// - /// Makes sure that the initialization can detect the backup - /// number correctly. - /// - /// - /// - public void VerifyInitializeRollBackups(int iBackups, int iMaxSizeRollBackups) - { - string sBaseFile = "LogFile.log"; - ArrayList arrFiles = new ArrayList(); - arrFiles.Add("junk1"); - for(int i = 0; i < iBackups; i++) - { - arrFiles.Add(MakeFileName(sBaseFile, i)); - } - RollingFileAppender rfa = new RollingFileAppender(); - rfa.RollingStyle = RollingFileAppender.RollingMode.Size; - SetFieldMaxSizeRollBackups(rfa, iMaxSizeRollBackups); - SetFieldCurSizeRollBackups(rfa, 0); - InitializeRollBackups(rfa, sBaseFile, arrFiles); - - // iBackups / Meaning - // 0 = none - // 1 = file.log - // 2 = file.log.1 - // 3 = file.log.2 - if (0 == iBackups || - 1 == iBackups) - { - Assert.AreEqual(0, GetFieldCurSizeRollBackups(rfa)); - } - else - { - Assert.AreEqual(Math.Min(iBackups - 1, iMaxSizeRollBackups), GetFieldCurSizeRollBackups(rfa)); - } - } - - /// - /// Tests that the current backup index is correctly detected, - /// and gets no bigger than the max backups setting - /// - [Test] - public void TestInitializeRollBackups4() - { - const int iMaxRollBackups = 5; - VerifyInitializeRollBackups(0, iMaxRollBackups); - VerifyInitializeRollBackups(1, iMaxRollBackups); - VerifyInitializeRollBackups(2, iMaxRollBackups); - VerifyInitializeRollBackups(3, iMaxRollBackups); - VerifyInitializeRollBackups(4, iMaxRollBackups); - VerifyInitializeRollBackups(5, iMaxRollBackups); - VerifyInitializeRollBackups(6, iMaxRollBackups); - // Final we cap out at the max value - VerifyInitializeRollBackups(7, iMaxRollBackups); - VerifyInitializeRollBackups(8, iMaxRollBackups); - } - - /// - /// - /// - [Test, Ignore("Not Implemented: Want to test counted files limited up, to see that others are ?? ignored? deleted?")] - public void TestInitialization3() - { - } - - /// - /// - /// - [Test, Ignore("Not Implemented: Want to test counted files limited down, to see that others are ?? ignored? deleted?")] - public void TestInitialization4() - { - } - - /// - /// - /// - [Test, Ignore("Not Implemented: Want to test dated files with a limit, to see that others are ?? ignored? deleted?")] - public void TestInitialization5() - { - } - - /// - /// - /// - [Test, Ignore("Not Implemented: Want to test dated files with no limit, to see that others are ?? ignored? deleted?")] - public void TestInitialization6() - { - } - - /// - /// - /// - [Test, Ignore("Not Implemented: Want to test dated files with mixed dates existing, to see that other dates do not matter")] - public void TestInitialization7() - { - } - - - // - // Helper functions to dig into the appender - // - - private static ArrayList GetExistingFiles(string baseFilePath) - { - RollingFileAppender appender = new RollingFileAppender(); - appender.SecurityContext = NullSecurityContext.Instance; - - return (ArrayList)Utils.InvokeMethod(appender, "GetExistingFiles", baseFilePath); - } - - private static void InitializeRollBackups(RollingFileAppender appender, string baseFile, ArrayList arrayFiles) - { - Utils.InvokeMethod(appender, "InitializeRollBackups", baseFile, arrayFiles); - } - - private static int GetFieldCurSizeRollBackups(RollingFileAppender appender) - { - return (int)Utils.GetField(appender, "m_curSizeRollBackups"); - } - - private static void SetFieldCurSizeRollBackups(RollingFileAppender appender, int val) - { - Utils.SetField(appender, "m_curSizeRollBackups", val); - } - - private static void SetFieldMaxSizeRollBackups(RollingFileAppender appender, int val) - { - Utils.SetField(appender, "m_maxSizeRollBackups", val); - } - - private static string GetTestMessage() - { - switch (Environment.NewLine.Length) - { - case 2: - return c_testMessage98Chars; - - case 1: - return c_testMessage99Chars; - - default: - throw new Exception("Unexpected Environment.NewLine.Length"); - } - } - } - - [TestFixture] - public class RollingFileAppenderSubClassTest : RollingFileAppender - { - [Test] - public void TestComputeCheckPeriod() - { - RollingFileAppender rfa = new RollingFileAppender(); - - Assert.AreEqual(RollPoint.TopOfMinute, InvokeComputeCheckPeriod(rfa, ".yyyy-MM-dd HH:mm"), "TopOfMinute pattern"); - Assert.AreEqual(RollPoint.TopOfHour, InvokeComputeCheckPeriod(rfa, ".yyyy-MM-dd HH"), "TopOfHour pattern"); - Assert.AreEqual(RollPoint.HalfDay, InvokeComputeCheckPeriod(rfa, ".yyyy-MM-dd tt"), "HalfDay pattern"); - Assert.AreEqual(RollPoint.TopOfDay, InvokeComputeCheckPeriod(rfa, ".yyyy-MM-dd"), "TopOfDay pattern"); - Assert.AreEqual(RollPoint.TopOfMonth, InvokeComputeCheckPeriod(rfa, ".yyyy-MM"), "TopOfMonth pattern"); - - // Test invalid roll point - Assert.AreEqual(RollPoint.InvalidRollPoint, InvokeComputeCheckPeriod(rfa, "..."), "TopOfMonth pattern"); - } - - private static RollPoint InvokeComputeCheckPeriod(RollingFileAppender rollingFileAppender, string datePattern) - { - return (RollPoint)Utils.InvokeMethod(rollingFileAppender, "ComputeCheckPeriod", datePattern); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/StringAppender.cs b/src/log4net.Tests/Appender/StringAppender.cs deleted file mode 100644 index 977099c5..00000000 --- a/src/log4net.Tests/Appender/StringAppender.cs +++ /dev/null @@ -1,76 +0,0 @@ -#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.Text; - -using log4net.Appender; -using log4net.Core; - -namespace log4net.Tests.Appender -{ - /// - /// Write events to a string - /// - /// Nicko Cadell - public class StringAppender : AppenderSkeleton - { - private StringBuilder m_buf = new StringBuilder(); - - /// - /// Initializes a new instance of the class. - /// - public StringAppender() - { - } - - /// - /// Get the string logged so far - /// - /// - public string GetString() - { - return m_buf.ToString(); - } - - /// - /// Reset the string - /// - public void Reset() - { - m_buf.Length = 0; - } - - /// - /// - /// the event to log - protected override void Append(LoggingEvent loggingEvent) - { - m_buf.Append(RenderLoggingEvent(loggingEvent)); - } - - /// - /// This appender requires a to be set. - /// - /// true - protected override bool RequiresLayout - { - get { return true; } - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/TraceAppenderTest.cs b/src/log4net.Tests/Appender/TraceAppenderTest.cs deleted file mode 100644 index 306ac16c..00000000 --- a/src/log4net.Tests/Appender/TraceAppenderTest.cs +++ /dev/null @@ -1,110 +0,0 @@ -/* - * - * 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.Diagnostics; -using log4net.Appender; -using log4net.Config; -using log4net.Layout; -using log4net.Repository; -using NUnit.Framework; - -namespace log4net.Tests.Appender -{ - [TestFixture] - public class TraceAppenderTest - { - [Test] - public void DefaultCategoryTest() - { - CategoryTraceListener categoryTraceListener = new CategoryTraceListener(); - Trace.Listeners.Clear(); - Trace.Listeners.Add(categoryTraceListener); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - - TraceAppender traceAppender = new TraceAppender(); - traceAppender.Layout = new SimpleLayout(); - traceAppender.ActivateOptions(); - - BasicConfigurator.Configure(rep, traceAppender); - - ILog log = LogManager.GetLogger(rep.Name, GetType()); - log.Debug("Message"); - - Assert.AreEqual( - GetType().ToString(), - categoryTraceListener.Category); - } - - [Test] - public void MethodNameCategoryTest() - { - CategoryTraceListener categoryTraceListener = new CategoryTraceListener(); - Trace.Listeners.Clear(); - Trace.Listeners.Add(categoryTraceListener); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - - TraceAppender traceAppender = new TraceAppender(); - PatternLayout methodLayout = new PatternLayout("%method"); - methodLayout.ActivateOptions(); - traceAppender.Category = methodLayout; - traceAppender.Layout = new SimpleLayout(); - traceAppender.ActivateOptions(); - - BasicConfigurator.Configure(rep, traceAppender); - - ILog log = LogManager.GetLogger(rep.Name, GetType()); - log.Debug("Message"); - - Assert.AreEqual( - System.Reflection.MethodInfo.GetCurrentMethod().Name, - categoryTraceListener.Category); - } - } - - public class CategoryTraceListener : TraceListener - { - private string lastCategory; - - public override void Write(string message) - { - // empty - } - - public override void WriteLine(string message) - { - Write(message); - } - - public override void Write(string message, string category) - { - lastCategory = category; - base.Write(message, category); - } - - public string Category - { - get { return lastCategory; } - } - } -} diff --git a/src/log4net.Tests/AssemblyInfo.cs b/src/log4net.Tests/AssemblyInfo.cs deleted file mode 100644 index f8b2a458..00000000 --- a/src/log4net.Tests/AssemblyInfo.cs +++ /dev/null @@ -1,32 +0,0 @@ -#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.Reflection; -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// - -[assembly: AssemblyTitle("log4net.Tests")] -[assembly: AssemblyDescription("Unit Tests for log4net")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyProduct("log4net")] -[assembly: AssemblyDefaultAlias("log4net")] -[assembly: AssemblyCulture("")] \ No newline at end of file diff --git a/src/log4net.Tests/Context/LogicalThreadContextTest.cs b/src/log4net.Tests/Context/LogicalThreadContextTest.cs deleted file mode 100644 index 5ac0a240..00000000 --- a/src/log4net.Tests/Context/LogicalThreadContextTest.cs +++ /dev/null @@ -1,344 +0,0 @@ -#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 - -#if FRAMEWORK_4_5_OR_ABOVE -using System; -using System.Threading.Tasks; -using System.Linq; - -using log4net.Config; -using log4net.Layout; -using log4net.Repository; -using log4net.Tests.Appender; -using log4net.Util; - -using NUnit.Framework; - -namespace log4net.Tests.Context -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class LogicalThreadContextTest - { - [TearDown] - public void TearDown() - { - Utils.RemovePropertyFromAllContexts(); - } - - [Test] - public void TestLogicalThreadPropertiesPatternBasicGetSet() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogicalThreadPropertiesPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread properties value set"); - stringAppender.Reset(); - - LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = "val1"; - - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread properties value set"); - stringAppender.Reset(); - - LogicalThreadContext.Properties.Remove(Utils.PROPERTY_KEY); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread properties value removed"); - stringAppender.Reset(); - } - - [Test] - public async Task TestLogicalThreadPropertiesPatternAsyncAwait() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogicalThreadPropertiesPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set"); - stringAppender.Reset(); - - string testValueForCurrentContext = "Outer"; - LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = testValueForCurrentContext; - - log1.Info("TestMessage"); - Assert.AreEqual(testValueForCurrentContext, stringAppender.GetString(), "Test logical thread properties value set"); - stringAppender.Reset(); - - var strings = await Task.WhenAll(Enumerable.Range(0, 10).Select(x => SomeWorkProperties(x.ToString()))); - - // strings should be ["00AA0BB0", "01AA1BB1", "02AA2BB2", ...] - for (int i = 0; i < strings.Length; i++) - { - Assert.AreEqual(string.Format("{0}{1}AA{1}BB{1}", testValueForCurrentContext, i), strings[i], "Test logical thread properties expected sequence"); - } - - log1.Info("TestMessage"); - Assert.AreEqual(testValueForCurrentContext, stringAppender.GetString(), "Test logical thread properties value set"); - stringAppender.Reset(); - - LogicalThreadContext.Properties.Remove(Utils.PROPERTY_KEY); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread properties value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestLogicalThreadStackPattern() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set"); - stringAppender.Reset(); - - using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1")) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread stack value set"); - stringAppender.Reset(); - } - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestLogicalThreadStackPattern2() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set"); - stringAppender.Reset(); - - using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1")) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread stack value set"); - stringAppender.Reset(); - - using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val2")) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1 val2", stringAppender.GetString(), "Test logical thread stack value pushed 2nd val"); - stringAppender.Reset(); - } - } - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestLogicalThreadStackPatternNullVal() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set"); - stringAppender.Reset(); - - using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null)) - { - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value set"); - stringAppender.Reset(); - } - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestLogicalThreadStackPatternNullVal2() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set"); - stringAppender.Reset(); - - using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1")) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread stack value set"); - stringAppender.Reset(); - - using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null)) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1 ", stringAppender.GetString(), "Test logical thread stack value pushed null"); - stringAppender.Reset(); - } - } - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed"); - stringAppender.Reset(); - } - - [Test] - public async Task TestLogicalThreadStackPatternAsyncAwait() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogicalThreadStackPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set"); - stringAppender.Reset(); - - string testValueForCurrentContext = "Outer"; - string[] strings = null; - using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(testValueForCurrentContext)) - { - log1.Info("TestMessage"); - Assert.AreEqual(testValueForCurrentContext, stringAppender.GetString(), "Test logical thread stack value set"); - stringAppender.Reset(); - - strings = await Task.WhenAll(Enumerable.Range(0, 10).Select(x => SomeWorkStack(x.ToString()))); - } - - // strings should be ["Outer 0 AOuter 0 AOuter 0Outer 0 BOuter 0 B Outer 0", ...] - for (int i = 0; i < strings.Length; i++) - { - Assert.AreEqual(string.Format("{0} {1} A{0} {1} A{0} {1}{0} {1} B{0} {1} B{0} {1}", testValueForCurrentContext, i), strings[i], "Test logical thread properties expected sequence"); - } - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread properties value removed"); - stringAppender.Reset(); - } - - static async Task SomeWorkProperties(string propertyName) - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log = LogManager.GetLogger(rep.Name, "TestLogicalThreadStackPattern"); - log.Info("TestMessage"); - - // set a new one - LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = propertyName; - log.Info("TestMessage"); - - await MoreWorkProperties(log, "A"); - log.Info("TestMessage"); - await MoreWorkProperties(log, "B"); - log.Info("TestMessage"); - return stringAppender.GetString(); - } - - static async Task MoreWorkProperties(ILog log, string propertyName) - { - LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = propertyName; - log.Info("TestMessage"); - await Task.Delay(1); - log.Info("TestMessage"); - } - - static async Task SomeWorkStack(string stackName) - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log = LogManager.GetLogger(rep.Name, "TestLogicalThreadStackPattern"); - - using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(stackName)) - { - log.Info("TestMessage"); - Assert.AreEqual(string.Format("Outer {0}", stackName), stringAppender.GetString(), "Test logical thread stack value set"); - stringAppender.Reset(); - - await MoreWorkStack(log, "A"); - log.Info("TestMessage"); - await MoreWorkStack(log, "B"); - log.Info("TestMessage"); - } - - return stringAppender.GetString(); - } - - static async Task MoreWorkStack(ILog log, string stackName) - { - using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(stackName)) - { - log.Info("TestMessage"); - await Task.Delay(1); - log.Info("TestMessage"); - } - } - } -} -#endif diff --git a/src/log4net.Tests/Context/ThreadContextTest.cs b/src/log4net.Tests/Context/ThreadContextTest.cs deleted file mode 100644 index e489efc4..00000000 --- a/src/log4net.Tests/Context/ThreadContextTest.cs +++ /dev/null @@ -1,227 +0,0 @@ -#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 System.Threading; - -using log4net.Config; -using log4net.Layout; -using log4net.Repository; -using log4net.Tests.Appender; -using log4net.Util; - -using NUnit.Framework; - -namespace log4net.Tests.Context -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class ThreadContextTest - { - [TearDown] - public void TearDown() { - Utils.RemovePropertyFromAllContexts(); - } - - [Test] - public void TestThreadPropertiesPattern() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadProperiesPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread properties value set"); - stringAppender.Reset(); - - ThreadContext.Properties[Utils.PROPERTY_KEY] = "val1"; - - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test thread properties value set"); - stringAppender.Reset(); - - ThreadContext.Properties.Remove(Utils.PROPERTY_KEY); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread properties value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestThreadStackPattern() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set"); - stringAppender.Reset(); - - using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1")) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set"); - stringAppender.Reset(); - } - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestThreadStackPattern2() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set"); - stringAppender.Reset(); - - using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1")) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set"); - stringAppender.Reset(); - - using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val2")) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1 val2", stringAppender.GetString(), "Test thread stack value pushed 2nd val"); - stringAppender.Reset(); - } - } - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestThreadStackPatternNullVal() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set"); - stringAppender.Reset(); - - using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null)) - { - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value set"); - stringAppender.Reset(); - } - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestThreadStackPatternNullVal2() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set"); - stringAppender.Reset(); - - using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1")) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set"); - stringAppender.Reset(); - - using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null)) - { - log1.Info("TestMessage"); - Assert.AreEqual("val1 ", stringAppender.GetString(), "Test thread stack value pushed null"); - stringAppender.Reset(); - } - } - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed"); - stringAppender.Reset(); - } - - private static string TestBackgroundThreadContextPropertyRepository; - - [Test] - public void TestBackgroundThreadContextProperty() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%property{DateTimeTodayToString}"); - - ILoggerRepository rep = LogManager.CreateRepository(TestBackgroundThreadContextPropertyRepository = "TestBackgroundThreadContextPropertyRepository" + Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - Thread thread = new Thread(new ThreadStart(ExecuteBackgroundThread)); - thread.Start(); - - Thread.CurrentThread.Join(2000); - } - - private static void ExecuteBackgroundThread() - { - ILog log = LogManager.GetLogger(TestBackgroundThreadContextPropertyRepository, "ExecuteBackGroundThread"); - ThreadContext.Properties["DateTimeTodayToString"] = DateTime.Today.ToString(); - - log.Info("TestMessage"); - - Repository.Hierarchy.Hierarchy hierarchyLoggingRepository = (Repository.Hierarchy.Hierarchy)log.Logger.Repository; - StringAppender stringAppender = (StringAppender)hierarchyLoggingRepository.Root.Appenders[0]; - - Assert.AreEqual(DateTime.Today.ToString(), stringAppender.GetString()); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Core/EvaluatorTest.cs b/src/log4net.Tests/Core/EvaluatorTest.cs deleted file mode 100644 index 62626d24..00000000 --- a/src/log4net.Tests/Core/EvaluatorTest.cs +++ /dev/null @@ -1,142 +0,0 @@ -/* - * - * 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 log4net.Appender; -using log4net.Core; -using log4net.Tests.Appender; -using NUnit.Framework; - -namespace log4net.Tests.Core -{ - [TestFixture] - public class EvaluatorTest - { - private BufferingForwardingAppender m_bufferingForwardingAppender; - private CountingAppender m_countingAppender; - private Repository.Hierarchy.Hierarchy m_hierarchy; - - [SetUp] - public void SetupRepository() - { - m_hierarchy = new Repository.Hierarchy.Hierarchy(); - - m_countingAppender = new CountingAppender(); - m_countingAppender.ActivateOptions(); - - m_bufferingForwardingAppender = new BufferingForwardingAppender(); - m_bufferingForwardingAppender.AddAppender(m_countingAppender); - - m_bufferingForwardingAppender.BufferSize = 5; - m_bufferingForwardingAppender.ClearFilters(); - m_bufferingForwardingAppender.Fix = FixFlags.Partial; - m_bufferingForwardingAppender.Lossy = false; - m_bufferingForwardingAppender.LossyEvaluator = null; - m_bufferingForwardingAppender.Threshold = Level.All; - } - - [Test] - public void TestLevelEvaluator() - { - m_bufferingForwardingAppender.Evaluator = new LevelEvaluator(Level.Info); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestLevelEvaluator"); - - logger.Log(typeof(EvaluatorTest), Level.Debug, "Debug message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Debug, "Debug message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Info, "Info message logged", null); - Assert.AreEqual(3, m_countingAppender.Counter, "Test 3 events flushed on Info message."); - } - - [Test] - public void TestExceptionEvaluator() - { - m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(ApplicationException), true); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluator"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); - Assert.AreEqual(3, m_countingAppender.Counter, "Test 3 events flushed on ApplicationException message."); - } - - [Test] - public void TestExceptionEvaluatorTriggerOnSubClass() - { - m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(Exception), true); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluatorTriggerOnSubClass"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); - Assert.AreEqual(3, m_countingAppender.Counter, "Test 3 events flushed on ApplicationException message."); - } - - [Test] - public void TestExceptionEvaluatorNoTriggerOnSubClass() - { - m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(Exception), false); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluatorNoTriggerOnSubClass"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 3 events buffered"); - } - - [Test] - public void TestInvalidExceptionEvaluator() - { - // warning: String is not a subclass of Exception - m_bufferingForwardingAppender.Evaluator = new ExceptionEvaluator(typeof(String), false); - m_bufferingForwardingAppender.ActivateOptions(); - log4net.Config.BasicConfigurator.Configure(m_hierarchy, m_bufferingForwardingAppender); - - ILogger logger = m_hierarchy.GetLogger("TestExceptionEvaluatorNoTriggerOnSubClass"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", null); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 2 events buffered"); - - logger.Log(typeof(EvaluatorTest), Level.Warn, "Warn message logged", new ApplicationException()); - Assert.AreEqual(0, m_countingAppender.Counter, "Test 3 events buffered"); - } - } -} diff --git a/src/log4net.Tests/Core/FixingTest.cs b/src/log4net.Tests/Core/FixingTest.cs deleted file mode 100644 index 5415f023..00000000 --- a/src/log4net.Tests/Core/FixingTest.cs +++ /dev/null @@ -1,151 +0,0 @@ -#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 System.Threading; - -using log4net.Core; - -using NUnit.Framework; - -namespace log4net.Tests.Core -{ - /// - /// - [TestFixture] - public class FixingTest - { - const string TEST_REPOSITORY = "Test Repository"; - - [TestFixtureSetUp] - public void CreateRepository() - { - bool exists = false; - Repository.ILoggerRepository[] repositories = LogManager.GetAllRepositories(); - if (repositories != null) { - foreach (Repository.ILoggerRepository r in repositories) { - if (r.Name == TEST_REPOSITORY) { - exists = true; - break; - } - } - } - if (!exists) { - LogManager.CreateRepository(TEST_REPOSITORY); - } - - // write-once - if (Thread.CurrentThread.Name == null) - { - Thread.CurrentThread.Name = "Log4Net Test thread"; - } - } - - [Test] - public void TestUnfixedValues() - { - LoggingEventData loggingEventData = BuildStandardEventData(); - - // LoggingEvents occur at distinct points in time - LoggingEvent loggingEvent = new LoggingEvent( - loggingEventData.LocationInfo.GetType(), - LogManager.GetRepository(TEST_REPOSITORY), - loggingEventData.LoggerName, - loggingEventData.Level, - loggingEventData.Message, - new Exception("This is the exception")); - - AssertExpectedLoggingEvent(loggingEvent, loggingEventData); - - Assert.AreEqual(FixFlags.None, loggingEvent.Fix, "Fixed Fields is incorrect"); - } - - [Test] - public void TestAllFixedValues() - { - LoggingEventData loggingEventData = BuildStandardEventData(); - - // LoggingEvents occur at distinct points in time - LoggingEvent loggingEvent = new LoggingEvent( - loggingEventData.LocationInfo.GetType(), - LogManager.GetRepository(TEST_REPOSITORY), - loggingEventData.LoggerName, - loggingEventData.Level, - loggingEventData.Message, - new Exception("This is the exception")); - - AssertExpectedLoggingEvent(loggingEvent, loggingEventData); - - loggingEvent.Fix = FixFlags.All; - - Assert.AreEqual(FixFlags.LocationInfo | FixFlags.UserName | FixFlags.Identity | FixFlags.Partial | FixFlags.Message | FixFlags.ThreadName | FixFlags.Exception | FixFlags.Domain | FixFlags.Properties, loggingEvent.Fix, "Fixed Fields is incorrect"); - } - - [Test] - public void TestNoFixedValues() - { - LoggingEventData loggingEventData = BuildStandardEventData(); - - // LoggingEvents occur at distinct points in time - LoggingEvent loggingEvent = new LoggingEvent( - loggingEventData.LocationInfo.GetType(), - LogManager.GetRepository(TEST_REPOSITORY), - loggingEventData.LoggerName, - loggingEventData.Level, - loggingEventData.Message, - new Exception("This is the exception")); - - AssertExpectedLoggingEvent(loggingEvent, loggingEventData); - - loggingEvent.Fix = FixFlags.None; - - Assert.AreEqual(FixFlags.None, loggingEvent.Fix, "Fixed Fields is incorrect"); - } - - private static LoggingEventData BuildStandardEventData() - { - LoggingEventData loggingEventData = new LoggingEventData(); - loggingEventData.LoggerName = typeof(FixingTest).FullName; - loggingEventData.Level = Level.Warn; - loggingEventData.Message = "Logging event works"; - loggingEventData.Domain = "ReallySimpleApp"; - loggingEventData.LocationInfo = new LocationInfo(typeof(FixingTest).Name, "Main", "Class1.cs", "29"); //Completely arbitary - loggingEventData.ThreadName = Thread.CurrentThread.Name; - loggingEventData.TimeStamp = DateTime.Today; - loggingEventData.ExceptionString = "Exception occured here"; - loggingEventData.UserName = "TestUser"; - return loggingEventData; - } - - private static void AssertExpectedLoggingEvent(LoggingEvent loggingEvent, LoggingEventData loggingEventData) - { - Assert.AreEqual("ReallySimpleApp", loggingEventData.Domain, "Domain is incorrect"); - Assert.AreEqual("System.Exception: This is the exception", loggingEvent.GetExceptionString(), "Exception is incorrect"); - Assert.AreEqual(null, loggingEventData.Identity, "Identity is incorrect"); - Assert.AreEqual(Level.Warn, loggingEventData.Level, "Level is incorrect"); - Assert.AreEqual("get_LocationInformation", loggingEvent.LocationInformation.MethodName, "Location Info is incorrect"); - Assert.AreEqual("log4net.Tests.Core.FixingTest", loggingEventData.LoggerName, "LoggerName is incorrect"); - Assert.AreEqual(LogManager.GetRepository(TEST_REPOSITORY), loggingEvent.Repository, "Repository is incorrect"); - Assert.AreEqual(Thread.CurrentThread.Name, loggingEventData.ThreadName, "ThreadName is incorrect"); - Assert.IsNotNull(loggingEventData.TimeStamp, "TimeStamp is incorrect"); - Assert.AreEqual("TestUser", loggingEventData.UserName, "UserName is incorrect"); - Assert.AreEqual("Logging event works", loggingEvent.RenderedMessage, "Message is incorrect"); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Core/ShutdownTest.cs b/src/log4net.Tests/Core/ShutdownTest.cs deleted file mode 100644 index 720a321b..00000000 --- a/src/log4net.Tests/Core/ShutdownTest.cs +++ /dev/null @@ -1,73 +0,0 @@ -#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.Config; -using log4net.Layout; -using log4net.Repository; -using log4net.Tests.Appender; - -using NUnit.Framework; - -namespace log4net.Tests.Core -{ - /// - /// - [TestFixture] - public class ShutdownTest - { - /// - /// Test that a repository can be shutdown and reconfigured - /// - [Test] - public void TestShutdownAndReconfigure() - { - // Create unique repository - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - - // Create appender and configure repos - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%m"); - BasicConfigurator.Configure(rep, stringAppender); - - // Get logger from repos - ILog log1 = LogManager.GetLogger(rep.Name, "logger1"); - - log1.Info("TestMessage1"); - Assert.AreEqual("TestMessage1", stringAppender.GetString(), "Test logging configured"); - stringAppender.Reset(); - - rep.Shutdown(); - - log1.Info("TestMessage2"); - Assert.AreEqual("", stringAppender.GetString(), "Test not logging while shutdown"); - stringAppender.Reset(); - - // Create new appender and configure - stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%m"); - BasicConfigurator.Configure(rep, stringAppender); - - log1.Info("TestMessage3"); - Assert.AreEqual("TestMessage3", stringAppender.GetString(), "Test logging re-configured"); - stringAppender.Reset(); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Core/StringFormatTest.cs b/src/log4net.Tests/Core/StringFormatTest.cs deleted file mode 100644 index e7b0d939..00000000 --- a/src/log4net.Tests/Core/StringFormatTest.cs +++ /dev/null @@ -1,709 +0,0 @@ -#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 System.Globalization; - -using log4net.Config; -using log4net.Core; -using log4net.Layout; -using log4net.Repository; -using log4net.Tests.Appender; -using log4net.Tests.Layout; - -using NUnit.Framework; - -namespace log4net.Tests.Core -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class StringFormatTest - { - private CultureInfo _currentCulture; - private CultureInfo _currentUICulture; - - [SetUp] - public void SetUp() - { - // set correct thread culture - _currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture; - _currentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture; - System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; - } - - [TearDown] - public void TearDown() - { - // restore previous culture - System.Threading.Thread.CurrentThread.CurrentCulture = _currentCulture; - System.Threading.Thread.CurrentThread.CurrentUICulture = _currentUICulture; - } - - [Test] - public void TestFormatString() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestFormatString"); - - // *** - log1.Info("TestMessage"); - Assert.AreEqual("TestMessage", stringAppender.GetString(), "Test simple INFO event"); - stringAppender.Reset(); - - - // *** - log1.DebugFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted DEBUG event"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted INFO event"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted WARN event"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted ERROR event"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("Before {0} After", "Middle"); - Assert.AreEqual("Before Middle After", stringAppender.GetString(), "Test simple formatted FATAL event"); - stringAppender.Reset(); - - - // *** - log1.InfoFormat("Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("Before Middle After End", stringAppender.GetString(), "Test simple formatted INFO event 2"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("IGNORE THIS WARNING - EXCEPTION EXPECTED Before {0} After {1} {2}", "Middle", "End"); - Assert.AreEqual(STRING_FORMAT_ERROR, stringAppender.GetString(), "Test formatting error"); - stringAppender.Reset(); - } - - private const string STRING_FORMAT_ERROR = "Exception during StringFormat: Index (zero based) must be greater than or equal to zero and less than the size of the argument list. IGNORE THIS WARNING - EXCEPTION EXPECTED Before {0} After {1} {2}{Middle, End}"; - - - [Test] - public void TestLogFormatApi_Debug() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Debug"); - - // *** - log1.Debug("TestMessage"); - Assert.AreEqual("DEBUG:TestMessage", stringAppender.GetString(), "Test simple DEBUG event 1"); - stringAppender.Reset(); - - // *** - log1.Debug("TestMessage", null); - Assert.AreEqual("DEBUG:TestMessage", stringAppender.GetString(), "Test simple DEBUG event 2"); - stringAppender.Reset(); - - // *** - log1.Debug("TestMessage", new Exception("Exception message")); - Assert.AreEqual("DEBUG:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple DEBUG event 3"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}", "1"); - Assert.AreEqual("DEBUG:a1", stringAppender.GetString(), "Test formatted DEBUG event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("DEBUG:a1b2", stringAppender.GetString(), "Test formatted DEBUG event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("DEBUG:a1b2c3", stringAppender.GetString(), "Test formatted DEBUG event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.DebugFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("DEBUG:aQbWcEdReTf", stringAppender.GetString(), "Test formatted DEBUG event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.DebugFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("DEBUG:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.DebugFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("DEBUG:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoDebug() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Info; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Debug"); - - // *** - log1.Debug("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple DEBUG event 1"); - stringAppender.Reset(); - - // *** - log1.Debug("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple DEBUG event 2"); - stringAppender.Reset(); - - // *** - log1.Debug("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple DEBUG event 3"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.DebugFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.DebugFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted DEBUG event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.DebugFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.DebugFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - - [Test] - public void TestLogFormatApi_Info() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Info"); - - // *** - log1.Info("TestMessage"); - Assert.AreEqual("INFO:TestMessage", stringAppender.GetString(), "Test simple INFO event 1"); - stringAppender.Reset(); - - // *** - log1.Info("TestMessage", null); - Assert.AreEqual("INFO:TestMessage", stringAppender.GetString(), "Test simple INFO event 2"); - stringAppender.Reset(); - - // *** - log1.Info("TestMessage", new Exception("Exception message")); - Assert.AreEqual("INFO:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple INFO event 3"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}", "1"); - Assert.AreEqual("INFO:a1", stringAppender.GetString(), "Test formatted INFO event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("INFO:a1b2", stringAppender.GetString(), "Test formatted INFO event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("INFO:a1b2c3", stringAppender.GetString(), "Test formatted INFO event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.InfoFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("INFO:aQbWcEdReTf", stringAppender.GetString(), "Test formatted INFO event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.InfoFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("INFO:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.InfoFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("INFO:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoInfo() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Warn; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Info"); - - // *** - log1.Info("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple INFO event 1"); - stringAppender.Reset(); - - // *** - log1.Info("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple INFO event 2"); - stringAppender.Reset(); - - // *** - log1.Info("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple INFO event 3"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.InfoFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.InfoFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted INFO event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.InfoFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.InfoFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - - [Test] - public void TestLogFormatApi_Warn() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Warn"); - - // *** - log1.Warn("TestMessage"); - Assert.AreEqual("WARN:TestMessage", stringAppender.GetString(), "Test simple WARN event 1"); - stringAppender.Reset(); - - // *** - log1.Warn("TestMessage", null); - Assert.AreEqual("WARN:TestMessage", stringAppender.GetString(), "Test simple WARN event 2"); - stringAppender.Reset(); - - // *** - log1.Warn("TestMessage", new Exception("Exception message")); - Assert.AreEqual("WARN:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple WARN event 3"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}", "1"); - Assert.AreEqual("WARN:a1", stringAppender.GetString(), "Test formatted WARN event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("WARN:a1b2", stringAppender.GetString(), "Test formatted WARN event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("WARN:a1b2c3", stringAppender.GetString(), "Test formatted WARN event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.WarnFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("WARN:aQbWcEdReTf", stringAppender.GetString(), "Test formatted WARN event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.WarnFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("WARN:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.WarnFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("WARN:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoWarn() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Error; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Warn"); - - // *** - log1.Warn("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple WARN event 1"); - stringAppender.Reset(); - - // *** - log1.Warn("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple WARN event 2"); - stringAppender.Reset(); - - // *** - log1.Warn("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple WARN event 3"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.WarnFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.WarnFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted WARN event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.WarnFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.WarnFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - - [Test] - public void TestLogFormatApi_Error() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Error"); - - // *** - log1.Error("TestMessage"); - Assert.AreEqual("ERROR:TestMessage", stringAppender.GetString(), "Test simple ERROR event 1"); - stringAppender.Reset(); - - // *** - log1.Error("TestMessage", null); - Assert.AreEqual("ERROR:TestMessage", stringAppender.GetString(), "Test simple ERROR event 2"); - stringAppender.Reset(); - - // *** - log1.Error("TestMessage", new Exception("Exception message")); - Assert.AreEqual("ERROR:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple ERROR event 3"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}", "1"); - Assert.AreEqual("ERROR:a1", stringAppender.GetString(), "Test formatted ERROR event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("ERROR:a1b2", stringAppender.GetString(), "Test formatted ERROR event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("ERROR:a1b2c3", stringAppender.GetString(), "Test formatted ERROR event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.ErrorFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("ERROR:aQbWcEdReTf", stringAppender.GetString(), "Test formatted ERROR event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("ERROR:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("ERROR:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoError() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Fatal; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Error"); - - // *** - log1.Error("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple ERROR event 1"); - stringAppender.Reset(); - - // *** - log1.Error("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple ERROR event 2"); - stringAppender.Reset(); - - // *** - log1.Error("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple ERROR event 3"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.ErrorFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted ERROR event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.ErrorFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - - [Test] - public void TestLogFormatApi_Fatal() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Fatal"); - - // *** - log1.Fatal("TestMessage"); - Assert.AreEqual("FATAL:TestMessage", stringAppender.GetString(), "Test simple FATAL event 1"); - stringAppender.Reset(); - - // *** - log1.Fatal("TestMessage", null); - Assert.AreEqual("FATAL:TestMessage", stringAppender.GetString(), "Test simple FATAL event 2"); - stringAppender.Reset(); - - // *** - log1.Fatal("TestMessage", new Exception("Exception message")); - Assert.AreEqual("FATAL:TestMessageSystem.Exception: Exception message" + Environment.NewLine, stringAppender.GetString(), "Test simple FATAL event 3"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}", "1"); - Assert.AreEqual("FATAL:a1", stringAppender.GetString(), "Test formatted FATAL event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("FATAL:a1b2", stringAppender.GetString(), "Test formatted FATAL event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("FATAL:a1b2c3", stringAppender.GetString(), "Test formatted FATAL event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.FatalFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("FATAL:aQbWcEdReTf", stringAppender.GetString(), "Test formatted FATAL event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.FatalFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("FATAL:Before Middle After End", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.FatalFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("FATAL:Before Middle After End", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - - [Test] - public void TestLogFormatApi_NoFatal() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Threshold = Level.Off; - stringAppender.Layout = new PatternLayout("%level:%message"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogFormatApi_Fatal"); - - // *** - log1.Fatal("TestMessage"); - Assert.AreEqual("", stringAppender.GetString(), "Test simple FATAL event 1"); - stringAppender.Reset(); - - // *** - log1.Fatal("TestMessage", null); - Assert.AreEqual("", stringAppender.GetString(), "Test simple FATAL event 2"); - stringAppender.Reset(); - - // *** - log1.Fatal("TestMessage", new Exception("Exception message")); - Assert.AreEqual("", stringAppender.GetString(), "Test simple FATAL event 3"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}", "1"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 1 parm"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}b{1}", "1", "2"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 2 parm"); - stringAppender.Reset(); - - // *** - log1.FatalFormat("a{0}b{1}c{2}", "1", "2", "3"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 3 parm"); - stringAppender.Reset(); - - - // *** - log1.FatalFormat("a{0}b{1}c{2}d{3}e{4}f", "Q", "W", "E", "R", "T", "Y"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatted FATAL event with 5 parms (only 4 used)"); - stringAppender.Reset(); - - // *** - log1.FatalFormat(null, "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with null provider"); - stringAppender.Reset(); - - // *** - log1.FatalFormat(new CultureInfo("en"), "Before {0} After {1}", "Middle", "End"); - Assert.AreEqual("", stringAppender.GetString(), "Test formatting with 'en' provider"); - stringAppender.Reset(); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/DateFormatter/AbsoluteTimeDateFormatterTest.cs b/src/log4net.Tests/DateFormatter/AbsoluteTimeDateFormatterTest.cs deleted file mode 100644 index 083dbf75..00000000 --- a/src/log4net.Tests/DateFormatter/AbsoluteTimeDateFormatterTest.cs +++ /dev/null @@ -1,105 +0,0 @@ -#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 System.IO; -using System.Text; -using log4net.DateFormatter; -using NUnit.Framework; - -namespace log4net.Tests.DateFormatter -{ - - [TestFixture] - public class AbsoluteTimeDateFormatterTest - { - - [TearDown] - public void resetCounts() - { - FormatterOne.invocations = 0; - } - - [Test] - public void CacheWorksForSameTicks() - { - StringWriter sw = new StringWriter(); - FormatterOne f1 = new FormatterOne(); - FormatterOne f2 = new FormatterOne(); - DateTime dt = DateTime.Now; - f1.FormatDate(dt, sw); - f2.FormatDate(dt, sw); - Assert.AreEqual(1, FormatterOne.invocations); - } - - [Test] - public void CacheWorksForSameSecond() - { - StringWriter sw = new StringWriter(); - FormatterOne f1 = new FormatterOne(); - FormatterOne f2 = new FormatterOne(); - DateTime dt1 = DateTime.Today; - DateTime dt2 = dt1.AddMilliseconds(600); - f1.FormatDate(dt1, sw); - f2.FormatDate(dt2, sw); - Assert.AreEqual(1, FormatterOne.invocations); - } - - [Test] - public void CacheExpiresWhenCrossingSecond() - { - StringWriter sw = new StringWriter(); - FormatterOne f1 = new FormatterOne(); - FormatterOne f2 = new FormatterOne(); - DateTime dt1 = DateTime.Today.AddMinutes(1); - DateTime dt2 = dt1.AddMilliseconds(1100); - f1.FormatDate(dt1, sw); - f2.FormatDate(dt2, sw); - Assert.AreEqual(2, FormatterOne.invocations); - } - - [Test] - public void CacheIsLocalToSubclass() - { - StringWriter sw = new StringWriter(); - FormatterOne f1 = new FormatterOne(); - FormatterTwo f2 = new FormatterTwo(); - DateTime dt1 = DateTime.Today.AddMinutes(10); - f1.FormatDate(dt1, sw); - f2.FormatDate(dt1, sw); - Assert.AreEqual(2, FormatterOne.invocations); - } - } - - internal class FormatterOne : AbsoluteTimeDateFormatter - { - internal static int invocations = 0; - - override protected void FormatDateWithoutMillis(DateTime dateToFormat, - StringBuilder buffer) - { - invocations++; - } - - } - - internal class FormatterTwo : FormatterOne - { - } -} diff --git a/src/log4net.Tests/Filter/FilterTest.cs b/src/log4net.Tests/Filter/FilterTest.cs deleted file mode 100644 index bc887612..00000000 --- a/src/log4net.Tests/Filter/FilterTest.cs +++ /dev/null @@ -1,120 +0,0 @@ -/* - * - * 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. - * -*/ - -#if !NETCF -using System; -using System.Collections.Generic; -using System.Xml; -using log4net.Appender; -using log4net.Config; -using log4net.Core; -using log4net.Filter; -using log4net.Repository; -using NUnit.Framework; - -namespace log4net.Tests.Filter -{ - [TestFixture] - public class FilterTest - { - [Test] - public void FilterConfigurationTest() - { - XmlDocument log4netConfig = new XmlDocument(); - #region Load log4netConfig - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - "); - #endregion - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - IAppender[] appenders = LogManager.GetRepository(rep.Name).GetAppenders(); - Assert.AreEqual(1, appenders.Length); - - IAppender appender = Array.Find(appenders, delegate(IAppender a) { - return a.Name == "MemoryAppender"; - }); - Assert.IsNotNull(appender); - - MultiplePropertyFilter multiplePropertyFilter = - ((AppenderSkeleton)appender).FilterHead as MultiplePropertyFilter; - - MultiplePropertyFilter.Condition[] conditions = multiplePropertyFilter.GetConditions(); - Assert.AreEqual(2, conditions.Length); - Assert.AreEqual("ABC", conditions[0].Key); - Assert.AreEqual("123", conditions[0].StringToMatch); - Assert.AreEqual("DEF", conditions[1].Key); - Assert.AreEqual("456", conditions[1].StringToMatch); - } - } - - public class MultiplePropertyFilter : FilterSkeleton - { - private readonly List _conditions = new List(); - - public override FilterDecision Decide(LoggingEvent loggingEvent) - { - return FilterDecision.Accept; - } - - public Condition[] GetConditions() - { - return _conditions.ToArray(); - } - - public void AddCondition(Condition condition) - { - _conditions.Add(condition); - } - - public class Condition - { - private string key, stringToMatch; - public string Key { - get { return key; } - set { key = value; } - } - public string StringToMatch { - get { return stringToMatch; } - set { stringToMatch = value; } - } - } - } -} -#endif diff --git a/src/log4net.Tests/Hierarchy/Hierarchy.cs b/src/log4net.Tests/Hierarchy/Hierarchy.cs deleted file mode 100644 index 8578566a..00000000 --- a/src/log4net.Tests/Hierarchy/Hierarchy.cs +++ /dev/null @@ -1,164 +0,0 @@ -/* - * - * 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.Xml; -using log4net.Config; -using log4net.Core; -using log4net.Repository; -using log4net.Repository.Hierarchy; -using log4net.Tests.Appender; -using NUnit.Framework; - -namespace log4net.Tests.Hierarchy -{ - [TestFixture] - public class Hierarchy - { - [Test] - public void SetRepositoryPropertiesInConfigFile() - { - // LOG4NET-53: Allow repository properties to be set in the config file - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - Assert.AreEqual("4", rep.Properties["two-plus-two"]); - Assert.IsNull(rep.Properties["one-plus-one"]); - } - - [Test] - public void AddingMultipleAppenders() - { - CountingAppender alpha = new CountingAppender(); - CountingAppender beta = new CountingAppender(); - - Repository.Hierarchy.Hierarchy hierarchy = - (Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); - hierarchy.Root.AddAppender(alpha); - hierarchy.Root.AddAppender(beta); - hierarchy.Configured = true; - - ILog log = LogManager.GetLogger(GetType()); - log.Debug("Hello World"); - - Assert.AreEqual(1, alpha.Counter); - Assert.AreEqual(1, beta.Counter); - } - - [Test] - public void AddingMultipleAppenders2() - { - CountingAppender alpha = new CountingAppender(); - CountingAppender beta = new CountingAppender(); - - BasicConfigurator.Configure(alpha, beta); - - ILog log = LogManager.GetLogger(GetType()); - log.Debug("Hello World"); - - Assert.AreEqual(1, alpha.Counter); - Assert.AreEqual(1, beta.Counter); - } - - [Test] - // LOG4NET-343 - public void LoggerNameCanConsistOfASingleDot() - { - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - } - - [Test] - public void LoggerNameCanConsistOfASingleNonDot() - { - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - } - - [Test] - public void LoggerNameCanContainSequenceOfDots() - { - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - } - } -} diff --git a/src/log4net.Tests/Hierarchy/Logger.cs b/src/log4net.Tests/Hierarchy/Logger.cs deleted file mode 100644 index 79135548..00000000 --- a/src/log4net.Tests/Hierarchy/Logger.cs +++ /dev/null @@ -1,307 +0,0 @@ -#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; - -using log4net.Core; -using log4net.Repository.Hierarchy; -using log4net.Tests.Appender; - -using NUnit.Framework; - -namespace log4net.Tests.Hierarchy -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Internal unit test. Uses the NUnit test harness. - /// - [TestFixture] - public class LoggerTest - { - private Logger log; - - // A short message. - private static string MSG = "M"; - - /// - /// Any initialization that happens before each test can - /// go here - /// - [SetUp] - public void SetUp() - { - } - - /// - /// Any steps that happen after each test go here - /// - [TearDown] - public void TearDown() - { - // Regular users should not use the clear method lightly! - LogManager.GetRepository().ResetConfiguration(); - LogManager.GetRepository().Shutdown(); - ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Clear(); - } - - /// - /// Add an appender and see if it can be retrieved. - /// - [Test] - public void TestAppender1() - { - log = (Logger)LogManager.GetLogger("test").Logger; - CountingAppender a1 = new CountingAppender(); - a1.Name = "testAppender1"; - log.AddAppender(a1); - - IEnumerator enumAppenders = ((IEnumerable)log.Appenders).GetEnumerator(); - Assert.IsTrue(enumAppenders.MoveNext()); - CountingAppender aHat = (CountingAppender)enumAppenders.Current; - Assert.AreEqual(a1, aHat); - } - - /// - /// Add an appender X, Y, remove X and check if Y is the only - /// remaining appender. - /// - [Test] - public void TestAppender2() - { - CountingAppender a1 = new CountingAppender(); - a1.Name = "testAppender2.1"; - CountingAppender a2 = new CountingAppender(); - a2.Name = "testAppender2.2"; - - log = (Logger)LogManager.GetLogger("test").Logger; - log.AddAppender(a1); - log.AddAppender(a2); - - CountingAppender aHat = (CountingAppender)log.GetAppender(a1.Name); - Assert.AreEqual(a1, aHat); - - aHat = (CountingAppender)log.GetAppender(a2.Name); - Assert.AreEqual(a2, aHat); - - log.RemoveAppender("testAppender2.1"); - - IEnumerator enumAppenders = ((IEnumerable)log.Appenders).GetEnumerator(); - Assert.IsTrue(enumAppenders.MoveNext()); - aHat = (CountingAppender)enumAppenders.Current; - Assert.AreEqual(a2, aHat); - Assert.IsTrue(!enumAppenders.MoveNext()); - - aHat = (CountingAppender)log.GetAppender(a2.Name); - Assert.AreEqual(a2, aHat); - } - - /// - /// Test if logger a.b inherits its appender from a. - /// - [Test] - public void TestAdditivity1() - { - Logger a = (Logger)LogManager.GetLogger("a").Logger; - Logger ab = (Logger)LogManager.GetLogger("a.b").Logger; - CountingAppender ca = new CountingAppender(); - - a.AddAppender(ca); - a.Repository.Configured = true; - - Assert.AreEqual(ca.Counter, 0); - ab.Log(Level.Debug, MSG, null); - Assert.AreEqual(ca.Counter, 1); - ab.Log(Level.Info, MSG, null); - Assert.AreEqual(ca.Counter, 2); - ab.Log(Level.Warn, MSG, null); - Assert.AreEqual(ca.Counter, 3); - ab.Log(Level.Error, MSG, null); - Assert.AreEqual(ca.Counter, 4); - } - - /// - /// Test multiple additivity. - /// - [Test] - public void TestAdditivity2() - { - Logger a = (Logger)LogManager.GetLogger("a").Logger; - Logger ab = (Logger)LogManager.GetLogger("a.b").Logger; - Logger abc = (Logger)LogManager.GetLogger("a.b.c").Logger; - Logger x = (Logger)LogManager.GetLogger("x").Logger; - - CountingAppender ca1 = new CountingAppender(); - CountingAppender ca2 = new CountingAppender(); - - a.AddAppender(ca1); - abc.AddAppender(ca2); - a.Repository.Configured = true; - - Assert.AreEqual(ca1.Counter, 0); - Assert.AreEqual(ca2.Counter, 0); - - ab.Log(Level.Debug, MSG, null); - Assert.AreEqual(ca1.Counter, 1); - Assert.AreEqual(ca2.Counter, 0); - - abc.Log(Level.Debug, MSG, null); - Assert.AreEqual(ca1.Counter, 2); - Assert.AreEqual(ca2.Counter, 1); - - x.Log(Level.Debug, MSG, null); - Assert.AreEqual(ca1.Counter, 2); - Assert.AreEqual(ca2.Counter, 1); - } - - /// - /// Test additivity flag. - /// - [Test] - public void TestAdditivity3() - { - Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root; - Logger a = (Logger)LogManager.GetLogger("a").Logger; - Logger ab = (Logger)LogManager.GetLogger("a.b").Logger; - Logger abc = (Logger)LogManager.GetLogger("a.b.c").Logger; - - CountingAppender caRoot = new CountingAppender(); - CountingAppender caA = new CountingAppender(); - CountingAppender caABC = new CountingAppender(); - - root.AddAppender(caRoot); - a.AddAppender(caA); - abc.AddAppender(caABC); - a.Repository.Configured = true; - - Assert.AreEqual(caRoot.Counter, 0); - Assert.AreEqual(caA.Counter, 0); - Assert.AreEqual(caABC.Counter, 0); - - ab.Additivity = false; - - a.Log(Level.Debug, MSG, null); - Assert.AreEqual(caRoot.Counter, 1); - Assert.AreEqual(caA.Counter, 1); - Assert.AreEqual(caABC.Counter, 0); - - ab.Log(Level.Debug, MSG, null); - Assert.AreEqual(caRoot.Counter, 1); - Assert.AreEqual(caA.Counter, 1); - Assert.AreEqual(caABC.Counter, 0); - - abc.Log(Level.Debug, MSG, null); - Assert.AreEqual(caRoot.Counter, 1); - Assert.AreEqual(caA.Counter, 1); - Assert.AreEqual(caABC.Counter, 1); - } - - /// - /// Test the ability to disable a level of message - /// - [Test] - public void TestDisable1() - { - CountingAppender caRoot = new CountingAppender(); - Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root; - root.AddAppender(caRoot); - - Repository.Hierarchy.Hierarchy h = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()); - h.Threshold = Level.Info; - h.Configured = true; - - Assert.AreEqual(caRoot.Counter, 0); - - root.Log(Level.Debug, MSG, null); - Assert.AreEqual(caRoot.Counter, 0); - root.Log(Level.Info, MSG, null); - Assert.AreEqual(caRoot.Counter, 1); - root.Log(Level.Warn, MSG, null); - Assert.AreEqual(caRoot.Counter, 2); - root.Log(Level.Warn, MSG, null); - Assert.AreEqual(caRoot.Counter, 3); - - h.Threshold = Level.Warn; - root.Log(Level.Debug, MSG, null); - Assert.AreEqual(caRoot.Counter, 3); - root.Log(Level.Info, MSG, null); - Assert.AreEqual(caRoot.Counter, 3); - root.Log(Level.Warn, MSG, null); - Assert.AreEqual(caRoot.Counter, 4); - root.Log(Level.Error, MSG, null); - Assert.AreEqual(caRoot.Counter, 5); - root.Log(Level.Error, MSG, null); - Assert.AreEqual(caRoot.Counter, 6); - - h.Threshold = Level.Off; - root.Log(Level.Debug, MSG, null); - Assert.AreEqual(caRoot.Counter, 6); - root.Log(Level.Info, MSG, null); - Assert.AreEqual(caRoot.Counter, 6); - root.Log(Level.Warn, MSG, null); - Assert.AreEqual(caRoot.Counter, 6); - root.Log(Level.Error, MSG, null); - Assert.AreEqual(caRoot.Counter, 6); - root.Log(Level.Fatal, MSG, null); - Assert.AreEqual(caRoot.Counter, 6); - root.Log(Level.Fatal, MSG, null); - Assert.AreEqual(caRoot.Counter, 6); - } - - /// - /// Tests the Exists method of the Logger class - /// - [Test] - public void TestExists() - { - object a = LogManager.GetLogger("a"); - object a_b = LogManager.GetLogger("a.b"); - object a_b_c = LogManager.GetLogger("a.b.c"); - - object t; - t = LogManager.Exists("xx"); - Assert.IsNull(t); - t = LogManager.Exists("a"); - Assert.AreSame(a, t); - t = LogManager.Exists("a.b"); - Assert.AreSame(a_b, t); - t = LogManager.Exists("a.b.c"); - Assert.AreSame(a_b_c, t); - } - - /// - /// Tests the chained level for a hierarchy - /// - [Test] - public void TestHierarchy1() - { - Repository.Hierarchy.Hierarchy h = new Repository.Hierarchy.Hierarchy(); - h.Root.Level = Level.Error; - - Logger a0 = (Logger)h.GetLogger("a"); - Assert.AreEqual("a", a0.Name); - Assert.IsNull(a0.Level); - Assert.AreSame(Level.Error, a0.EffectiveLevel); - - Logger a1 = (Logger)h.GetLogger("a"); - Assert.AreSame(a0, a1); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Hierarchy/XmlHierarchyConfiguratorTest.cs b/src/log4net.Tests/Hierarchy/XmlHierarchyConfiguratorTest.cs deleted file mode 100644 index 8bd1baba..00000000 --- a/src/log4net.Tests/Hierarchy/XmlHierarchyConfiguratorTest.cs +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * 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.Xml; -using NUnit.Framework; - -using log4net.Repository.Hierarchy; - -namespace log4net.Tests.Hierarchy -{ - [TestFixture] - public class XmlHierarchyConfiguratorTest - { - - private string testProp; - - public string TestProp - { - set - { - testProp = value; - } - get - { - return testProp; - } - } - - [Test][Platform(Include="Win")] - public void EnvironmentOnWindowsIsCaseInsensitive() - { - SetTestPropWithPath(); - Assert.AreNotEqual("Path=", TestProp); - } - - [Test][Platform(Include="Unix")] - public void EnvironmentOnUnixIsCaseSensitive() - { - SetTestPropWithPath(); - Assert.AreEqual("Path=", TestProp); - } - - private void SetTestPropWithPath() - { - XmlDocument doc = new XmlDocument(); - XmlElement el = doc.CreateElement("param"); - el.SetAttribute("name", "TestProp"); - el.SetAttribute("value", "Path=${path}"); - new TestConfigurator().PublicSetParameter(el, this); - } - - // workaround for SetParameter being protected - private class TestConfigurator : XmlHierarchyConfigurator { - public TestConfigurator() : base(null) - { - } - public void PublicSetParameter(XmlElement element, object target) - { - SetParameter(element, target); - } - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Layout/DynamicPatternLayoutTest.cs b/src/log4net.Tests/Layout/DynamicPatternLayoutTest.cs deleted file mode 100644 index ee79a0aa..00000000 --- a/src/log4net.Tests/Layout/DynamicPatternLayoutTest.cs +++ /dev/null @@ -1,37 +0,0 @@ -#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 log4net.Layout; - -using NUnit.Framework; - -namespace log4net.Tests.Layout { - /// - /// Used for internal unit testing the class. - /// - public class DynamicPatternLayoutTest : PatternLayoutTest { - protected override PatternLayout NewPatternLayout() { - return new DynamicPatternLayout(); - } - - protected override PatternLayout NewPatternLayout(string pattern) { - return new DynamicPatternLayout(pattern); - } - } -} diff --git a/src/log4net.Tests/Layout/PatternLayoutTest.cs b/src/log4net.Tests/Layout/PatternLayoutTest.cs deleted file mode 100644 index c8ee77c3..00000000 --- a/src/log4net.Tests/Layout/PatternLayoutTest.cs +++ /dev/null @@ -1,353 +0,0 @@ -#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 System.IO; - -using log4net.Config; -using log4net.Core; -using log4net.Layout; -using log4net.Layout.Pattern; -using log4net.Repository; -using log4net.Tests.Appender; -using log4net.Util; - -using NUnit.Framework; -using System.Globalization; - -namespace log4net.Tests.Layout -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class PatternLayoutTest - { - private CultureInfo _currentCulture; - private CultureInfo _currentUICulture; - - [SetUp] - public void SetUp() - { - // set correct thread culture - _currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture; - _currentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture; - System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; - } - - - [TearDown] - public void TearDown() { - Utils.RemovePropertyFromAllContexts(); - // restore previous culture - System.Threading.Thread.CurrentThread.CurrentCulture = _currentCulture; - System.Threading.Thread.CurrentThread.CurrentUICulture = _currentUICulture; - } - - protected virtual PatternLayout NewPatternLayout() { - return new PatternLayout(); - } - - protected virtual PatternLayout NewPatternLayout(string pattern) { - return new PatternLayout(pattern); - } - - [Test] - public void TestThreadPropertiesPattern() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = NewPatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadProperiesPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread properties value set"); - stringAppender.Reset(); - - ThreadContext.Properties[Utils.PROPERTY_KEY] = "val1"; - - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test thread properties value set"); - stringAppender.Reset(); - - ThreadContext.Properties.Remove(Utils.PROPERTY_KEY); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread properties value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestStackTracePattern() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = NewPatternLayout("%stacktrace{2}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestStackTracePattern"); - - log1.Info("TestMessage"); - StringAssert.EndsWith("PatternLayoutTest.TestStackTracePattern", stringAppender.GetString(), "stack trace value set"); - stringAppender.Reset(); - } - - [Test] - public void TestGlobalPropertiesPattern() - { - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = NewPatternLayout("%property{" + Utils.PROPERTY_KEY + "}"); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestGlobalProperiesPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no global properties value set"); - stringAppender.Reset(); - - GlobalContext.Properties[Utils.PROPERTY_KEY] = "val1"; - - log1.Info("TestMessage"); - Assert.AreEqual("val1", stringAppender.GetString(), "Test global properties value set"); - stringAppender.Reset(); - - GlobalContext.Properties.Remove(Utils.PROPERTY_KEY); - - log1.Info("TestMessage"); - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test global properties value removed"); - stringAppender.Reset(); - } - - [Test] - public void TestAddingCustomPattern() - { - StringAppender stringAppender = new StringAppender(); - PatternLayout layout = NewPatternLayout(); - - layout.AddConverter("TestAddingCustomPattern", typeof(TestMessagePatternConverter)); - layout.ConversionPattern = "%TestAddingCustomPattern"; - layout.ActivateOptions(); - - stringAppender.Layout = layout; - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern"); - - log1.Info("TestMessage"); - Assert.AreEqual("TestMessage", stringAppender.GetString(), "%TestAddingCustomPattern not registered"); - stringAppender.Reset(); - } - - [Test] - public void NamedPatternConverterWithoutPrecisionShouldReturnFullName() - { - StringAppender stringAppender = new StringAppender(); - PatternLayout layout = NewPatternLayout(); - layout.AddConverter("message-as-name", typeof(MessageAsNamePatternConverter)); - layout.ConversionPattern = "%message-as-name"; - layout.ActivateOptions(); - stringAppender.Layout = layout; - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern"); - - log1.Info("NoDots"); - Assert.AreEqual("NoDots", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("One.Dot"); - Assert.AreEqual("One.Dot", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("Tw.o.Dots"); - Assert.AreEqual("Tw.o.Dots", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("TrailingDot."); - Assert.AreEqual("TrailingDot.", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info(".LeadingDot"); - Assert.AreEqual(".LeadingDot", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - // empty string and other evil combinations as tests for of-by-one mistakes in index calculations - log1.Info(string.Empty); - Assert.AreEqual(string.Empty, stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("."); - Assert.AreEqual(".", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("x"); - Assert.AreEqual("x", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - } - - [Test] - public void NamedPatternConverterWithPrecision1ShouldStripLeadingStuffIfPresent() - { - StringAppender stringAppender = new StringAppender(); - PatternLayout layout = NewPatternLayout(); - layout.AddConverter("message-as-name", typeof(MessageAsNamePatternConverter)); - layout.ConversionPattern = "%message-as-name{1}"; - layout.ActivateOptions(); - stringAppender.Layout = layout; - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern"); - - log1.Info("NoDots"); - Assert.AreEqual("NoDots", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("One.Dot"); - Assert.AreEqual("Dot", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("Tw.o.Dots"); - Assert.AreEqual("Dots", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("TrailingDot."); - Assert.AreEqual("TrailingDot.", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info(".LeadingDot"); - Assert.AreEqual("LeadingDot", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - // empty string and other evil combinations as tests for of-by-one mistakes in index calculations - log1.Info(string.Empty); - Assert.AreEqual(string.Empty, stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("x"); - Assert.AreEqual("x", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("."); - Assert.AreEqual(".", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - } - - [Test] - public void NamedPatternConverterWithPrecision2ShouldStripLessLeadingStuffIfPresent() { - StringAppender stringAppender = new StringAppender(); - PatternLayout layout = NewPatternLayout(); - layout.AddConverter("message-as-name", typeof(MessageAsNamePatternConverter)); - layout.ConversionPattern = "%message-as-name{2}"; - layout.ActivateOptions(); - stringAppender.Layout = layout; - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern"); - - log1.Info("NoDots"); - Assert.AreEqual("NoDots", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("One.Dot"); - Assert.AreEqual("One.Dot", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("Tw.o.Dots"); - Assert.AreEqual("o.Dots", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("TrailingDot."); - Assert.AreEqual("TrailingDot.", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info(".LeadingDot"); - Assert.AreEqual("LeadingDot", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - // empty string and other evil combinations as tests for of-by-one mistakes in index calculations - log1.Info(string.Empty); - Assert.AreEqual(string.Empty, stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("x"); - Assert.AreEqual("x", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - - log1.Info("."); - Assert.AreEqual(".", stringAppender.GetString(), "%message-as-name not registered"); - stringAppender.Reset(); - } - - /// - /// Converter to include event message - /// - private class TestMessagePatternConverter : PatternLayoutConverter - { - /// - /// Convert the pattern to the rendered message - /// - /// that will receive the formatted result. - /// the event being logged - /// the relevant location information - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - loggingEvent.WriteRenderedMessage(writer); - } - } - - [Test] - public void TestExceptionPattern() - { - StringAppender stringAppender = new StringAppender(); - PatternLayout layout = NewPatternLayout("%exception{stacktrace}"); - stringAppender.Layout = layout; - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - - ILog log1 = LogManager.GetLogger(rep.Name, "TestExceptionPattern"); - - Exception exception = new Exception("Oh no!"); - log1.Info("TestMessage", exception); - - Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString()); - - stringAppender.Reset(); - } - - private class MessageAsNamePatternConverter : NamedPatternConverter - { - protected override string GetFullyQualifiedName(LoggingEvent loggingEvent) - { - return loggingEvent.MessageObject.ToString(); - } - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Layout/XmlLayoutTest.cs b/src/log4net.Tests/Layout/XmlLayoutTest.cs deleted file mode 100644 index d7a33523..00000000 --- a/src/log4net.Tests/Layout/XmlLayoutTest.cs +++ /dev/null @@ -1,365 +0,0 @@ -#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 System.IO; -using System.Xml; - -using log4net.Config; -using log4net.Core; -using log4net.Layout; -using log4net.Repository; -using log4net.Tests.Appender; -using log4net.Util; - -using NUnit.Framework; -using System.Globalization; - -namespace log4net.Tests.Layout -{ - [TestFixture] - public class XmlLayoutTest - { - private CultureInfo _currentCulture; - private CultureInfo _currentUICulture; - - [SetUp] - public void SetUp() - { - // set correct thread culture - _currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture; - _currentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture; - System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; - } - - [TearDown] - public void TearDown() - { - // restore previous culture - System.Threading.Thread.CurrentThread.CurrentCulture = _currentCulture; - System.Threading.Thread.CurrentThread.CurrentUICulture = _currentUICulture; - } - - /// - /// Build a basic object with some default values. - /// - /// A useful LoggingEventData object - private LoggingEventData CreateBaseEvent() - { - LoggingEventData ed = new LoggingEventData(); - ed.Domain = "Tests"; - ed.ExceptionString = ""; - ed.Identity = "TestRunner"; - ed.Level = Level.Info; - ed.LocationInfo = new LocationInfo(GetType()); - ed.LoggerName = "TestLogger"; - ed.Message = "Test message"; - ed.ThreadName = "TestThread"; - ed.TimeStamp = DateTime.Today; - ed.UserName = "TestRunner"; - ed.Properties = new PropertiesDictionary(); - - return ed; - } - - private static string CreateEventNode(string message) - { - return String.Format("{1}" + Environment.NewLine, -#if !NETCF - XmlConvert.ToString(DateTime.Today, XmlDateTimeSerializationMode.Local), -#else - XmlConvert.ToString(DateTime.Today), -#endif - message); - } - - private static string CreateEventNode(string key, string value) - { - return String.Format("Test message" + Environment.NewLine, -#if !NETCF - XmlConvert.ToString(DateTime.Today, XmlDateTimeSerializationMode.Local), -#else - XmlConvert.ToString(DateTime.Today), -#endif - key, - value); - } - - [Test] - public void TestBasicEventLogging() - { - TextWriter writer = new StringWriter(); - XmlLayout layout = new XmlLayout(); - LoggingEventData evt = CreateBaseEvent(); - - layout.Format(writer, new LoggingEvent(evt)); - - string expected = CreateEventNode("Test message"); - - Assert.AreEqual(expected, writer.ToString()); - } - - [Test] - public void TestIllegalCharacterMasking() - { - TextWriter writer = new StringWriter(); - XmlLayout layout = new XmlLayout(); - LoggingEventData evt = CreateBaseEvent(); - - evt.Message = "This is a masked char->\uFFFF"; - - layout.Format(writer, new LoggingEvent(evt)); - - string expected = CreateEventNode("This is a masked char->?"); - - Assert.AreEqual(expected, writer.ToString()); - } - - [Test] - public void TestCDATAEscaping1() - { - TextWriter writer = new StringWriter(); - XmlLayout layout = new XmlLayout(); - LoggingEventData evt = CreateBaseEvent(); - - //The &'s trigger the use of a cdata block - evt.Message = "&&&&&&&Escape this ]]>. End here."; - - layout.Format(writer, new LoggingEvent(evt)); - - string expected = CreateEventNode("]]. End here.]]>"); - - Assert.AreEqual(expected, writer.ToString()); - } - - [Test] - public void TestCDATAEscaping2() - { - TextWriter writer = new StringWriter(); - XmlLayout layout = new XmlLayout(); - LoggingEventData evt = CreateBaseEvent(); - - //The &'s trigger the use of a cdata block - evt.Message = "&&&&&&&Escape the end ]]>"; - - layout.Format(writer, new LoggingEvent(evt)); - - string expected = CreateEventNode("]]>"); - - Assert.AreEqual(expected, writer.ToString()); - } - - [Test] - public void TestCDATAEscaping3() - { - TextWriter writer = new StringWriter(); - XmlLayout layout = new XmlLayout(); - LoggingEventData evt = CreateBaseEvent(); - - //The &'s trigger the use of a cdata block - evt.Message = "]]>&&&&&&&Escape the begining"; - - layout.Format(writer, new LoggingEvent(evt)); - - string expected = CreateEventNode("]]&&&&&&&Escape the begining]]>"); - - Assert.AreEqual(expected, writer.ToString()); - } - - [Test] - public void TestBase64EventLogging() - { - TextWriter writer = new StringWriter(); - XmlLayout layout = new XmlLayout(); - LoggingEventData evt = CreateBaseEvent(); - - layout.Base64EncodeMessage = true; - layout.Format(writer, new LoggingEvent(evt)); - - string expected = CreateEventNode("VGVzdCBtZXNzYWdl"); - - Assert.AreEqual(expected, writer.ToString()); - } - - [Test] - public void TestPropertyEventLogging() - { - LoggingEventData evt = CreateBaseEvent(); - evt.Properties["Property1"] = "prop1"; - - XmlLayout layout = new XmlLayout(); - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = layout; - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadProperiesPattern"); - - log1.Logger.Log(new LoggingEvent(evt)); - - string expected = CreateEventNode("Property1", "prop1"); - - Assert.AreEqual(expected, stringAppender.GetString()); - } - - [Test] - public void TestBase64PropertyEventLogging() - { - LoggingEventData evt = CreateBaseEvent(); - evt.Properties["Property1"] = "prop1"; - - XmlLayout layout = new XmlLayout(); - layout.Base64EncodeProperties = true; - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = layout; - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadProperiesPattern"); - - log1.Logger.Log(new LoggingEvent(evt)); - - string expected = CreateEventNode("Property1", "cHJvcDE="); - - Assert.AreEqual(expected, stringAppender.GetString()); - } - - [Test] - public void TestPropertyCharacterEscaping() - { - LoggingEventData evt = CreateBaseEvent(); - evt.Properties["Property1"] = "prop1 \"quoted\""; - - XmlLayout layout = new XmlLayout(); - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = layout; - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadProperiesPattern"); - - log1.Logger.Log(new LoggingEvent(evt)); - - string expected = CreateEventNode("Property1", "prop1 "quoted""); - - Assert.AreEqual(expected, stringAppender.GetString()); - } - - [Test] - public void TestPropertyIllegalCharacterMasking() - { - LoggingEventData evt = CreateBaseEvent(); - evt.Properties["Property1"] = "mask this ->\uFFFF"; - - XmlLayout layout = new XmlLayout(); - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = layout; - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadProperiesPattern"); - - log1.Logger.Log(new LoggingEvent(evt)); - - string expected = CreateEventNode("Property1", "mask this ->?"); - - Assert.AreEqual(expected, stringAppender.GetString()); - } - - [Test] - public void TestPropertyIllegalCharacterMaskingInName() - { - LoggingEventData evt = CreateBaseEvent(); - evt.Properties["Property\uFFFF"] = "mask this ->\uFFFF"; - - XmlLayout layout = new XmlLayout(); - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = layout; - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadProperiesPattern"); - - log1.Logger.Log(new LoggingEvent(evt)); - - string expected = CreateEventNode("Property?", "mask this ->?"); - - Assert.AreEqual(expected, stringAppender.GetString()); - } - -#if FRAMEWORK_4_0_OR_ABOVE - [Test] - public void BracketsInStackTracesKeepLogWellFormed() { - XmlLayout layout = new XmlLayout(); - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = layout; - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogger"); - Action bar = foo => { - try { - throw new NullReferenceException(); - } catch (Exception ex) { - log1.Error(string.Format("Error {0}", foo), ex); - } - }; - bar(42); - - // really only asserts there is no exception - var loggedDoc = new XmlDocument(); - loggedDoc.LoadXml(stringAppender.GetString()); - } - - [Test] - public void BracketsInStackTracesAreEscapedProperly() { - XmlLayout layout = new XmlLayout(); - StringAppender stringAppender = new StringAppender(); - stringAppender.Layout = layout; - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - BasicConfigurator.Configure(rep, stringAppender); - ILog log1 = LogManager.GetLogger(rep.Name, "TestLogger"); - Action bar = foo => { - try { - throw new NullReferenceException(); - } - catch (Exception ex) { - log1.Error(string.Format("Error {0}", foo), ex); - } - }; - bar(42); - - var log = stringAppender.GetString(); - var startOfExceptionText = log.IndexOf("", StringComparison.InvariantCulture) + 11; - var endOfExceptionText = log.IndexOf("", StringComparison.InvariantCulture); - var sub = log.Substring(startOfExceptionText, endOfExceptionText - startOfExceptionText); - if (sub.StartsWith("", sub); - } - else - { - StringAssert.DoesNotContain("<", sub); - StringAssert.DoesNotContain(">", sub); - } - } -#endif - } -} \ No newline at end of file diff --git a/src/log4net.Tests/LoggerRepository/ConfigurationMessages.cs b/src/log4net.Tests/LoggerRepository/ConfigurationMessages.cs deleted file mode 100644 index e9a88778..00000000 --- a/src/log4net.Tests/LoggerRepository/ConfigurationMessages.cs +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * 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.Collections; -using System.Xml; -using log4net.Appender; -using log4net.Config; -using log4net.Core; -using log4net.Repository; -using log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.LoggerRepository -{ - [TestFixture] - public class ConfigurationMessages - { - [Test] - public void ConfigurationMessagesTest() - { - try { - LogLog.EmitInternalMessages = false; - LogLog.InternalDebugging = true; - - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - rep.ConfigurationChanged += new LoggerRepositoryConfigurationChangedEventHandler(rep_ConfigurationChanged); - - ICollection configurationMessages = XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - Assert.IsTrue(configurationMessages.Count > 0); - } - finally { - LogLog.EmitInternalMessages = true; - LogLog.InternalDebugging = false; - } - } - - static void rep_ConfigurationChanged(object sender, EventArgs e) - { - ConfigurationChangedEventArgs configChanged = (ConfigurationChangedEventArgs)e; - - Assert.IsTrue(configChanged.ConfigurationMessages.Count > 0); - } - } - - public class LogLogAppender : AppenderSkeleton - { - private readonly static Type declaringType = typeof(LogLogAppender); - - public override void ActivateOptions() - { - LogLog.Debug(declaringType, "Debug - Activating options..."); - LogLog.Warn(declaringType, "Warn - Activating options..."); - LogLog.Error(declaringType, "Error - Activating options..."); - - base.ActivateOptions(); - } - - protected override void Append(LoggingEvent loggingEvent) - { - LogLog.Debug(declaringType, "Debug - Appending..."); - LogLog.Warn(declaringType, "Warn - Appending..."); - LogLog.Error(declaringType, "Error - Appending..."); - } - } -} diff --git a/src/log4net.Tests/Util/CyclicBufferTest.cs b/src/log4net.Tests/Util/CyclicBufferTest.cs deleted file mode 100644 index a3a95cd4..00000000 --- a/src/log4net.Tests/Util/CyclicBufferTest.cs +++ /dev/null @@ -1,110 +0,0 @@ -#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.Util; - -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class CyclicBufferTest - { - [Test, ExpectedException(typeof(ArgumentOutOfRangeException))] - public void TestConstructorSize0() - { - CyclicBuffer cb = new CyclicBuffer(0); - Assert.IsNotNull(cb); - } - - [Test] - public void TestSize1() - { - CyclicBuffer cb = new CyclicBuffer(1); - - Assert.AreEqual(0, cb.Length, "Empty Buffer should have length 0"); - Assert.AreEqual(1, cb.MaxSize, "Buffer should have max size 1"); - - LoggingEvent event1 = new LoggingEvent(null, null, null, null, null, null); - LoggingEvent event2 = new LoggingEvent(null, null, null, null, null, null); - - LoggingEvent discardedEvent = cb.Append(event1); - - Assert.IsNull(discardedEvent, "No event should be discarded untill the buffer is full"); - Assert.AreEqual(1, cb.Length, "Buffer should have length 1"); - Assert.AreEqual(1, cb.MaxSize, "Buffer should still have max size 1"); - - - discardedEvent = cb.Append(event2); - - Assert.AreSame(event1, discardedEvent, "Expect event1 to now be discarded"); - Assert.AreEqual(1, cb.Length, "Buffer should still have length 1"); - Assert.AreEqual(1, cb.MaxSize, "Buffer should really still have max size 1"); - - LoggingEvent[] discardedEvents = cb.PopAll(); - - Assert.AreEqual(1, discardedEvents.Length, "Poped events length should be 1"); - Assert.AreSame(event2, discardedEvents[0], "Expect event2 to now be popped"); - Assert.AreEqual(0, cb.Length, "Buffer should be back to length 0"); - Assert.AreEqual(1, cb.MaxSize, "Buffer should really really still have max size 1"); - } - - [Test] - public void TestSize2() - { - CyclicBuffer cb = new CyclicBuffer(2); - - Assert.AreEqual(0, cb.Length, "Empty Buffer should have length 0"); - Assert.AreEqual(2, cb.MaxSize, "Buffer should have max size 2"); - - LoggingEvent event1 = new LoggingEvent(null, null, null, null, null, null); - LoggingEvent event2 = new LoggingEvent(null, null, null, null, null, null); - LoggingEvent event3 = new LoggingEvent(null, null, null, null, null, null); - - LoggingEvent discardedEvent; - - discardedEvent = cb.Append(event1); - Assert.IsNull(discardedEvent, "No event should be discarded after append 1"); - discardedEvent = cb.Append(event2); - Assert.IsNull(discardedEvent, "No event should be discarded after append 2"); - - discardedEvent = cb.Append(event3); - Assert.AreSame(event1, discardedEvent, "Expect event1 to now be discarded"); - - discardedEvent = cb.PopOldest(); - Assert.AreSame(event2, discardedEvent, "Expect event2 to now be discarded"); - - LoggingEvent[] discardedEvents = cb.PopAll(); - - Assert.AreEqual(1, discardedEvents.Length, "Poped events length should be 1"); - Assert.AreSame(event3, discardedEvents[0], "Expect event3 to now be popped"); - Assert.AreEqual(0, cb.Length, "Buffer should be back to length 0"); - Assert.AreEqual(2, cb.MaxSize, "Buffer should really really still have max size 2"); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Util/EnvironmentPatternConverterTest.cs b/src/log4net.Tests/Util/EnvironmentPatternConverterTest.cs deleted file mode 100644 index 53083bde..00000000 --- a/src/log4net.Tests/Util/EnvironmentPatternConverterTest.cs +++ /dev/null @@ -1,147 +0,0 @@ -/* - * - * 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. - * -*/ - -#if !NETCF - -using System; -using System.Collections; -using System.IO; -using System.Text; -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - [TestFixture] - public class EnvironmentPatternConverterTest - { - private const string ENVIRONMENT_VARIABLE_NAME = "LOG4NET_TEST_TEMP"; - const string SYSTEM_LEVEL_VALUE = "SystemLevelEnvironmentValue"; - const string USER_LEVEL_VALUE = "UserLevelEnvironmentValue"; - const string PROCESS_LEVEL_VALUE = "ProcessLevelEnvironmentValue"; - - [Test][Platform("Win")] - public void SystemLevelEnvironmentVariable() - { - EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); - try { - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, SYSTEM_LEVEL_VALUE, EnvironmentVariableTarget.Machine); - } - catch (System.Security.SecurityException) { - Assert.Ignore("Test skipped as current user must not set system level environment variables"); - } - - converter.Option = ENVIRONMENT_VARIABLE_NAME; - - StringWriter sw = new StringWriter(); - converter.Convert(sw, null); - sw.Close(); - - try - { - Assert.AreEqual(SYSTEM_LEVEL_VALUE, sw.ToString(), - string.Format("Process level environment variable not expanded correctly. Found {0}" , Dump(Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine)))); - } - finally - { - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null, EnvironmentVariableTarget.Machine); - } - } - - [Test][Platform("Win")] - public void UserLevelEnvironmentVariable() - { - EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, USER_LEVEL_VALUE, EnvironmentVariableTarget.User); - - converter.Option = ENVIRONMENT_VARIABLE_NAME; - - StringWriter sw = new StringWriter(); - converter.Convert(sw, null); - sw.Close(); - - try - { - Assert.AreEqual(USER_LEVEL_VALUE, sw.ToString(), - string.Format("Process level environment variable not expanded correctly. Found {0}" , Dump(Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User)))); - } - finally - { - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null, EnvironmentVariableTarget.User); - } - } - - [Test] - public void ProcessLevelEnvironmentVariable() - { - EnvironmentPatternConverter converter = new EnvironmentPatternConverter(); - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, PROCESS_LEVEL_VALUE); - - converter.Option = ENVIRONMENT_VARIABLE_NAME; - - StringWriter sw = new StringWriter(); - converter.Convert(sw, null); - sw.Close(); - - try - { - Assert.AreEqual(PROCESS_LEVEL_VALUE, sw.ToString(), - string.Format("Process level environment variable not expanded correctly. Found {0}" , Dump(Environment.GetEnvironmentVariables()))); - } - finally - { - Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null); - } - } - - private string Dump(IDictionary d) - { - StringBuilder sb = new StringBuilder(); - foreach (DictionaryEntry de in d) - { - sb.Append(de.Key).Append("=").Append(de.Value).Append(","); - } - return sb.ToString(); - } - - private class EnvironmentPatternConverter - { - private object target = null; - - public EnvironmentPatternConverter() - { - target = Utils.CreateInstance("log4net.Util.PatternStringConverters.EnvironmentPatternConverter,log4net-1.3"); - } - - public string Option - { - get { return Utils.GetProperty(target, "Option") as string; } - set { Utils.SetProperty(target, "Option", value); } - } - - public void Convert(TextWriter writer, object state) - { - Utils.InvokeMethod(target, "Convert", writer, state); - } - } - } -} - -#endif diff --git a/src/log4net.Tests/Util/LogLogTest.cs b/src/log4net.Tests/Util/LogLogTest.cs deleted file mode 100644 index 7d9030b6..00000000 --- a/src/log4net.Tests/Util/LogLogTest.cs +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * 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.Collections; -using System.Diagnostics; -using log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - [TestFixture] - public class LogLogTest - { - [Test] - public void TraceListenerCounterTest() - { - TraceListenerCounter listTraceListener = new TraceListenerCounter(); - - Trace.Listeners.Clear(); - Trace.Listeners.Add(listTraceListener); - - Trace.Write("Hello"); - Trace.Write("World"); - - Assert.AreEqual(2, listTraceListener.Count); - } - - [Test] - public void EmitInternalMessages() - { - TraceListenerCounter listTraceListener = new TraceListenerCounter(); - Trace.Listeners.Clear(); - Trace.Listeners.Add(listTraceListener); - LogLog.Error(GetType(), "Hello"); - LogLog.Error(GetType(), "World"); - Trace.Flush(); - Assert.AreEqual(2, listTraceListener.Count); - - try { - LogLog.EmitInternalMessages = false; - - LogLog.Error(GetType(), "Hello"); - LogLog.Error(GetType(), "World"); - Assert.AreEqual(2, listTraceListener.Count); - } - finally { - LogLog.EmitInternalMessages = true; - } - } - - [Test] - public void LogReceivedAdapter() - { - ArrayList messages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(messages)) - { - LogLog.Debug(GetType(), "Won't be recorded"); - LogLog.Error(GetType(), "This will be recorded."); - LogLog.Error(GetType(), "This will be recorded."); - } - - Assert.AreEqual(2, messages.Count); - } - } - - public class TraceListenerCounter : TraceListener - { - private int count = 0; - - public override void Write(string message) - { - count++; - } - - public override void WriteLine(string message) - { - Write(message); - } - - public void Reset() - { - count = 0; - } - - public int Count - { - get { return count; } - } - } -} diff --git a/src/log4net.Tests/Util/PatternConverterTest.cs b/src/log4net.Tests/Util/PatternConverterTest.cs deleted file mode 100644 index 06f352eb..00000000 --- a/src/log4net.Tests/Util/PatternConverterTest.cs +++ /dev/null @@ -1,192 +0,0 @@ -/* - * - * 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.IO; -using System.Xml; -using log4net.Config; -using log4net.Core; -using log4net.Layout.Pattern; -using log4net.Repository; -using log4net.Tests.Appender; -using log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - [TestFixture] - public class PatternConverterTest - { - [Test] - public void PatternLayoutConverterProperties() - { - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - ILog log = LogManager.GetLogger(rep.Name, "PatternLayoutConverterProperties"); - log.Debug("Message"); - - PropertyKeyCountPatternLayoutConverter converter = - PropertyKeyCountPatternLayoutConverter.MostRecentInstance; - Assert.AreEqual(2, converter.Properties.Count); - Assert.AreEqual("4", converter.Properties["two-plus-two"]); - - StringAppender appender = - (StringAppender)LogManager.GetRepository(rep.Name).GetAppenders()[0]; - Assert.AreEqual("2", appender.GetString()); - } - - [Test] - public void PatternConverterProperties() - { - XmlDocument log4netConfig = new XmlDocument(); - log4netConfig.LoadXml(@" - - - - - - - - - - - - - - - - - - - - - - - - "); - - ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); - XmlConfigurator.Configure(rep, log4netConfig["log4net"]); - - ILog log = LogManager.GetLogger(rep.Name, "PatternConverterProperties"); - log.Debug("Message"); - - PropertyKeyCountPatternConverter converter = - PropertyKeyCountPatternConverter.MostRecentInstance; - Assert.AreEqual(2, converter.Properties.Count); - Assert.AreEqual("4", converter.Properties["two-plus-two"]); - - PatternStringAppender appender = - (PatternStringAppender)LogManager.GetRepository(rep.Name).GetAppenders()[0]; - Assert.AreEqual("2", appender.Setting.Format()); - } - } - - public class PropertyKeyCountPatternLayoutConverter : PatternLayoutConverter - { - private static PropertyKeyCountPatternLayoutConverter mostRecentInstance; - - public PropertyKeyCountPatternLayoutConverter() - { - mostRecentInstance = this; - } - - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write(Properties.GetKeys().Length); - } - - public static PropertyKeyCountPatternLayoutConverter MostRecentInstance - { - get { return mostRecentInstance; } - } - } - - public class PropertyKeyCountPatternConverter : PatternConverter - { - private static PropertyKeyCountPatternConverter mostRecentInstance; - - public PropertyKeyCountPatternConverter() - { - mostRecentInstance = this; - } - - protected override void Convert(TextWriter writer, object state) - { - writer.Write(Properties.GetKeys().Length); - } - - public static PropertyKeyCountPatternConverter MostRecentInstance - { - get { return mostRecentInstance; } - } - } - - public class PatternStringAppender : StringAppender - { - private static PatternStringAppender mostRecentInstace; - - private PatternString setting; - - public PatternStringAppender() - { - mostRecentInstace = this; - } - - public PatternString Setting - { - get { return setting; } - set { setting = value; } - } - - public static PatternStringAppender MostRecentInstace - { - get { return mostRecentInstace; } - } - } -} diff --git a/src/log4net.Tests/Util/PatternStringTest.cs b/src/log4net.Tests/Util/PatternStringTest.cs deleted file mode 100644 index 2a2ed7df..00000000 --- a/src/log4net.Tests/Util/PatternStringTest.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * 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 log4net.Util; -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - [TestFixture] - public class PatternStringTest - { - [Test] - public void TestEnvironmentFolderPathPatternConverter() - { - string[] specialFolderNames = Enum.GetNames(typeof(Environment.SpecialFolder)); - - foreach (string specialFolderName in specialFolderNames) - { - string pattern = "%envFolderPath{" + specialFolderName + "}"; - - PatternString patternString = new PatternString(pattern); - - string evaluatedPattern = patternString.Format(); - - Environment.SpecialFolder specialFolder = - (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), specialFolderName); - - Assert.AreEqual(Environment.GetFolderPath(specialFolder), evaluatedPattern); - } - } - } -} diff --git a/src/log4net.Tests/Util/PropertiesDictionaryTest.cs b/src/log4net.Tests/Util/PropertiesDictionaryTest.cs deleted file mode 100644 index 0809cc99..00000000 --- a/src/log4net.Tests/Util/PropertiesDictionaryTest.cs +++ /dev/null @@ -1,67 +0,0 @@ -#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.IO; -using System.Runtime.Serialization.Formatters.Binary; - -using log4net.Util; - -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class PropertiesDictionaryTest - { - [Test] - public void TestSerialization() - { - PropertiesDictionary pd = new PropertiesDictionary(); - - for(int i = 0; i < 10; i++) - { - pd[i.ToString()] = i; - } - - Assert.AreEqual(10, pd.Count, "Dictionary should have 10 items"); - - // Serialize the properties into a memory stream - BinaryFormatter formatter = new BinaryFormatter(); - MemoryStream memory = new MemoryStream(); - formatter.Serialize(memory, pd); - - // Deserialize the stream into a new properties dictionary - memory.Position = 0; - PropertiesDictionary pd2 = (PropertiesDictionary)formatter.Deserialize(memory); - - Assert.AreEqual(10, pd2.Count, "Deserialized Dictionary should have 10 items"); - - foreach(string key in pd.GetKeys()) - { - Assert.AreEqual(pd[key], pd2[key], "Check Value Persisted for key [{0}]", key); - } - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Util/RandomStringPatternConverterTest.cs b/src/log4net.Tests/Util/RandomStringPatternConverterTest.cs deleted file mode 100644 index f15623fb..00000000 --- a/src/log4net.Tests/Util/RandomStringPatternConverterTest.cs +++ /dev/null @@ -1,90 +0,0 @@ -#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.IO; - -using NUnit.Framework; - -namespace log4net.Tests.Util -{ - /// - /// Used for internal unit testing the class. - /// - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class RandomStringPatternConverterTest - { - [Test] - public void TestConvert() - { - RandomStringPatternConverter converter = new RandomStringPatternConverter(); - - // Check default string length - StringWriter sw = new StringWriter(); - converter.Convert(sw, null); - - Assert.AreEqual(4, sw.ToString().Length, "Default string length should be 4"); - - // Set string length to 7 - converter.Option = "7"; - converter.ActivateOptions(); - - sw = new StringWriter(); - converter.Convert(sw, null); - - string string1 = sw.ToString(); - Assert.AreEqual(7, string1.Length, "string length should be 7"); - - // Check for duplicate result - sw = new StringWriter(); - converter.Convert(sw, null); - - string string2 = sw.ToString(); - Assert.IsTrue(string1 != string2, "strings should be different"); - } - - private class RandomStringPatternConverter - { - private object target = null; - - public RandomStringPatternConverter() - { - target = Utils.CreateInstance("log4net.Util.PatternStringConverters.RandomStringPatternConverter,log4net-1.3"); - } - - public string Option - { - get { return Utils.GetProperty(target, "Option") as string; } - set { Utils.SetProperty(target, "Option", value); } - } - - public void Convert(TextWriter writer, object state) - { - Utils.InvokeMethod(target, "Convert", writer, state); - } - - public void ActivateOptions() - { - Utils.InvokeMethod(target, "ActivateOptions"); - } - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/Util/SystemInfoTest.cs b/src/log4net.Tests/Util/SystemInfoTest.cs deleted file mode 100644 index 87af35e1..00000000 --- a/src/log4net.Tests/Util/SystemInfoTest.cs +++ /dev/null @@ -1,153 +0,0 @@ -#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.Util; - -using NUnit.Framework; - -#if FRAMEWORK_4_0_OR_ABOVE -using System.Linq.Expressions; -using System.Reflection; -#endif - -namespace log4net.Tests.Util -{ - /// - /// Used for internal unit testing the class. - /// - [TestFixture] - public class SystemInfoTest - { - -#if FRAMEWORK_4_0_OR_ABOVE - /// - /// It's "does not throw not supported exception" NOT - /// "returns 'Dynamic Assembly' string for dynamic assemblies" by purpose. - /// can be JITted and inlined in different release configurations, - /// thus we cannot determine what the exact result of this test will be. - /// In 'Debug' GetCallingAssembly should return dynamic assembly named: 'Anonymously Hosted DynamicMethods Assembly' - /// whereas in 'Release' this will be inlined and the result will be something like 'X:\Y\Z\log4net.Tests.dll'. - /// Therefore simple check against dynamic assembly - /// in to avoid 'Debug' release. - /// - [Test] - public void TestAssemblyLocationInfoDoesNotThrowNotSupportedExceptionForDynamicAssembly() - { - var systemInfoAssemblyLocationMethod = GetAssemblyLocationInfoMethodCall(); - - Assert.DoesNotThrow(() => systemInfoAssemblyLocationMethod()); - } - - private static Func GetAssemblyLocationInfoMethodCall() - { - var method = typeof(SystemInfoTest).GetMethod("TestAssemblyLocationInfoMethod", new Type[0]); - var methodCall = Expression.Call(null, method, new Expression[0]); - return Expression.Lambda>(methodCall, new ParameterExpression[0]).Compile(); - } - - public static string TestAssemblyLocationInfoMethod() - { - return SystemInfo.AssemblyLocationInfo(Assembly.GetCallingAssembly()); - } -#endif - - [Test] - public void TestGetTypeFromStringFullyQualified() - { - Type t; - - t = SystemInfo.GetTypeFromString("log4net.Tests.Util.SystemInfoTest,log4net.Tests", false, false); - Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case sensitive type load"); - - t = SystemInfo.GetTypeFromString("LOG4NET.TESTS.UTIL.SYSTEMINFOTEST,log4net.Tests", false, true); - Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case in-sensitive type load caps"); - - t = SystemInfo.GetTypeFromString("log4net.tests.util.systeminfotest,log4net.Tests", false, true); - Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case in-sensitive type load lower"); - } - - [Test][Platform(Include="Win")] - public void TestGetTypeFromStringCaseInsensitiveOnAssemblyName() - { - Type t; - - t = SystemInfo.GetTypeFromString("LOG4NET.TESTS.UTIL.SYSTEMINFOTEST,LOG4NET.TESTS", false, true); - Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case in-sensitive type load caps"); - - t = SystemInfo.GetTypeFromString("log4net.tests.util.systeminfotest,log4net.tests", false, true); - Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case in-sensitive type load lower"); - } - - [Test] - public void TestGetTypeFromStringRelative() - { - Type t; - - t = SystemInfo.GetTypeFromString("log4net.Tests.Util.SystemInfoTest", false, false); - Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case sensitive type load"); - - t = SystemInfo.GetTypeFromString("LOG4NET.TESTS.UTIL.SYSTEMINFOTEST", false, true); - Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case in-sensitive type load caps"); - - t = SystemInfo.GetTypeFromString("log4net.tests.util.systeminfotest", false, true); - Assert.AreSame(typeof(SystemInfoTest), t, "Test explicit case in-sensitive type load lower"); - } - - [Test] - public void TestGetTypeFromStringSearch() - { - Type t; - - t = SystemInfo.GetTypeFromString("log4net.Util.SystemInfo", false, false); - Assert.AreSame(typeof(SystemInfo), t, - string.Format("Test explicit case sensitive type load found {0} rather than {1}", - t.AssemblyQualifiedName, typeof(SystemInfo).AssemblyQualifiedName)); - - t = SystemInfo.GetTypeFromString("LOG4NET.UTIL.SYSTEMINFO", false, true); - Assert.AreSame(typeof(SystemInfo), t, "Test explicit case in-sensitive type load caps"); - - t = SystemInfo.GetTypeFromString("log4net.util.systeminfo", false, true); - Assert.AreSame(typeof(SystemInfo), t, "Test explicit case in-sensitive type load lower"); - } - - [Test, ExpectedException(typeof(TypeLoadException))] - public void TestGetTypeFromStringFails1() - { - Type t; - - t = SystemInfo.GetTypeFromString("LOG4NET.TESTS.UTIL.SYSTEMINFOTEST,LOG4NET.TESTS", false, false); - Assert.AreSame(null, t, "Test explicit case sensitive fails type load"); - - t = SystemInfo.GetTypeFromString("LOG4NET.TESTS.UTIL.SYSTEMINFOTEST,LOG4NET.TESTS", true, false); - } - - [Test, ExpectedException(typeof(TypeLoadException))] - public void TestGetTypeFromStringFails2() - { - Type t; - - t = SystemInfo.GetTypeFromString("LOG4NET.TESTS.UTIL.SYSTEMINFOTEST", false, false); - Assert.AreSame(null, t, "Test explicit case sensitive fails type load"); - - t = SystemInfo.GetTypeFromString("LOG4NET.TESTS.UTIL.SYSTEMINFOTEST", true, false); - } - } -} diff --git a/src/log4net.Tests/Util/TransformTest.cs b/src/log4net.Tests/Util/TransformTest.cs deleted file mode 100644 index 7d4026a8..00000000 --- a/src/log4net.Tests/Util/TransformTest.cs +++ /dev/null @@ -1,45 +0,0 @@ -#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.Util; - -using NUnit.Framework; - -namespace log4net.Tests.Util { - - [TestFixture] - public class TransformTest - { - [Test] - public void MaskXmlInvalidCharactersAllowsJapaneseCharacters() - { - string kome = "\u203B"; - Assert.AreEqual(kome, Transform.MaskXmlInvalidCharacters(kome, "?")); - } - - [Test] - public void MaskXmlInvalidCharactersMasks0Char() - { - string c = "\u0000"; - Assert.AreEqual("?", Transform.MaskXmlInvalidCharacters(c, "?")); - } - } -} diff --git a/src/log4net.Tests/Utils.cs b/src/log4net.Tests/Utils.cs deleted file mode 100644 index 4e98283c..00000000 --- a/src/log4net.Tests/Utils.cs +++ /dev/null @@ -1,111 +0,0 @@ -#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 System.Reflection; - -namespace log4net.Tests -{ - /// - /// Summary description for Class1. - /// - public class Utils - { - private Utils() - { - } - - public static object CreateInstance(string targetType) - { - return CreateInstance(Type.GetType(targetType, true, true)); - } - - public static object CreateInstance(Type targetType) - { - return targetType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Type[0], null).Invoke(null); - } - - public static object InvokeMethod(object target, string name, params object[] args) - { - return target.GetType().GetMethod(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance, null, GetTypesArray(args), null).Invoke(target, args); - } - - public static object InvokeMethod(Type target, string name, params object[] args) - { - return target.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, GetTypesArray(args), null).Invoke(null, args); - } - - public static object GetField(object target, string name) - { - return target.GetType().GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).GetValue(target); - } - - public static void SetField(object target, string name, object val) - { - target.GetType().GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).SetValue(target, val); - } - - public static object GetProperty(object target, string name) - { - return target.GetType().GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).GetValue(target, null); - } - - public static void SetProperty(object target, string name, object val) - { - target.GetType().GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).SetValue(target, val, null); - } - - public static object GetProperty(object target, string name, params object[] index) - { - return target.GetType().GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).GetValue(target, index); - } - - public static void SetProperty(object target, string name, object val, params object[] index) - { - target.GetType().GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).SetValue(target, val, index); - } - - private static Type[] GetTypesArray(object[] args) - { - Type[] types = new Type[args.Length]; - - for(int i = 0; i < args.Length; i++) - { - if (args[i] == null) - { - types[i] = typeof(object); - } - else - { - types[i] = args[i].GetType(); - } - } - - return types; - } - - internal const string PROPERTY_KEY = "prop1"; - - internal static void RemovePropertyFromAllContexts() { - GlobalContext.Properties.Remove(PROPERTY_KEY); - ThreadContext.Properties.Remove(PROPERTY_KEY); - LogicalThreadContext.Properties.Remove(PROPERTY_KEY); - } - } -} \ No newline at end of file diff --git a/src/log4net.Tests/log4net.Tests.vs2008.csproj b/src/log4net.Tests/log4net.Tests.vs2008.csproj deleted file mode 100644 index 5492c243..00000000 --- a/src/log4net.Tests/log4net.Tests.vs2008.csproj +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - Local - 9.0.30729 - 2.0 - {B0530F10-0238-49A9-93B0-8EF412E90BCF} - Debug - AnyCPU - - - - - log4net.Tests - - - JScript - Grid - IE50 - false - Library - log4net.Tests - - - - - - - 2.0 - v3.5 - - - ..\..\build\bin\log4net.Tests\net\2.0\debug\ - false - 285212672 - false - - - TRACE;DEBUG - - - true - 4096 - false - false - false - false - 4 - full - prompt - - - ..\..\build\bin\log4net.Tests\net\2.0\release\ - false - 285212672 - false - - - TRACE - - - true - 4096 - true - false - false - false - 4 - pdbonly - prompt - - - - False - ..\..\lib\test\nunit.framework.dll - - - System - - - - 3.5 - - - System.Data - - - System.Runtime.Remoting - - - System.XML - - - - - AssemblyVersionInfo.cs - Code - - - - - - - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - - - Code - - - Code - - - - - - - Code - - - Code - - - Code - - - Code - - - - - {181FE707-E161-4722-9F38-6AAAB6FAA106} - log4net.vs2008 - - - - - - - - - - diff --git a/src/log4net.Tests/log4net.Tests.vs2010.csproj b/src/log4net.Tests/log4net.Tests.vs2010.csproj deleted file mode 100644 index 392c4f21..00000000 --- a/src/log4net.Tests/log4net.Tests.vs2010.csproj +++ /dev/null @@ -1,249 +0,0 @@ - - - - - Local - 9.0.30729 - 2.0 - {B0530F10-0238-49A9-93B0-8EF412E90BCF} - Debug - AnyCPU - - - - - log4net.Tests - - - JScript - Grid - IE50 - false - Library - log4net.Tests - - - - - - - 3.5 - v4.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - ..\..\build\bin\log4net.Tests\net\4.0\debug\ - false - 285212672 - false - - - TRACE;DEBUG;DOTNET;FRAMEWORK_3_5_OR_ABOVE;FRAMEWORK_4_0_OR_ABOVE - - - true - 4096 - false - false - false - false - 4 - full - prompt - AllRules.ruleset - - - ..\..\build\bin\log4net.Tests\net\4.0\release\ - false - 285212672 - false - - - TRACE;DOTNET;FRAMEWORK_3_5_OR_ABOVE;FRAMEWORK_4_0_OR_ABOVE - - - true - 4096 - true - false - false - false - 4 - pdbonly - prompt - AllRules.ruleset - - - - False - ..\..\lib\test\nunit.framework.dll - - - System - - - - 3.5 - - - System.Data - - - System.Runtime.Remoting - - - System.XML - - - - - AssemblyVersionInfo.cs - Code - - - - - - - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - - Code - - - Code - - - - - Code - - - Code - - - - - - - Code - - - Code - - - Code - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - {181fe707-e161-4722-9f38-6aaab6faa106} - log4net.vs2010 - - - - - - - - - - diff --git a/src/log4net.Tests/log4net.Tests.vs2012.csproj b/src/log4net.Tests/log4net.Tests.vs2012.csproj deleted file mode 100644 index 4295e274..00000000 --- a/src/log4net.Tests/log4net.Tests.vs2012.csproj +++ /dev/null @@ -1,252 +0,0 @@ - - - - - Local - 9.0.30729 - 2.0 - {B0530F10-0238-49A9-93B0-8EF412E90BCF} - Debug - AnyCPU - - - - - log4net.Tests - - - JScript - Grid - IE50 - false - Library - log4net.Tests - - - - - - - 3.5 - v4.5 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - ..\..\build\bin\log4net.Tests\net\4.5\debug\ - false - 285212672 - false - - - TRACE;DEBUG;DOTNET;FRAMEWORK_3_5_OR_ABOVE;FRAMEWORK_4_0_OR_ABOVE;FRAMEWORK_4_5_OR_ABOVE - - - true - 4096 - false - false - false - false - 4 - full - prompt - AllRules.ruleset - - - ..\..\build\bin\log4net.Tests\net\4.5\release\ - false - 285212672 - false - - - TRACE;DOTNET;FRAMEWORK_3_5_OR_ABOVE;FRAMEWORK_4_0_OR_ABOVE;FRAMEWORK_4_5_OR_ABOVE - - - true - 4096 - true - false - false - false - 4 - pdbonly - prompt - AllRules.ruleset - - - - False - ..\..\lib\test\nunit.framework.dll - - - System - - - - 3.5 - - - System.Data - - - System.Runtime.Remoting - - - System.XML - - - - - AssemblyVersionInfo.cs - Code - - - - - - - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - - Code - - - Code - - - - - Code - - - Code - - - - - - - Code - - - Code - - - Code - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - {181fe707-e161-4722-9f38-6aaab6faa106} - log4net.vs2012 - - - - - - - - - - - - - diff --git a/src/log4net/Appender/AdoNetAppender.cs b/src/log4net/Appender/AdoNetAppender.cs deleted file mode 100644 index b7fb7142..00000000 --- a/src/log4net/Appender/AdoNetAppender.cs +++ /dev/null @@ -1,1246 +0,0 @@ -#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 System.Collections; -using System.Configuration; -using System.Data; -using System.IO; - -using log4net.Util; -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Appender that logs to a database. - /// - /// - /// - /// appends logging events to a table within a - /// database. The appender can be configured to specify the connection - /// string by setting the property. - /// The connection type (provider) can be specified by setting the - /// property. For more information on database connection strings for - /// your specific database see http://www.connectionstrings.com/. - /// - /// - /// Records are written into the database either using a prepared - /// statement or a stored procedure. The property - /// is set to (System.Data.CommandType.Text) to specify a prepared statement - /// or to (System.Data.CommandType.StoredProcedure) to specify a stored - /// procedure. - /// - /// - /// The prepared statement text or the name of the stored procedure - /// must be set in the property. - /// - /// - /// The prepared statement or stored procedure can take a number - /// of parameters. Parameters are added using the - /// method. This adds a single to the - /// ordered list of parameters. The - /// type may be subclassed if required to provide database specific - /// functionality. The specifies - /// the parameter name, database type, size, and how the value should - /// be generated using a . - /// - /// - /// - /// An example of a SQL Server table that could be logged to: - /// - /// CREATE TABLE [dbo].[Log] ( - /// [ID] [int] IDENTITY (1, 1) NOT NULL , - /// [Date] [datetime] NOT NULL , - /// [Thread] [varchar] (255) NOT NULL , - /// [Level] [varchar] (20) NOT NULL , - /// [Logger] [varchar] (255) NOT NULL , - /// [Message] [varchar] (4000) NOT NULL - /// ) ON [PRIMARY] - /// - /// - /// - /// An example configuration to log to the above table: - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Julian Biddle - /// Nicko Cadell - /// Gert Driesen - /// Lance Nehring - public class AdoNetAppender : BufferingAppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// Public default constructor to initialize a new instance of this class. - /// - public AdoNetAppender() - { - m_connectionType = "System.Data.OleDb.OleDbConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; - m_useTransactions = true; - m_commandType = System.Data.CommandType.Text; - m_parameters = new ArrayList(); - m_reconnectOnError = false; - } - - #endregion // Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the database connection string that is used to connect to - /// the database. - /// - /// - /// The database connection string used to connect to the database. - /// - /// - /// - /// The connections string is specific to the connection type. - /// See for more information. - /// - /// - /// Connection string for MS Access via ODBC: - /// "DSN=MS Access Database;UID=admin;PWD=;SystemDB=C:\data\System.mdw;SafeTransactions = 0;FIL=MS Access;DriverID = 25;DBQ=C:\data\train33.mdb" - /// - /// Another connection string for MS Access via ODBC: - /// "Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\Work\cvs_root\log4net-1.2\access.mdb;UID=;PWD=;" - /// - /// Connection string for MS Access via OLE DB: - /// "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Work\cvs_root\log4net-1.2\access.mdb;User Id=;Password=;" - /// - public string ConnectionString - { - get { return m_connectionString; } - set { m_connectionString = value; } - } - - /// - /// The appSettings key from App.Config that contains the connection string. - /// - public string AppSettingsKey - { - get { return m_appSettingsKey; } - set { m_appSettingsKey = value; } - } - - /// - /// The connectionStrings key from App.Config that contains the connection string. - /// - /// - /// This property requires at least .NET 2.0. - /// - public string ConnectionStringName - { - get { return m_connectionStringName; } - set { m_connectionStringName = value; } - } - - /// - /// Gets or sets the type name of the connection - /// that should be created. - /// - /// - /// The type name of the connection. - /// - /// - /// - /// The type name of the ADO.NET provider to use. - /// - /// - /// The default is to use the OLE DB provider. - /// - /// - /// Use the OLE DB Provider. This is the default value. - /// System.Data.OleDb.OleDbConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// - /// Use the MS SQL Server Provider. - /// System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// - /// Use the ODBC Provider. - /// Microsoft.Data.Odbc.OdbcConnection,Microsoft.Data.Odbc,version=1.0.3300.0,publicKeyToken=b77a5c561934e089,culture=neutral - /// This is an optional package that you can download from - /// http://msdn.microsoft.com/downloads - /// search for ODBC .NET Data Provider. - /// - /// Use the Oracle Provider. - /// System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// This is an optional package that you can download from - /// http://msdn.microsoft.com/downloads - /// search for .NET Managed Provider for Oracle. - /// - public string ConnectionType - { - get { return m_connectionType; } - set { m_connectionType = value; } - } - - /// - /// Gets or sets the command text that is used to insert logging events - /// into the database. - /// - /// - /// The command text used to insert logging events into the database. - /// - /// - /// - /// Either the text of the prepared statement or the - /// name of the stored procedure to execute to write into - /// the database. - /// - /// - /// The property determines if - /// this text is a prepared statement or a stored procedure. - /// - /// - public string CommandText - { - get { return m_commandText; } - set { m_commandText = value; } - } - - /// - /// Gets or sets the command type to execute. - /// - /// - /// The command type to execute. - /// - /// - /// - /// This value may be either (System.Data.CommandType.Text) to specify - /// that the is a prepared statement to execute, - /// or (System.Data.CommandType.StoredProcedure) to specify that the - /// property is the name of a stored procedure - /// to execute. - /// - /// - /// The default value is (System.Data.CommandType.Text). - /// - /// - public CommandType CommandType - { - get { return m_commandType; } - set { m_commandType = value; } - } - - /// - /// Should transactions be used to insert logging events in the database. - /// - /// - /// true if transactions should be used to insert logging events in - /// the database, otherwise false. The default value is true. - /// - /// - /// - /// Gets or sets a value that indicates whether transactions should be used - /// to insert logging events in the database. - /// - /// - /// When set a single transaction will be used to insert the buffered events - /// into the database. Otherwise each event will be inserted without using - /// an explicit transaction. - /// - /// - public bool UseTransactions - { - get { return m_useTransactions; } - set { m_useTransactions = value; } - } - - /// - /// Gets or sets the used to call the NetSend method. - /// - /// - /// The used to call the NetSend method. - /// - /// - /// - /// Unless a specified here for this appender - /// the is queried for the - /// security context to use. The default behavior is to use the security context - /// of the current thread. - /// - /// - public SecurityContext SecurityContext - { - get { return m_securityContext; } - set { m_securityContext = value; } - } - - /// - /// Should this appender try to reconnect to the database on error. - /// - /// - /// true if the appender should try to reconnect to the database after an - /// error has occurred, otherwise false. The default value is false, - /// i.e. not to try to reconnect. - /// - /// - /// - /// The default behaviour is for the appender not to try to reconnect to the - /// database if an error occurs. Subsequent logging events are discarded. - /// - /// - /// To force the appender to attempt to reconnect to the database set this - /// property to true. - /// - /// - /// When the appender attempts to connect to the database there may be a - /// delay of up to the connection timeout specified in the connection string. - /// This delay will block the calling application's thread. - /// Until the connection can be reestablished this potential delay may occur multiple times. - /// - /// - public bool ReconnectOnError - { - get { return m_reconnectOnError; } - set { m_reconnectOnError = value; } - } - - #endregion // Public Instance Properties - - #region Protected Instance Properties - - /// - /// Gets or sets the underlying . - /// - /// - /// The underlying . - /// - /// - /// creates a to insert - /// logging events into a database. Classes deriving from - /// can use this property to get or set this . Use the - /// underlying returned from if - /// you require access beyond that which provides. - /// - protected IDbConnection Connection - { - get { return m_dbConnection; } - set { m_dbConnection = value; } - } - - #endregion // Protected Instance Properties - - #region Implementation of IOptionHandler - - /// - /// Initialize the appender based on the options set - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - override public void ActivateOptions() - { - base.ActivateOptions(); - - // Are we using a command object - m_usePreparedCommand = (m_commandText != null && m_commandText.Length > 0); - - if (m_securityContext == null) - { - m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); - } - - InitializeDatabaseConnection(); - InitializeDatabaseCommand(); - } - - #endregion - - #region Override implementation of AppenderSkeleton - - /// - /// Override the parent method to close the database - /// - /// - /// - /// Closes the database command and database connection. - /// - /// - override protected void OnClose() - { - base.OnClose(); - DisposeCommand(false); - DiposeConnection(); - } - - #endregion - - #region Override implementation of BufferingAppenderSkeleton - - /// - /// Inserts the events into the database. - /// - /// The events to insert into the database. - /// - /// - /// Insert all the events specified in the - /// array into the database. - /// - /// - override protected void SendBuffer(LoggingEvent[] events) - { - if (m_reconnectOnError && (m_dbConnection == null || m_dbConnection.State != ConnectionState.Open)) - { - LogLog.Debug(declaringType, "Attempting to reconnect to database. Current Connection State: " + ((m_dbConnection==null)?SystemInfo.NullText:m_dbConnection.State.ToString()) ); - - InitializeDatabaseConnection(); - InitializeDatabaseCommand(); - } - - // Check that the connection exists and is open - if (m_dbConnection != null && m_dbConnection.State == ConnectionState.Open) - { - if (m_useTransactions) - { - // Create transaction - // NJC - Do this on 2 lines because it can confuse the debugger - IDbTransaction dbTran = null; - try - { - dbTran = m_dbConnection.BeginTransaction(); - - SendBuffer(dbTran, events); - - // commit transaction - dbTran.Commit(); - } - catch(Exception ex) - { - // rollback the transaction - if (dbTran != null) - { - try - { - dbTran.Rollback(); - } - catch(Exception) - { - // Ignore exception - } - } - - // Can't insert into the database. That's a bad thing - ErrorHandler.Error("Exception while writing to database", ex); - } - } - else - { - // Send without transaction - SendBuffer(null, events); - } - } - } - - #endregion // Override implementation of BufferingAppenderSkeleton - - #region Public Instance Methods - - /// - /// Adds a parameter to the command. - /// - /// The parameter to add to the command. - /// - /// - /// Adds a parameter to the ordered list of command parameters. - /// - /// - public void AddParameter(AdoNetAppenderParameter parameter) - { - m_parameters.Add(parameter); - } - - - #endregion // Public Instance Methods - - #region Protected Instance Methods - - /// - /// Writes the events to the database using the transaction specified. - /// - /// The transaction that the events will be executed under. - /// The array of events to insert into the database. - /// - /// - /// The transaction argument can be null if the appender has been - /// configured not to use transactions. See - /// property for more information. - /// - /// - virtual protected void SendBuffer(IDbTransaction dbTran, LoggingEvent[] events) - { - if (m_usePreparedCommand) - { - // Send buffer using the prepared command object - - if (m_dbCommand != null) - { - if (dbTran != null) - { - m_dbCommand.Transaction = dbTran; - } - - // run for all events - foreach(LoggingEvent e in events) - { - // Set the parameter values - foreach(AdoNetAppenderParameter param in m_parameters) - { - param.FormatValue(m_dbCommand, e); - } - - // Execute the query - m_dbCommand.ExecuteNonQuery(); - } - } - } - else - { - // create a new command - using(IDbCommand dbCmd = m_dbConnection.CreateCommand()) - { - if (dbTran != null) - { - dbCmd.Transaction = dbTran; - } - - // run for all events - foreach(LoggingEvent e in events) - { - // Get the command text from the Layout - string logStatement = GetLogStatement(e); - - LogLog.Debug(declaringType, "LogStatement ["+logStatement+"]"); - - dbCmd.CommandText = logStatement; - dbCmd.ExecuteNonQuery(); - } - } - } - } - - /// - /// Formats the log message into database statement text. - /// - /// The event being logged. - /// - /// This method can be overridden by subclasses to provide - /// more control over the format of the database statement. - /// - /// - /// Text that can be passed to a . - /// - virtual protected string GetLogStatement(LoggingEvent logEvent) - { - if (Layout == null) - { - ErrorHandler.Error("AdoNetAppender: No Layout specified."); - return ""; - } - else - { - StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture); - Layout.Format(writer, logEvent); - return writer.ToString(); - } - } - - /// - /// Creates an instance used to connect to the database. - /// - /// - /// This method is called whenever a new IDbConnection is needed (i.e. when a reconnect is necessary). - /// - /// The of the object. - /// The connectionString output from the ResolveConnectionString method. - /// An instance with a valid connection string. - virtual protected IDbConnection CreateConnection(Type connectionType, string connectionString) - { - IDbConnection connection = (IDbConnection)Activator.CreateInstance(connectionType); - connection.ConnectionString = connectionString; - return connection; - } - - /// - /// Resolves the connection string from the ConnectionString, ConnectionStringName, or AppSettingsKey - /// property. - /// - /// - /// ConnectiongStringName is only supported on .NET 2.0 and higher. - /// - /// Additional information describing the connection string. - /// A connection string used to connect to the database. - virtual protected string ResolveConnectionString(out string connectionStringContext) - { - if (m_connectionString != null && m_connectionString.Length > 0) - { - connectionStringContext = "ConnectionString"; - return m_connectionString; - } - - if (!String.IsNullOrEmpty(m_connectionStringName)) - { - ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[m_connectionStringName]; - if (settings != null) - { - connectionStringContext = "ConnectionStringName"; - return settings.ConnectionString; - } - else - { - throw new LogException("Unable to find [" + m_connectionStringName + "] ConfigurationManager.ConnectionStrings item"); - } - } - - if (m_appSettingsKey != null && m_appSettingsKey.Length > 0) - { - connectionStringContext = "AppSettingsKey"; - string appSettingsConnectionString = SystemInfo.GetAppSetting(m_appSettingsKey); - if (appSettingsConnectionString == null || appSettingsConnectionString.Length == 0) - { - throw new LogException("Unable to find [" + m_appSettingsKey + "] AppSettings key."); - } - return appSettingsConnectionString; - } - - connectionStringContext = "Unable to resolve connection string from ConnectionString, ConnectionStrings, or AppSettings."; - return string.Empty; - } - - /// - /// Retrieves the class type of the ADO.NET provider. - /// - /// - /// - /// Gets the Type of the ADO.NET provider to use to connect to the - /// database. This method resolves the type specified in the - /// property. - /// - /// - /// Subclasses can override this method to return a different type - /// if necessary. - /// - /// - /// The of the ADO.NET provider - virtual protected Type ResolveConnectionType() - { - try - { - return SystemInfo.GetTypeFromString(m_connectionType, true, false); - } - catch(Exception ex) - { - ErrorHandler.Error("Failed to load connection type ["+m_connectionType+"]", ex); - throw; - } - } - - #endregion // Protected Instance Methods - - #region Private Instance Methods - - /// - /// Prepares the database command and initialize the parameters. - /// - private void InitializeDatabaseCommand() - { - if (m_dbConnection != null && m_usePreparedCommand) - { - try - { - DisposeCommand(false); - - // Create the command object - m_dbCommand = m_dbConnection.CreateCommand(); - - // Set the command string - m_dbCommand.CommandText = m_commandText; - - // Set the command type - m_dbCommand.CommandType = m_commandType; - } - catch (Exception e) - { - ErrorHandler.Error("Could not create database command [" + m_commandText + "]", e); - - DisposeCommand(true); - } - - if (m_dbCommand != null) - { - try - { - foreach (AdoNetAppenderParameter param in m_parameters) - { - try - { - param.Prepare(m_dbCommand); - } - catch (Exception e) - { - ErrorHandler.Error("Could not add database command parameter [" + param.ParameterName + "]", e); - throw; - } - } - } - catch - { - DisposeCommand(true); - } - } - - if (m_dbCommand != null) - { - try - { - // Prepare the command statement. - m_dbCommand.Prepare(); - } - catch (Exception e) - { - ErrorHandler.Error("Could not prepare database command [" + m_commandText + "]", e); - - DisposeCommand(true); - } - } - } - } - - /// - /// Connects to the database. - /// - private void InitializeDatabaseConnection() - { - string connectionStringContext = "Unable to determine connection string context."; - string resolvedConnectionString = string.Empty; - - try - { - DisposeCommand(true); - DiposeConnection(); - - // Set the connection string - resolvedConnectionString = ResolveConnectionString(out connectionStringContext); - - m_dbConnection = CreateConnection(ResolveConnectionType(), resolvedConnectionString); - - using (SecurityContext.Impersonate(this)) - { - // Open the database connection - m_dbConnection.Open(); - } - } - catch (Exception e) - { - // Sadly, your connection string is bad. - ErrorHandler.Error("Could not open database connection [" + resolvedConnectionString + "]. Connection string context [" + connectionStringContext + "].", e); - - m_dbConnection = null; - } - } - - /// - /// Cleanup the existing command. - /// - /// - /// If true, a message will be written using LogLog.Warn if an exception is encountered when calling Dispose. - /// - private void DisposeCommand(bool ignoreException) - { - // Cleanup any existing command or connection - if (m_dbCommand != null) - { - try - { - m_dbCommand.Dispose(); - } - catch (Exception ex) - { - if (!ignoreException) - { - LogLog.Warn(declaringType, "Exception while disposing cached command object", ex); - } - } - m_dbCommand = null; - } - } - - /// - /// Cleanup the existing connection. - /// - /// - /// Calls the IDbConnection's method. - /// - private void DiposeConnection() - { - if (m_dbConnection != null) - { - try - { - m_dbConnection.Close(); - } - catch (Exception ex) - { - LogLog.Warn(declaringType, "Exception while disposing cached connection object", ex); - } - m_dbConnection = null; - } - } - - #endregion // Private Instance Methods - - #region Protected Instance Fields - - /// - /// Flag to indicate if we are using a command object - /// - /// - /// - /// Set to true when the appender is to use a prepared - /// statement or stored procedure to insert into the database. - /// - /// - protected bool m_usePreparedCommand; - - /// - /// The list of objects. - /// - /// - /// - /// The list of objects. - /// - /// - protected ArrayList m_parameters; - - #endregion // Protected Instance Fields - - #region Private Instance Fields - - /// - /// The security context to use for privileged calls - /// - private SecurityContext m_securityContext; - - /// - /// The that will be used - /// to insert logging events into a database. - /// - private IDbConnection m_dbConnection; - - /// - /// The database command. - /// - private IDbCommand m_dbCommand; - - /// - /// Database connection string. - /// - private string m_connectionString; - - /// - /// The appSettings key from App.Config that contains the connection string. - /// - private string m_appSettingsKey; - - /// - /// The connectionStrings key from App.Config that contains the connection string. - /// - private string m_connectionStringName; - - /// - /// String type name of the type name. - /// - private string m_connectionType; - - /// - /// The text of the command. - /// - private string m_commandText; - - /// - /// The command type. - /// - private CommandType m_commandType; - - /// - /// Indicates whether to use transactions when writing to the database. - /// - private bool m_useTransactions; - - /// - /// Indicates whether to use transactions when writing to the database. - /// - private bool m_reconnectOnError; - - #endregion // Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the AdoNetAppender class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(AdoNetAppender); - - #endregion Private Static Fields - } - - /// - /// Parameter type used by the . - /// - /// - /// - /// This class provides the basic database parameter properties - /// as defined by the interface. - /// - /// This type can be subclassed to provide database specific - /// functionality. The two methods that are called externally are - /// and . - /// - /// - public class AdoNetAppenderParameter - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// Default constructor for the AdoNetAppenderParameter class. - /// - public AdoNetAppenderParameter() - { - m_precision = 0; - m_scale = 0; - m_size = 0; - } - - #endregion // Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the name of this parameter. - /// - /// - /// The name of this parameter. - /// - /// - /// - /// The name of this parameter. The parameter name - /// must match up to a named parameter to the SQL stored procedure - /// or prepared statement. - /// - /// - public string ParameterName - { - get { return m_parameterName; } - set { m_parameterName = value; } - } - - /// - /// Gets or sets the database type for this parameter. - /// - /// - /// The database type for this parameter. - /// - /// - /// - /// The database type for this parameter. This property should - /// be set to the database type from the - /// enumeration. See . - /// - /// - /// This property is optional. If not specified the ADO.NET provider - /// will attempt to infer the type from the value. - /// - /// - /// - public DbType DbType - { - get { return m_dbType; } - set - { - m_dbType = value; - m_inferType = false; - } - } - - /// - /// Gets or sets the precision for this parameter. - /// - /// - /// The precision for this parameter. - /// - /// - /// - /// The maximum number of digits used to represent the Value. - /// - /// - /// This property is optional. If not specified the ADO.NET provider - /// will attempt to infer the precision from the value. - /// - /// - /// - public byte Precision - { - get { return m_precision; } - set { m_precision = value; } - } - - /// - /// Gets or sets the scale for this parameter. - /// - /// - /// The scale for this parameter. - /// - /// - /// - /// The number of decimal places to which Value is resolved. - /// - /// - /// This property is optional. If not specified the ADO.NET provider - /// will attempt to infer the scale from the value. - /// - /// - /// - public byte Scale - { - get { return m_scale; } - set { m_scale = value; } - } - - /// - /// Gets or sets the size for this parameter. - /// - /// - /// The size for this parameter. - /// - /// - /// - /// The maximum size, in bytes, of the data within the column. - /// - /// - /// This property is optional. If not specified the ADO.NET provider - /// will attempt to infer the size from the value. - /// - /// - /// For BLOB data types like VARCHAR(max) it may be impossible to infer the value automatically, use -1 as the size in this case. - /// - /// - /// - public int Size - { - get { return m_size; } - set { m_size = value; } - } - - /// - /// Gets or sets the to use to - /// render the logging event into an object for this - /// parameter. - /// - /// - /// The used to render the - /// logging event into an object for this parameter. - /// - /// - /// - /// The that renders the value for this - /// parameter. - /// - /// - /// The can be used to adapt - /// any into a - /// for use in the property. - /// - /// - public IRawLayout Layout - { - get { return m_layout; } - set { m_layout = value; } - } - - #endregion // Public Instance Properties - - #region Public Instance Methods - - /// - /// Prepare the specified database command object. - /// - /// The command to prepare. - /// - /// - /// Prepares the database command object by adding - /// this parameter to its collection of parameters. - /// - /// - virtual public void Prepare(IDbCommand command) - { - // Create a new parameter - IDbDataParameter param = command.CreateParameter(); - - // Set the parameter properties - param.ParameterName = m_parameterName; - - if (!m_inferType) - { - param.DbType = m_dbType; - } - if (m_precision != 0) - { - param.Precision = m_precision; - } - if (m_scale != 0) - { - param.Scale = m_scale; - } - if (m_size != 0) - { - param.Size = m_size; - } - - // Add the parameter to the collection of params - command.Parameters.Add(param); - } - - /// - /// Renders the logging event and set the parameter value in the command. - /// - /// The command containing the parameter. - /// The event to be rendered. - /// - /// - /// Renders the logging event using this parameters layout - /// object. Sets the value of the parameter on the command object. - /// - /// - virtual public void FormatValue(IDbCommand command, LoggingEvent loggingEvent) - { - // Lookup the parameter - IDbDataParameter param = (IDbDataParameter)command.Parameters[m_parameterName]; - - // Format the value - object formattedValue = Layout.Format(loggingEvent); - - // If the value is null then convert to a DBNull - if (formattedValue == null) - { - formattedValue = DBNull.Value; - } - - param.Value = formattedValue; - } - - #endregion // Public Instance Methods - - #region Private Instance Fields - - /// - /// The name of this parameter. - /// - private string m_parameterName; - - /// - /// The database type for this parameter. - /// - private DbType m_dbType; - - /// - /// Flag to infer type rather than use the DbType - /// - private bool m_inferType = true; - - /// - /// The precision for this parameter. - /// - private byte m_precision; - - /// - /// The scale for this parameter. - /// - private byte m_scale; - - /// - /// The size for this parameter. - /// - private int m_size; - - /// - /// The to use to render the - /// logging event into an object for this parameter. - /// - private IRawLayout m_layout; - - #endregion // Private Instance Fields - } -} diff --git a/src/log4net/Appender/AnsiColorTerminalAppender.cs b/src/log4net/Appender/AnsiColorTerminalAppender.cs deleted file mode 100644 index 58013d8e..00000000 --- a/src/log4net/Appender/AnsiColorTerminalAppender.cs +++ /dev/null @@ -1,569 +0,0 @@ -#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 System.Text; -using System.Globalization; - -using log4net.Core; -using log4net.Layout; -using log4net.Util; - -namespace log4net.Appender -{ - /// - /// Appends logging events to the terminal using ANSI color escape sequences. - /// - /// - /// - /// AnsiColorTerminalAppender appends log events to the standard output stream - /// or the error output stream using a layout specified by the - /// user. It also allows the color of a specific level of message to be set. - /// - /// - /// This appender expects the terminal to understand the VT100 control set - /// in order to interpret the color codes. If the terminal or console does not - /// understand the control codes the behavior is not defined. - /// - /// - /// By default, all output is written to the console's standard output stream. - /// The property can be set to direct the output to the - /// error stream. - /// - /// - /// NOTE: This appender writes each message to the System.Console.Out or - /// System.Console.Error that is set at the time the event is appended. - /// Therefore it is possible to programmatically redirect the output of this appender - /// (for example NUnit does this to capture program output). While this is the desired - /// behavior of this appender it may have security implications in your application. - /// - /// - /// When configuring the ANSI colored terminal appender, a mapping should be - /// specified to map a logging level to a color. For example: - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The Level is the standard log4net logging level and ForeColor and BackColor can be any - /// of the following values: - /// - /// Blue - /// Green - /// Red - /// White - /// Yellow - /// Purple - /// Cyan - /// - /// These color values cannot be combined together to make new colors. - /// - /// - /// The attributes can be any combination of the following: - /// - /// Brightforeground is brighter - /// Dimforeground is dimmer - /// Underscoremessage is underlined - /// Blinkforeground is blinking (does not work on all terminals) - /// Reverseforeground and background are reversed - /// Hiddenoutput is hidden - /// Strikethroughmessage has a line through it - /// - /// While any of these attributes may be combined together not all combinations - /// work well together, for example setting both Bright and Dim attributes makes - /// no sense. - /// - /// - /// Patrick Wagstrom - /// Nicko Cadell - public class AnsiColorTerminalAppender : AppenderSkeleton - { - #region Colors Enum - - /// - /// The enum of possible display attributes - /// - /// - /// - /// The following flags can be combined together to - /// form the ANSI color attributes. - /// - /// - /// - [Flags] - public enum AnsiAttributes : int - { - /// - /// text is bright - /// - Bright = 1, - /// - /// text is dim - /// - Dim = 2, - - /// - /// text is underlined - /// - Underscore = 4, - - /// - /// text is blinking - /// - /// - /// Not all terminals support this attribute - /// - Blink = 8, - - /// - /// text and background colors are reversed - /// - Reverse = 16, - - /// - /// text is hidden - /// - Hidden = 32, - - /// - /// text is displayed with a strikethrough - /// - Strikethrough = 64, - - /// - /// text color is light - /// - Light = 128 - } - - /// - /// The enum of possible foreground or background color values for - /// use with the color mapping method - /// - /// - /// - /// The output can be in one for the following ANSI colors. - /// - /// - /// - public enum AnsiColor : int - { - /// - /// color is black - /// - Black = 0, - - /// - /// color is red - /// - Red = 1, - - /// - /// color is green - /// - Green = 2, - - /// - /// color is yellow - /// - Yellow = 3, - - /// - /// color is blue - /// - Blue = 4, - - /// - /// color is magenta - /// - Magenta = 5, - - /// - /// color is cyan - /// - Cyan = 6, - - /// - /// color is white - /// - White = 7 - } - - #endregion - - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// The instance of the class is set up to write - /// to the standard output stream. - /// - public AnsiColorTerminalAppender() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Target is the value of the console output stream. - /// - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - virtual public string Target - { - get { return m_writeToErrorStream ? ConsoleError : ConsoleOut; } - set - { - string trimmedTargetName = value.Trim(); - - if (string.Compare(ConsoleError, trimmedTargetName, true, CultureInfo.InvariantCulture) == 0) - { - m_writeToErrorStream = true; - } - else - { - m_writeToErrorStream = false; - } - } - } - - /// - /// Add a mapping of level to color - /// - /// The mapping to add - /// - /// - /// Add a mapping to this appender. - /// Each mapping defines the foreground and background colours - /// for a level. - /// - /// - public void AddMapping(LevelColors mapping) - { - m_levelMapping.Add(mapping); - } - - #endregion Public Instance Properties - - #region Override implementation of AppenderSkeleton - - /// - /// This method is called by the method. - /// - /// The event to log. - /// - /// - /// Writes the event to the console. - /// - /// - /// The format of the output will depend on the appender's layout. - /// - /// - override protected void Append(log4net.Core.LoggingEvent loggingEvent) - { - string loggingMessage = RenderLoggingEvent(loggingEvent); - - // see if there is a specified lookup. - LevelColors levelColors = m_levelMapping.Lookup(loggingEvent.Level) as LevelColors; - if (levelColors != null) - { - // Prepend the Ansi Color code - loggingMessage = levelColors.CombinedColor + loggingMessage; - } - - // on most terminals there are weird effects if we don't clear the background color - // before the new line. This checks to see if it ends with a newline, and if - // so, inserts the clear codes before the newline, otherwise the clear codes - // are inserted afterwards. - if (loggingMessage.Length > 1) - { - if (loggingMessage.EndsWith("\r\n") || loggingMessage.EndsWith("\n\r")) - { - loggingMessage = loggingMessage.Insert(loggingMessage.Length - 2, PostEventCodes); - } - else if (loggingMessage.EndsWith("\n") || loggingMessage.EndsWith("\r")) - { - loggingMessage = loggingMessage.Insert(loggingMessage.Length - 1, PostEventCodes); - } - else - { - loggingMessage = loggingMessage + PostEventCodes; - } - } - else - { - if (loggingMessage[0] == '\n' || loggingMessage[0] == '\r') - { - loggingMessage = PostEventCodes + loggingMessage; - } - else - { - loggingMessage = loggingMessage + PostEventCodes; - } - } - - if (m_writeToErrorStream) - { - // Write to the error stream - Console.Error.Write(loggingMessage); - } - else - { - // Write to the output stream - Console.Write(loggingMessage); - } - - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - /// - /// Initialize the options for this appender - /// - /// - /// - /// Initialize the level to color mappings set on this appender. - /// - /// - public override void ActivateOptions() - { - base.ActivateOptions(); - m_levelMapping.ActivateOptions(); - } - - #endregion Override implementation of AppenderSkeleton - - #region Public Static Fields - - /// - /// The to use when writing to the Console - /// standard output stream. - /// - /// - /// - /// The to use when writing to the Console - /// standard output stream. - /// - /// - public const string ConsoleOut = "Console.Out"; - - /// - /// The to use when writing to the Console - /// standard error output stream. - /// - /// - /// - /// The to use when writing to the Console - /// standard error output stream. - /// - /// - public const string ConsoleError = "Console.Error"; - - #endregion Public Static Fields - - #region Private Instances Fields - - /// - /// Flag to write output to the error stream rather than the standard output stream - /// - private bool m_writeToErrorStream = false; - - /// - /// Mapping from level object to color value - /// - private LevelMapping m_levelMapping = new LevelMapping(); - - /// - /// Ansi code to reset terminal - /// - private const string PostEventCodes = "\x1b[0m"; - - #endregion Private Instances Fields - - #region LevelColors LevelMapping Entry - - /// - /// A class to act as a mapping between the level that a logging call is made at and - /// the color it should be displayed as. - /// - /// - /// - /// Defines the mapping between a level and the color it should be displayed in. - /// - /// - public class LevelColors : LevelMappingEntry - { - private AnsiColor m_foreColor; - private AnsiColor m_backColor; - private AnsiAttributes m_attributes; - private string m_combinedColor = ""; - - /// - /// The mapped foreground color for the specified level - /// - /// - /// - /// Required property. - /// The mapped foreground color for the specified level - /// - /// - public AnsiColor ForeColor - { - get { return m_foreColor; } - set { m_foreColor = value; } - } - - /// - /// The mapped background color for the specified level - /// - /// - /// - /// Required property. - /// The mapped background color for the specified level - /// - /// - public AnsiColor BackColor - { - get { return m_backColor; } - set { m_backColor = value; } - } - - /// - /// The color attributes for the specified level - /// - /// - /// - /// Required property. - /// The color attributes for the specified level - /// - /// - public AnsiAttributes Attributes - { - get { return m_attributes; } - set { m_attributes = value; } - } - - /// - /// Initialize the options for the object - /// - /// - /// - /// Combine the and together - /// and append the attributes. - /// - /// - public override void ActivateOptions() - { - base.ActivateOptions(); - - StringBuilder buf = new StringBuilder(); - - // Reset any existing codes - buf.Append("\x1b[0;"); - - int lightAdjustment = ((m_attributes & AnsiAttributes.Light) > 0) ? 60 : 0; - - // set the foreground color - buf.Append(30 + lightAdjustment + (int)m_foreColor); - buf.Append(';'); - - // set the background color - buf.Append(40 + lightAdjustment + (int)m_backColor); - - // set the attributes - if ((m_attributes & AnsiAttributes.Bright) > 0) - { - buf.Append(";1"); - } - if ((m_attributes & AnsiAttributes.Dim) > 0) - { - buf.Append(";2"); - } - if ((m_attributes & AnsiAttributes.Underscore) > 0) - { - buf.Append(";4"); - } - if ((m_attributes & AnsiAttributes.Blink) > 0) - { - buf.Append(";5"); - } - if ((m_attributes & AnsiAttributes.Reverse) > 0) - { - buf.Append(";7"); - } - if ((m_attributes & AnsiAttributes.Hidden) > 0) - { - buf.Append(";8"); - } - if ((m_attributes & AnsiAttributes.Strikethrough) > 0) - { - buf.Append(";9"); - } - - buf.Append('m'); - - m_combinedColor = buf.ToString(); - } - - /// - /// The combined , and - /// suitable for setting the ansi terminal color. - /// - internal string CombinedColor - { - get { return m_combinedColor; } - } - } - - #endregion // LevelColors LevelMapping Entry - } -} diff --git a/src/log4net/Appender/AppenderCollection.cs b/src/log4net/Appender/AppenderCollection.cs deleted file mode 100644 index 53ea990e..00000000 --- a/src/log4net/Appender/AppenderCollection.cs +++ /dev/null @@ -1,902 +0,0 @@ -#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 System.Collections; - -namespace log4net.Appender -{ - /// - /// A strongly-typed collection of objects. - /// - /// Nicko Cadell - public class AppenderCollection : ICollection, IList, IEnumerable, ICloneable - { - #region Interfaces - /// - /// Supports type-safe iteration over a . - /// - /// - public interface IAppenderCollectionEnumerator - { - /// - /// Gets the current element in the collection. - /// - IAppender Current { get; } - - /// - /// Advances the enumerator to the next element in the collection. - /// - /// - /// true if the enumerator was successfully advanced to the next element; - /// false if the enumerator has passed the end of the collection. - /// - /// - /// The collection was modified after the enumerator was created. - /// - bool MoveNext(); - - /// - /// Sets the enumerator to its initial position, before the first element in the collection. - /// - void Reset(); - } - #endregion - - private const int DEFAULT_CAPACITY = 16; - - #region Implementation (data) - - private IAppender[] m_array; - private int m_count = 0; - private int m_version = 0; - - #endregion - - #region Static Wrappers - - /// - /// Creates a read-only wrapper for a AppenderCollection instance. - /// - /// list to create a readonly wrapper arround - /// - /// An AppenderCollection wrapper that is read-only. - /// - public static AppenderCollection ReadOnly(AppenderCollection list) - { - if(list==null) throw new ArgumentNullException("list"); - - return new ReadOnlyAppenderCollection(list); - } - - #endregion - - #region Static Fields - - /// - /// An empty readonly static AppenderCollection - /// - public static readonly AppenderCollection EmptyCollection = ReadOnly(new AppenderCollection(0)); - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the AppenderCollection class - /// that is empty and has the default initial capacity. - /// - public AppenderCollection() - { - m_array = new IAppender[DEFAULT_CAPACITY]; - } - - /// - /// Initializes a new instance of the AppenderCollection class - /// that has the specified initial capacity. - /// - /// - /// The number of elements that the new AppenderCollection is initially capable of storing. - /// - public AppenderCollection(int capacity) - { - m_array = new IAppender[capacity]; - } - - /// - /// Initializes a new instance of the AppenderCollection class - /// that contains elements copied from the specified AppenderCollection. - /// - /// The AppenderCollection whose elements are copied to the new collection. - public AppenderCollection(AppenderCollection c) - { - m_array = new IAppender[c.Count]; - AddRange(c); - } - - /// - /// Initializes a new instance of the AppenderCollection class - /// that contains elements copied from the specified array. - /// - /// The array whose elements are copied to the new list. - public AppenderCollection(IAppender[] a) - { - m_array = new IAppender[a.Length]; - AddRange(a); - } - - /// - /// Initializes a new instance of the AppenderCollection class - /// that contains elements copied from the specified collection. - /// - /// The collection whose elements are copied to the new list. - public AppenderCollection(ICollection col) - { - m_array = new IAppender[col.Count]; - AddRange(col); - } - - /// - /// Type visible only to our subclasses - /// Used to access protected constructor - /// - /// - internal protected enum Tag - { - /// - /// A value - /// - Default - } - - /// - /// Allow subclasses to avoid our default constructors - /// - /// - /// - internal protected AppenderCollection(Tag tag) - { - m_array = null; - } - - #endregion - - #region Operations (type-safe ICollection) - - /// - /// Gets the number of elements actually contained in the AppenderCollection. - /// - public virtual int Count - { - get { return m_count; } - } - - /// - /// Copies the entire AppenderCollection to a one-dimensional - /// array. - /// - /// The one-dimensional array to copy to. - public virtual void CopyTo(IAppender[] array) - { - this.CopyTo(array, 0); - } - - /// - /// Copies the entire AppenderCollection to a one-dimensional - /// array, starting at the specified index of the target array. - /// - /// The one-dimensional array to copy to. - /// The zero-based index in at which copying begins. - public virtual void CopyTo(IAppender[] array, int start) - { - if (m_count > array.GetUpperBound(0) + 1 - start) - { - throw new System.ArgumentException("Destination array was not long enough."); - } - - Array.Copy(m_array, 0, array, start, m_count); - } - - /// - /// Gets a value indicating whether access to the collection is synchronized (thread-safe). - /// - /// true if access to the ICollection is synchronized (thread-safe); otherwise, false. - public virtual bool IsSynchronized - { - get { return m_array.IsSynchronized; } - } - - /// - /// Gets an object that can be used to synchronize access to the collection. - /// - public virtual object SyncRoot - { - get { return m_array.SyncRoot; } - } - - #endregion - - #region Operations (type-safe IList) - - /// - /// Gets or sets the at the specified index. - /// - /// The zero-based index of the element to get or set. - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - public virtual IAppender this[int index] - { - get - { - ValidateIndex(index); // throws - return m_array[index]; - } - set - { - ValidateIndex(index); // throws - ++m_version; - m_array[index] = value; - } - } - - /// - /// Adds a to the end of the AppenderCollection. - /// - /// The to be added to the end of the AppenderCollection. - /// The index at which the value has been added. - public virtual int Add(IAppender item) - { - if (m_count == m_array.Length) - { - EnsureCapacity(m_count + 1); - } - - m_array[m_count] = item; - m_version++; - - return m_count++; - } - - /// - /// Removes all elements from the AppenderCollection. - /// - public virtual void Clear() - { - ++m_version; - m_array = new IAppender[DEFAULT_CAPACITY]; - m_count = 0; - } - - /// - /// Creates a shallow copy of the . - /// - /// A new with a shallow copy of the collection data. - public virtual object Clone() - { - AppenderCollection newCol = new AppenderCollection(m_count); - Array.Copy(m_array, 0, newCol.m_array, 0, m_count); - newCol.m_count = m_count; - newCol.m_version = m_version; - - return newCol; - } - - /// - /// Determines whether a given is in the AppenderCollection. - /// - /// The to check for. - /// true if is found in the AppenderCollection; otherwise, false. - public virtual bool Contains(IAppender item) - { - for (int i=0; i != m_count; ++i) - { - if (m_array[i].Equals(item)) - { - return true; - } - } - return false; - } - - /// - /// Returns the zero-based index of the first occurrence of a - /// in the AppenderCollection. - /// - /// The to locate in the AppenderCollection. - /// - /// The zero-based index of the first occurrence of - /// in the entire AppenderCollection, if found; otherwise, -1. - /// - public virtual int IndexOf(IAppender item) - { - for (int i=0; i != m_count; ++i) - { - if (m_array[i].Equals(item)) - { - return i; - } - } - return -1; - } - - /// - /// Inserts an element into the AppenderCollection at the specified index. - /// - /// The zero-based index at which should be inserted. - /// The to insert. - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - public virtual void Insert(int index, IAppender item) - { - ValidateIndex(index, true); // throws - - if (m_count == m_array.Length) - { - EnsureCapacity(m_count + 1); - } - - if (index < m_count) - { - Array.Copy(m_array, index, m_array, index + 1, m_count - index); - } - - m_array[index] = item; - m_count++; - m_version++; - } - - /// - /// Removes the first occurrence of a specific from the AppenderCollection. - /// - /// The to remove from the AppenderCollection. - /// - /// The specified was not found in the AppenderCollection. - /// - public virtual void Remove(IAppender item) - { - int i = IndexOf(item); - if (i < 0) - { - throw new System.ArgumentException("Cannot remove the specified item because it was not found in the specified Collection."); - } - - ++m_version; - RemoveAt(i); - } - - /// - /// Removes the element at the specified index of the AppenderCollection. - /// - /// The zero-based index of the element to remove. - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - public virtual void RemoveAt(int index) - { - ValidateIndex(index); // throws - - m_count--; - - if (index < m_count) - { - Array.Copy(m_array, index + 1, m_array, index, m_count - index); - } - - // We can't set the deleted entry equal to null, because it might be a value type. - // Instead, we'll create an empty single-element array of the right type and copy it - // over the entry we want to erase. - IAppender[] temp = new IAppender[1]; - Array.Copy(temp, 0, m_array, m_count, 1); - m_version++; - } - - /// - /// Gets a value indicating whether the collection has a fixed size. - /// - /// true if the collection has a fixed size; otherwise, false. The default is false - public virtual bool IsFixedSize - { - get { return false; } - } - - /// - /// Gets a value indicating whether the IList is read-only. - /// - /// true if the collection is read-only; otherwise, false. The default is false - public virtual bool IsReadOnly - { - get { return false; } - } - - #endregion - - #region Operations (type-safe IEnumerable) - - /// - /// Returns an enumerator that can iterate through the AppenderCollection. - /// - /// An for the entire AppenderCollection. - public virtual IAppenderCollectionEnumerator GetEnumerator() - { - return new Enumerator(this); - } - - #endregion - - #region Public helpers (just to mimic some nice features of ArrayList) - - /// - /// Gets or sets the number of elements the AppenderCollection can contain. - /// - public virtual int Capacity - { - get - { - return m_array.Length; - } - set - { - if (value < m_count) - { - value = m_count; - } - - if (value != m_array.Length) - { - if (value > 0) - { - IAppender[] temp = new IAppender[value]; - Array.Copy(m_array, 0, temp, 0, m_count); - m_array = temp; - } - else - { - m_array = new IAppender[DEFAULT_CAPACITY]; - } - } - } - } - - /// - /// Adds the elements of another AppenderCollection to the current AppenderCollection. - /// - /// The AppenderCollection whose elements should be added to the end of the current AppenderCollection. - /// The new of the AppenderCollection. - public virtual int AddRange(AppenderCollection x) - { - if (m_count + x.Count >= m_array.Length) - { - EnsureCapacity(m_count + x.Count); - } - - Array.Copy(x.m_array, 0, m_array, m_count, x.Count); - m_count += x.Count; - m_version++; - - return m_count; - } - - /// - /// Adds the elements of a array to the current AppenderCollection. - /// - /// The array whose elements should be added to the end of the AppenderCollection. - /// The new of the AppenderCollection. - public virtual int AddRange(IAppender[] x) - { - if (m_count + x.Length >= m_array.Length) - { - EnsureCapacity(m_count + x.Length); - } - - Array.Copy(x, 0, m_array, m_count, x.Length); - m_count += x.Length; - m_version++; - - return m_count; - } - - /// - /// Adds the elements of a collection to the current AppenderCollection. - /// - /// The collection whose elements should be added to the end of the AppenderCollection. - /// The new of the AppenderCollection. - public virtual int AddRange(ICollection col) - { - if (m_count + col.Count >= m_array.Length) - { - EnsureCapacity(m_count + col.Count); - } - - foreach(object item in col) - { - Add((IAppender)item); - } - - return m_count; - } - - /// - /// Sets the capacity to the actual number of elements. - /// - public virtual void TrimToSize() - { - this.Capacity = m_count; - } - - /// - /// Return the collection elements as an array - /// - /// the array - public virtual IAppender[] ToArray() - { - IAppender[] resultArray = new IAppender[m_count]; - if (m_count > 0) - { - Array.Copy(m_array, 0, resultArray, 0, m_count); - } - return resultArray; - } - - #endregion - - #region Implementation (helpers) - - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - private void ValidateIndex(int i) - { - ValidateIndex(i, false); - } - - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - private void ValidateIndex(int i, bool allowEqualEnd) - { - int max = (allowEqualEnd) ? (m_count) : (m_count-1); - if (i < 0 || i > max) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("i", (object)i, "Index was out of range. Must be non-negative and less than the size of the collection. [" + (object)i + "] Specified argument was out of the range of valid values."); - } - } - - private void EnsureCapacity(int min) - { - int newCapacity = ((m_array.Length == 0) ? DEFAULT_CAPACITY : m_array.Length * 2); - if (newCapacity < min) - { - newCapacity = min; - } - - this.Capacity = newCapacity; - } - - #endregion - - #region Implementation (ICollection) - - void ICollection.CopyTo(Array array, int start) - { - if (m_count > 0) - { - Array.Copy(m_array, 0, array, start, m_count); - } - } - - #endregion - - #region Implementation (IList) - - object IList.this[int i] - { - get { return (object)this[i]; } - set { this[i] = (IAppender)value; } - } - - int IList.Add(object x) - { - return this.Add((IAppender)x); - } - - bool IList.Contains(object x) - { - return this.Contains((IAppender)x); - } - - int IList.IndexOf(object x) - { - return this.IndexOf((IAppender)x); - } - - void IList.Insert(int pos, object x) - { - this.Insert(pos, (IAppender)x); - } - - void IList.Remove(object x) - { - this.Remove((IAppender)x); - } - - void IList.RemoveAt(int pos) - { - this.RemoveAt(pos); - } - - #endregion - - #region Implementation (IEnumerable) - - IEnumerator IEnumerable.GetEnumerator() - { - return (IEnumerator)(this.GetEnumerator()); - } - - #endregion - - #region Nested enumerator class - - /// - /// Supports simple iteration over a . - /// - /// - private sealed class Enumerator : IEnumerator, IAppenderCollectionEnumerator - { - #region Implementation (data) - - private readonly AppenderCollection m_collection; - private int m_index; - private int m_version; - - #endregion - - #region Construction - - /// - /// Initializes a new instance of the Enumerator class. - /// - /// - internal Enumerator(AppenderCollection tc) - { - m_collection = tc; - m_index = -1; - m_version = tc.m_version; - } - - #endregion - - #region Operations (type-safe IEnumerator) - - /// - /// Gets the current element in the collection. - /// - public IAppender Current - { - get { return m_collection[m_index]; } - } - - /// - /// Advances the enumerator to the next element in the collection. - /// - /// - /// true if the enumerator was successfully advanced to the next element; - /// false if the enumerator has passed the end of the collection. - /// - /// - /// The collection was modified after the enumerator was created. - /// - public bool MoveNext() - { - if (m_version != m_collection.m_version) - { - throw new System.InvalidOperationException("Collection was modified; enumeration operation may not execute."); - } - - ++m_index; - return (m_index < m_collection.Count); - } - - /// - /// Sets the enumerator to its initial position, before the first element in the collection. - /// - public void Reset() - { - m_index = -1; - } - #endregion - - #region Implementation (IEnumerator) - - object IEnumerator.Current - { - get { return this.Current; } - } - - #endregion - } - - #endregion - - #region Nested Read Only Wrapper class - - /// - private sealed class ReadOnlyAppenderCollection : AppenderCollection, ICollection - { - #region Implementation (data) - - private readonly AppenderCollection m_collection; - - #endregion - - #region Construction - - internal ReadOnlyAppenderCollection(AppenderCollection list) : base(Tag.Default) - { - m_collection = list; - } - - #endregion - - #region Type-safe ICollection - - public override void CopyTo(IAppender[] array) - { - m_collection.CopyTo(array); - } - - public override void CopyTo(IAppender[] array, int start) - { - m_collection.CopyTo(array,start); - } - - void ICollection.CopyTo(Array array, int start) - { - ((ICollection)m_collection).CopyTo(array, start); - } - - public override int Count - { - get { return m_collection.Count; } - } - - public override bool IsSynchronized - { - get { return m_collection.IsSynchronized; } - } - - public override object SyncRoot - { - get { return this.m_collection.SyncRoot; } - } - - #endregion - - #region Type-safe IList - - public override IAppender this[int i] - { - get { return m_collection[i]; } - set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); } - } - - public override int Add(IAppender x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override void Clear() - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override bool Contains(IAppender x) - { - return m_collection.Contains(x); - } - - public override int IndexOf(IAppender x) - { - return m_collection.IndexOf(x); - } - - public override void Insert(int pos, IAppender x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override void Remove(IAppender x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override void RemoveAt(int pos) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override bool IsFixedSize - { - get { return true; } - } - - public override bool IsReadOnly - { - get { return true; } - } - - #endregion - - #region Type-safe IEnumerable - - public override IAppenderCollectionEnumerator GetEnumerator() - { - return m_collection.GetEnumerator(); - } - - #endregion - - #region Public Helpers - - // (just to mimic some nice features of ArrayList) - public override int Capacity - { - get { return m_collection.Capacity; } - set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); } - } - - public override int AddRange(AppenderCollection x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override int AddRange(IAppender[] x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override IAppender[] ToArray() - { - return m_collection.ToArray(); - } - - public override void TrimToSize() - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - #endregion - } - - #endregion - } - -} diff --git a/src/log4net/Appender/AppenderSkeleton.cs b/src/log4net/Appender/AppenderSkeleton.cs deleted file mode 100644 index c04a7613..00000000 --- a/src/log4net/Appender/AppenderSkeleton.cs +++ /dev/null @@ -1,897 +0,0 @@ -#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 System.IO; -using System.Collections; - -using log4net.Filter; -using log4net.Util; -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Abstract base class implementation of . - /// - /// - /// - /// This class provides the code for common functionality, such - /// as support for threshold filtering and support for general filters. - /// - /// - /// Appenders can also implement the interface. Therefore - /// they would require that the method - /// be called after the appenders properties have been configured. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public abstract class AppenderSkeleton : IAppender, IBulkAppender, IOptionHandler - { - #region Protected Instance Constructors - - /// - /// Default constructor - /// - /// - /// Empty default constructor - /// - protected AppenderSkeleton() - { - m_errorHandler = new OnlyOnceErrorHandler(this.GetType().Name); - } - - #endregion Protected Instance Constructors - - #region Finalizer - - /// - /// Finalizes this appender by calling the implementation's - /// method. - /// - /// - /// - /// If this appender has not been closed then the Finalize method - /// will call . - /// - /// - ~AppenderSkeleton() - { - // An appender might be closed then garbage collected. - // There is no point in closing twice. - if (!m_closed) - { - LogLog.Debug(declaringType, "Finalizing appender named ["+m_name+"]."); - Close(); - } - } - - #endregion Finalizer - - #region Public Instance Properties - - /// - /// Gets or sets the threshold of this appender. - /// - /// - /// The threshold of the appender. - /// - /// - /// - /// All log events with lower level than the threshold level are ignored - /// by the appender. - /// - /// - /// In configuration files this option is specified by setting the - /// value of the option to a level - /// string, such as "DEBUG", "INFO" and so on. - /// - /// - public Level Threshold - { - get { return m_threshold; } - set { m_threshold = value; } - } - - /// - /// Gets or sets the for this appender. - /// - /// The of the appender - /// - /// - /// The provides a default - /// implementation for the property. - /// - /// - virtual public IErrorHandler ErrorHandler - { - get { return this.m_errorHandler; } - set - { - lock(this) - { - if (value == null) - { - // We do not throw exception here since the cause is probably a - // bad config file. - LogLog.Warn(declaringType, "You have tried to set a null error-handler."); - } - else - { - m_errorHandler = value; - } - } - } - } - - /// - /// The filter chain. - /// - /// The head of the filter chain filter chain. - /// - /// - /// Returns the head Filter. The Filters are organized in a linked list - /// and so all Filters on this Appender are available through the result. - /// - /// - virtual public IFilter FilterHead - { - get { return m_headFilter; } - } - - /// - /// Gets or sets the for this appender. - /// - /// The layout of the appender. - /// - /// - /// See for more information. - /// - /// - /// - virtual public ILayout Layout - { - get { return m_layout; } - set { m_layout = value; } - } - - #endregion - - #region Implementation of IOptionHandler - - /// - /// Initialize the appender based on the options set - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - virtual public void ActivateOptions() - { - } - - #endregion Implementation of IOptionHandler - - #region Implementation of IAppender - - /// - /// Gets or sets the name of this appender. - /// - /// The name of the appender. - /// - /// - /// The name uniquely identifies the appender. - /// - /// - public string Name - { - get { return m_name; } - set { m_name = value; } - } - - /// - /// Closes the appender and release resources. - /// - /// - /// - /// Release any resources allocated within the appender such as file handles, - /// network connections, etc. - /// - /// - /// It is a programming error to append to a closed appender. - /// - /// - /// This method cannot be overridden by subclasses. This method - /// delegates the closing of the appender to the - /// method which must be overridden in the subclass. - /// - /// - public void Close() - { - // This lock prevents the appender being closed while it is still appending - lock(this) - { - if (!m_closed) - { - OnClose(); - m_closed = true; - } - } - } - - /// - /// Performs threshold checks and invokes filters before - /// delegating actual logging to the subclasses specific - /// method. - /// - /// The event to log. - /// - /// - /// This method cannot be overridden by derived classes. A - /// derived class should override the method - /// which is called by this method. - /// - /// - /// The implementation of this method is as follows: - /// - /// - /// - /// - /// - /// Checks that the severity of the - /// is greater than or equal to the of this - /// appender. - /// - /// - /// - /// Checks that the chain accepts the - /// . - /// - /// - /// - /// - /// Calls and checks that - /// it returns true. - /// - /// - /// - /// - /// If all of the above steps succeed then the - /// will be passed to the abstract method. - /// - /// - public void DoAppend(LoggingEvent loggingEvent) - { - // This lock is absolutely critical for correct formatting - // of the message in a multi-threaded environment. Without - // this, the message may be broken up into elements from - // multiple thread contexts (like get the wrong thread ID). - - lock(this) - { - if (m_closed) - { - ErrorHandler.Error("Attempted to append to closed appender named ["+m_name+"]."); - return; - } - - // prevent re-entry - if (m_recursiveGuard) - { - return; - } - - try - { - m_recursiveGuard = true; - - if (FilterEvent(loggingEvent) && PreAppendCheck()) - { - this.Append(loggingEvent); - } - } - catch(Exception ex) - { - ErrorHandler.Error("Failed in DoAppend", ex); - } -#if NETCF - // on .NET 2.0 (and higher) and Mono (all profiles), - // exceptions that do not derive from System.Exception will be - // wrapped in a RuntimeWrappedException by the runtime, and as - // such will be catched by the catch clause above - catch - { - // Catch handler for non System.Exception types - ErrorHandler.Error("Failed in DoAppend (unknown exception)"); - } -#endif - finally - { - m_recursiveGuard = false; - } - } - } - - #endregion Implementation of IAppender - - #region Implementation of IBulkAppender - - /// - /// Performs threshold checks and invokes filters before - /// delegating actual logging to the subclasses specific - /// method. - /// - /// The array of events to log. - /// - /// - /// This method cannot be overridden by derived classes. A - /// derived class should override the method - /// which is called by this method. - /// - /// - /// The implementation of this method is as follows: - /// - /// - /// - /// - /// - /// Checks that the severity of the - /// is greater than or equal to the of this - /// appender. - /// - /// - /// - /// Checks that the chain accepts the - /// . - /// - /// - /// - /// - /// Calls and checks that - /// it returns true. - /// - /// - /// - /// - /// If all of the above steps succeed then the - /// will be passed to the method. - /// - /// - public void DoAppend(LoggingEvent[] loggingEvents) - { - // This lock is absolutely critical for correct formatting - // of the message in a multi-threaded environment. Without - // this, the message may be broken up into elements from - // multiple thread contexts (like get the wrong thread ID). - - lock(this) - { - if (m_closed) - { - ErrorHandler.Error("Attempted to append to closed appender named ["+m_name+"]."); - return; - } - - // prevent re-entry - if (m_recursiveGuard) - { - return; - } - - try - { - m_recursiveGuard = true; - - ArrayList filteredEvents = new ArrayList(loggingEvents.Length); - - foreach(LoggingEvent loggingEvent in loggingEvents) - { - if (FilterEvent(loggingEvent)) - { - filteredEvents.Add(loggingEvent); - } - } - - if (filteredEvents.Count > 0 && PreAppendCheck()) - { - this.Append((LoggingEvent[])filteredEvents.ToArray(typeof(LoggingEvent))); - } - } - catch(Exception ex) - { - ErrorHandler.Error("Failed in Bulk DoAppend", ex); - } -#if NETCF - // on .NET 2.0 (and higher) and Mono (all profiles), - // exceptions that do not derive from System.Exception will be - // wrapped in a RuntimeWrappedException by the runtime, and as - // such will be catched by the catch clause above - catch - { - // Catch handler for non System.Exception types - ErrorHandler.Error("Failed in Bulk DoAppend (unknown exception)"); - } -#endif - finally - { - m_recursiveGuard = false; - } - } - } - - #endregion Implementation of IBulkAppender - - /// - /// Test if the logging event should we output by this appender - /// - /// the event to test - /// true if the event should be output, false if the event should be ignored - /// - /// - /// This method checks the logging event against the threshold level set - /// on this appender and also against the filters specified on this - /// appender. - /// - /// - /// The implementation of this method is as follows: - /// - /// - /// - /// - /// - /// Checks that the severity of the - /// is greater than or equal to the of this - /// appender. - /// - /// - /// - /// Checks that the chain accepts the - /// . - /// - /// - /// - /// - /// - virtual protected bool FilterEvent(LoggingEvent loggingEvent) - { - if (!IsAsSevereAsThreshold(loggingEvent.Level)) - { - return false; - } - - IFilter f = this.FilterHead; - - while(f != null) - { - switch(f.Decide(loggingEvent)) - { - case FilterDecision.Deny: - return false; // Return without appending - - case FilterDecision.Accept: - f = null; // Break out of the loop - break; - - case FilterDecision.Neutral: - f = f.Next; // Move to next filter - break; - } - } - - return true; - } - - #region Public Instance Methods - - /// - /// Adds a filter to the end of the filter chain. - /// - /// the filter to add to this appender - /// - /// - /// The Filters are organized in a linked list. - /// - /// - /// Setting this property causes the new filter to be pushed onto the - /// back of the filter chain. - /// - /// - virtual public void AddFilter(IFilter filter) - { - if (filter == null) - { - throw new ArgumentNullException("filter param must not be null"); - } - - if (m_headFilter == null) - { - m_headFilter = m_tailFilter = filter; - } - else - { - m_tailFilter.Next = filter; - m_tailFilter = filter; - } - } - - /// - /// Clears the filter list for this appender. - /// - /// - /// - /// Clears the filter list for this appender. - /// - /// - virtual public void ClearFilters() - { - m_headFilter = m_tailFilter = null; - } - - #endregion Public Instance Methods - - #region Protected Instance Methods - - /// - /// Checks if the message level is below this appender's threshold. - /// - /// to test against. - /// - /// - /// If there is no threshold set, then the return value is always true. - /// - /// - /// - /// true if the meets the - /// requirements of this appender. - /// - virtual protected bool IsAsSevereAsThreshold(Level level) - { - return ((m_threshold == null) || level >= m_threshold); - } - - /// - /// Is called when the appender is closed. Derived classes should override - /// this method if resources need to be released. - /// - /// - /// - /// Releases any resources allocated within the appender such as file handles, - /// network connections, etc. - /// - /// - /// It is a programming error to append to a closed appender. - /// - /// - virtual protected void OnClose() - { - // Do nothing by default - } - - /// - /// Subclasses of should implement this method - /// to perform actual logging. - /// - /// The event to append. - /// - /// - /// A subclass must implement this method to perform - /// logging of the . - /// - /// This method will be called by - /// if all the conditions listed for that method are met. - /// - /// - /// To restrict the logging of events in the appender - /// override the method. - /// - /// - abstract protected void Append(LoggingEvent loggingEvent); - - /// - /// Append a bulk array of logging events. - /// - /// the array of logging events - /// - /// - /// This base class implementation calls the - /// method for each element in the bulk array. - /// - /// - /// A sub class that can better process a bulk array of events should - /// override this method in addition to . - /// - /// - virtual protected void Append(LoggingEvent[] loggingEvents) - { - foreach(LoggingEvent loggingEvent in loggingEvents) - { - Append(loggingEvent); - } - } - - /// - /// Called before as a precondition. - /// - /// - /// - /// This method is called by - /// before the call to the abstract method. - /// - /// - /// This method can be overridden in a subclass to extend the checks - /// made before the event is passed to the method. - /// - /// - /// A subclass should ensure that they delegate this call to - /// this base class if it is overridden. - /// - /// - /// true if the call to should proceed. - virtual protected bool PreAppendCheck() - { - if ((m_layout == null) && RequiresLayout) - { - ErrorHandler.Error("AppenderSkeleton: No layout set for the appender named ["+m_name+"]."); - return false; - } - - return true; - } - - /// - /// Renders the to a string. - /// - /// The event to render. - /// The event rendered as a string. - /// - /// - /// Helper method to render a to - /// a string. This appender must have a - /// set to render the to - /// a string. - /// - /// If there is exception data in the logging event and - /// the layout does not process the exception, this method - /// will append the exception text to the rendered string. - /// - /// - /// Where possible use the alternative version of this method - /// . - /// That method streams the rendering onto an existing Writer - /// which can give better performance if the caller already has - /// a open and ready for writing. - /// - /// - protected string RenderLoggingEvent(LoggingEvent loggingEvent) - { - // Create the render writer on first use - if (m_renderWriter == null) - { - m_renderWriter = new ReusableStringWriter(System.Globalization.CultureInfo.InvariantCulture); - } - - lock (m_renderWriter) - { - // Reset the writer so we can reuse it - m_renderWriter.Reset(c_renderBufferMaxCapacity, c_renderBufferSize); - - RenderLoggingEvent(m_renderWriter, loggingEvent); - return m_renderWriter.ToString(); - } - } - - /// - /// Renders the to a string. - /// - /// The event to render. - /// The TextWriter to write the formatted event to - /// - /// - /// Helper method to render a to - /// a string. This appender must have a - /// set to render the to - /// a string. - /// - /// If there is exception data in the logging event and - /// the layout does not process the exception, this method - /// will append the exception text to the rendered string. - /// - /// - /// Use this method in preference to - /// where possible. If, however, the caller needs to render the event - /// to a string then does - /// provide an efficient mechanism for doing so. - /// - /// - protected void RenderLoggingEvent(TextWriter writer, LoggingEvent loggingEvent) - { - if (m_layout == null) - { - throw new InvalidOperationException("A layout must be set"); - } - - if (m_layout.IgnoresException) - { - string exceptionStr = loggingEvent.GetExceptionString(); - if (exceptionStr != null && exceptionStr.Length > 0) - { - // render the event and the exception - m_layout.Format(writer, loggingEvent); - writer.WriteLine(exceptionStr); - } - else - { - // there is no exception to render - m_layout.Format(writer, loggingEvent); - } - } - else - { - // The layout will render the exception - m_layout.Format(writer, loggingEvent); - } - } - - /// - /// Tests if this appender requires a to be set. - /// - /// - /// - /// In the rather exceptional case, where the appender - /// implementation admits a layout but can also work without it, - /// then the appender should return true. - /// - /// - /// This default implementation always returns false. - /// - /// - /// - /// true if the appender requires a layout object, otherwise false. - /// - virtual protected bool RequiresLayout - { - get { return false; } - } - - #endregion - - #region Private Instance Fields - - /// - /// The layout of this appender. - /// - /// - /// See for more information. - /// - private ILayout m_layout; - - /// - /// The name of this appender. - /// - /// - /// See for more information. - /// - private string m_name; - - /// - /// The level threshold of this appender. - /// - /// - /// - /// There is no level threshold filtering by default. - /// - /// - /// See for more information. - /// - /// - private Level m_threshold; - - /// - /// It is assumed and enforced that errorHandler is never null. - /// - /// - /// - /// It is assumed and enforced that errorHandler is never null. - /// - /// - /// See for more information. - /// - /// - private IErrorHandler m_errorHandler; - - /// - /// The first filter in the filter chain. - /// - /// - /// - /// Set to null initially. - /// - /// - /// See for more information. - /// - /// - private IFilter m_headFilter; - - /// - /// The last filter in the filter chain. - /// - /// - /// See for more information. - /// - private IFilter m_tailFilter; - - /// - /// Flag indicating if this appender is closed. - /// - /// - /// See for more information. - /// - private bool m_closed = false; - - /// - /// The guard prevents an appender from repeatedly calling its own DoAppend method - /// - private bool m_recursiveGuard = false; - - /// - /// StringWriter used to render events - /// - private ReusableStringWriter m_renderWriter = null; - - #endregion Private Instance Fields - - #region Constants - - /// - /// Initial buffer size - /// - private const int c_renderBufferSize = 256; - - /// - /// Maximum buffer size before it is recycled - /// - private const int c_renderBufferMaxCapacity = 1024; - - #endregion - - #region Private Static Fields - - /// - /// The fully qualified type of the AppenderSkeleton class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(AppenderSkeleton); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Appender/AspNetTraceAppender.cs b/src/log4net/Appender/AspNetTraceAppender.cs deleted file mode 100644 index 08a49a7f..00000000 --- a/src/log4net/Appender/AspNetTraceAppender.cs +++ /dev/null @@ -1,153 +0,0 @@ -#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 - -#if !NETCF && !CLIENT_PROFILE - -using System.Web; - -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// - /// Appends log events to the ASP.NET system. - /// - /// - /// - /// - /// Diagnostic information and tracing messages that you specify are appended to the output - /// of the page that is sent to the requesting browser. Optionally, you can view this information - /// from a separate trace viewer (Trace.axd) that displays trace information for every page in a - /// given application. - /// - /// - /// Trace statements are processed and displayed only when tracing is enabled. You can control - /// whether tracing is displayed to a page, to the trace viewer, or both. - /// - /// - /// The logging event is passed to the or - /// method depending on the level of the logging event. - /// The event's logger name is the default value for the category parameter of the Write/Warn method. - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Ron Grabowski - public class AspNetTraceAppender : AppenderSkeleton - { - #region Public Instances Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public AspNetTraceAppender() - { - } - - #endregion // Public Instances Constructors - - #region Override implementation of AppenderSkeleton - - /// - /// Write the logging event to the ASP.NET trace - /// - /// the event to log - /// - /// - /// Write the logging event to the ASP.NET trace - /// HttpContext.Current.Trace - /// (). - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - // check if log4net is running in the context of an ASP.NET application - if (HttpContext.Current != null) - { - // check if tracing is enabled for the current context - if (HttpContext.Current.Trace.IsEnabled) - { - if (loggingEvent.Level >= Level.Warn) - { - HttpContext.Current.Trace.Warn(m_category.Format(loggingEvent), RenderLoggingEvent(loggingEvent)); - } - else - { - HttpContext.Current.Trace.Write(m_category.Format(loggingEvent), RenderLoggingEvent(loggingEvent)); - } - } - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion // Override implementation of AppenderSkeleton - - #region Public Instance Properties - - /// - /// The category parameter sent to the Trace method. - /// - /// - /// - /// Defaults to %logger which will use the logger name of the current - /// as the category parameter. - /// - /// - /// - /// - public PatternLayout Category - { - get { return m_category; } - set { m_category = value; } - } - - #endregion - - #region Private Instance Fields - - /// - /// Defaults to %logger - /// - private PatternLayout m_category = new PatternLayout("%logger"); - - #endregion - } -} - -#endif // !NETCF diff --git a/src/log4net/Appender/AsyncAppender.cs b/src/log4net/Appender/AsyncAppender.cs deleted file mode 100644 index da6932ad..00000000 --- a/src/log4net/Appender/AsyncAppender.cs +++ /dev/null @@ -1,222 +0,0 @@ -#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 System.Collections.Generic; -#if FRAMEWORK_4_0_OR_ABOVE -using System.Threading.Tasks; -#else -using System.Threading; -#endif -using log4net.Appender; -using log4net.Core; -using log4net.Util; - -namespace log4net.Appender -{ - /// - /// Appender that forwards LoggingEvents asynchronously - /// - /// - /// This appender forwards LoggingEvents to a list of attached appenders. - /// The events are forwarded asynchronously using the ThreadPool. - /// This allows the calling thread to be released quickly, however it does - /// not guarantee the ordering of events delivered to the attached appenders. - /// - public sealed class AsyncAppender : ForwardingAppender - { - /// - /// Creates a new AsyncAppender. - /// - public AsyncAppender() - { -#if FRAMEWORK_4_0_OR_ABOVE - logTask = new Task(() => { }); - logTask.Start(); -#endif - } - - /// - /// Gets or sets a the fields that will be fixed in the event - /// - /// - /// The event fields that will be fixed before the event is forwarded - /// - /// - /// - /// The logging event needs to have certain thread specific values - /// captured before it can be forwarded to a different thread. - /// See for details. - /// - /// - /// - public FixFlags Fix - { - get { return m_fixFlags; } - set { m_fixFlags = value; } - } - - /// - /// Forward the logging event to the attached appenders on a ThreadPool thread - /// - /// The event to log. - /// - /// - /// Delivers the logging event to all the attached appenders on a ThreadPool thread. - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - loggingEvent.Fix = m_fixFlags; - lock (lockObject) - { - if (closed) - { - return; - } - events.Add(loggingEvent); - } -#if FRAMEWORK_4_0_OR_ABOVE - logTask.ContinueWith(AsyncAppend); -#else - ThreadPool.QueueUserWorkItem(AsyncAppend, null); -#endif - } - - /// - /// Forward the logging events to the attached appenders on a ThreadPool thread - /// - /// The array of events to log. - /// - /// - /// Delivers the logging events to all the attached appenders on a ThreadPool thread. - /// - /// - override protected void Append(LoggingEvent[] loggingEvents) - { - foreach (LoggingEvent loggingEvent in loggingEvents) - { - loggingEvent.Fix = m_fixFlags; - } - lock (lockObject) - { - if (closed) - { - return; - } - events.AddRange(loggingEvents); - } -#if FRAMEWORK_4_0_OR_ABOVE - logTask.ContinueWith(AsyncAppend); -#else - ThreadPool.QueueUserWorkItem(AsyncAppend, null); -#endif - } - - /// - /// Closes the appender and releases resources. - /// - /// - /// - /// Releases any resources allocated within the appender such as file handles, - /// network connections, etc. - /// - /// - /// It is a programming error to append to a closed appender. - /// - /// - override protected void OnClose() - { - lock (lockObject) - { -#if FRAMEWORK_4_0_OR_ABOVE - if (!closed) - { - logTask.Wait(); - } -#endif - closed = true; - } - base.OnClose(); - } - - private void AsyncAppend(object _ignored) - { -#if FRAMEWORK_4_0_OR_ABOVE // ContinueWith already ensures there is only one thread executing this method at a time - ForwardEvents(); -#else - lock (lockObject) - { - if (inLoggingLoop) - { - return; - } - inLoggingLoop = true; - } - try - { - while (true) - { - if (!ForwardEvents()) - { - break; - } - } - } - finally - { - lock (lockObject) - { - inLoggingLoop = false; - } - } -#endif - } - - /// - /// Forwards the queued events to the nested appenders. - /// - /// whether there have been any events to forward. - private bool ForwardEvents() - { - LoggingEvent[] loggingEvents = null; - lock (lockObject) - { - loggingEvents = events.ToArray(); - events.Clear(); - } - if (loggingEvents.Length == 0) - { - return false; - } - base.Append(loggingEvents); - return true; - } - - private FixFlags m_fixFlags = FixFlags.All; - private readonly object lockObject = new object(); - private readonly List events = new List(); - private bool closed = false; -#if FRAMEWORK_4_0_OR_ABOVE - private readonly Task logTask; -#else - private bool inLoggingLoop = false; -#endif - } -} diff --git a/src/log4net/Appender/BufferingAppenderSkeleton.cs b/src/log4net/Appender/BufferingAppenderSkeleton.cs deleted file mode 100644 index 4cf37a0b..00000000 --- a/src/log4net/Appender/BufferingAppenderSkeleton.cs +++ /dev/null @@ -1,613 +0,0 @@ -#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 System.Collections; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Abstract base class implementation of that - /// buffers events in a fixed size buffer. - /// - /// - /// - /// This base class should be used by appenders that need to buffer a - /// number of events before logging them. For example the - /// buffers events and then submits the entire contents of the buffer to - /// the underlying database in one go. - /// - /// - /// Subclasses should override the - /// method to deliver the buffered events. - /// - /// The BufferingAppenderSkeleton maintains a fixed size cyclic - /// buffer of events. The size of the buffer is set using - /// the property. - /// - /// A is used to inspect - /// each event as it arrives in the appender. If the - /// triggers, then the current buffer is sent immediately - /// (see ). Otherwise the event - /// is stored in the buffer. For example, an evaluator can be used to - /// deliver the events immediately when an ERROR event arrives. - /// - /// - /// The buffering appender can be configured in a mode. - /// By default the appender is NOT lossy. When the buffer is full all - /// the buffered events are sent with . - /// If the property is set to true then the - /// buffer will not be sent when it is full, and new events arriving - /// in the appender will overwrite the oldest event in the buffer. - /// In lossy mode the buffer will only be sent when the - /// triggers. This can be useful behavior when you need to know about - /// ERROR events but not about events with a lower level, configure an - /// evaluator that will trigger when an ERROR event arrives, the whole - /// buffer will be sent which gives a history of events leading up to - /// the ERROR event. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public abstract class BufferingAppenderSkeleton : AppenderSkeleton - { - #region Protected Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Protected default constructor to allow subclassing. - /// - /// - protected BufferingAppenderSkeleton() : this(true) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// the events passed through this appender must be - /// fixed by the time that they arrive in the derived class' SendBuffer method. - /// - /// - /// Protected constructor to allow subclassing. - /// - /// - /// The should be set if the subclass - /// expects the events delivered to be fixed even if the - /// is set to zero, i.e. when no buffering occurs. - /// - /// - protected BufferingAppenderSkeleton(bool eventMustBeFixed) : base() - { - m_eventMustBeFixed = eventMustBeFixed; - } - - #endregion Protected Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets a value that indicates whether the appender is lossy. - /// - /// - /// true if the appender is lossy, otherwise false. The default is false. - /// - /// - /// - /// This appender uses a buffer to store logging events before - /// delivering them. A triggering event causes the whole buffer - /// to be send to the remote sink. If the buffer overruns before - /// a triggering event then logging events could be lost. Set - /// to false to prevent logging events - /// from being lost. - /// - /// If is set to true then an - /// must be specified. - /// - public bool Lossy - { - get { return m_lossy; } - set { m_lossy = value; } - } - - /// - /// Gets or sets the size of the cyclic buffer used to hold the - /// logging events. - /// - /// - /// The size of the cyclic buffer used to hold the logging events. - /// - /// - /// - /// The option takes a positive integer - /// representing the maximum number of logging events to collect in - /// a cyclic buffer. When the is reached, - /// oldest events are deleted as new events are added to the - /// buffer. By default the size of the cyclic buffer is 512 events. - /// - /// - /// If the is set to a value less than - /// or equal to 1 then no buffering will occur. The logging event - /// will be delivered synchronously (depending on the - /// and properties). Otherwise the event will - /// be buffered. - /// - /// - public int BufferSize - { - get { return m_bufferSize; } - set { m_bufferSize = value; } - } - - /// - /// Gets or sets the that causes the - /// buffer to be sent immediately. - /// - /// - /// The that causes the buffer to be - /// sent immediately. - /// - /// - /// - /// The evaluator will be called for each event that is appended to this - /// appender. If the evaluator triggers then the current buffer will - /// immediately be sent (see ). - /// - /// If is set to true then an - /// must be specified. - /// - public ITriggeringEventEvaluator Evaluator - { - get { return m_evaluator; } - set { m_evaluator = value; } - } - - /// - /// Gets or sets the value of the to use. - /// - /// - /// The value of the to use. - /// - /// - /// - /// The evaluator will be called for each event that is discarded from this - /// appender. If the evaluator triggers then the current buffer will immediately - /// be sent (see ). - /// - /// - public ITriggeringEventEvaluator LossyEvaluator - { - get { return m_lossyEvaluator; } - set { m_lossyEvaluator = value; } - } - - /// - /// Gets or sets a the fields that will be fixed in the event - /// - /// - /// The event fields that will be fixed before the event is buffered - /// - /// - /// - /// The logging event needs to have certain thread specific values - /// captured before it can be buffered. See - /// for details. - /// - /// - /// - virtual public FixFlags Fix - { - get { return m_fixFlags; } - set { m_fixFlags = value; } - } - - #endregion Public Instance Properties - - #region Public Methods - - /// - /// Flush the currently buffered events - /// - /// - /// - /// Flushes any events that have been buffered. - /// - /// - /// If the appender is buffering in mode then the contents - /// of the buffer will NOT be flushed to the appender. - /// - /// - public virtual void Flush() - { - Flush(false); - } - - /// - /// Flush the currently buffered events - /// - /// set to true to flush the buffer of lossy events - /// - /// - /// Flushes events that have been buffered. If is - /// false then events will only be flushed if this buffer is non-lossy mode. - /// - /// - /// If the appender is buffering in mode then the contents - /// of the buffer will only be flushed if is true. - /// In this case the contents of the buffer will be tested against the - /// and if triggering will be output. All other buffered - /// events will be discarded. - /// - /// - /// If is true then the buffer will always - /// be emptied by calling this method. - /// - /// - public virtual void Flush(bool flushLossyBuffer) - { - // This method will be called outside of the AppenderSkeleton DoAppend() method - // therefore it needs to be protected by its own lock. This will block any - // Appends while the buffer is flushed. - lock(this) - { - if (m_cb != null && m_cb.Length > 0) - { - if (m_lossy) - { - // If we are allowed to eagerly flush from the lossy buffer - if (flushLossyBuffer) - { - if (m_lossyEvaluator != null) - { - // Test the contents of the buffer against the lossy evaluator - LoggingEvent[] bufferedEvents = m_cb.PopAll(); - ArrayList filteredEvents = new ArrayList(bufferedEvents.Length); - - foreach(LoggingEvent loggingEvent in bufferedEvents) - { - if (m_lossyEvaluator.IsTriggeringEvent(loggingEvent)) - { - filteredEvents.Add(loggingEvent); - } - } - - // Send the events that meet the lossy evaluator criteria - if (filteredEvents.Count > 0) - { - SendBuffer((LoggingEvent[])filteredEvents.ToArray(typeof(LoggingEvent))); - } - } - else - { - // No lossy evaluator, all buffered events are discarded - m_cb.Clear(); - } - } - } - else - { - // Not lossy, send whole buffer - SendFromBuffer(null, m_cb); - } - } - } - } - - #endregion Public Methods - - #region Implementation of IOptionHandler - - /// - /// Initialize the appender based on the options set - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - override public void ActivateOptions() - { - base.ActivateOptions(); - - // If the appender is in Lossy mode then we will - // only send the buffer when the Evaluator triggers - // therefore check we have an evaluator. - if (m_lossy && m_evaluator == null) - { - ErrorHandler.Error("Appender ["+Name+"] is Lossy but has no Evaluator. The buffer will never be sent!"); - } - - if (m_bufferSize > 1) - { - m_cb = new CyclicBuffer(m_bufferSize); - } - else - { - m_cb = null; - } - } - - #endregion Implementation of IOptionHandler - - #region Override implementation of AppenderSkeleton - - /// - /// Close this appender instance. - /// - /// - /// - /// Close this appender instance. If this appender is marked - /// as not then the remaining events in - /// the buffer must be sent when the appender is closed. - /// - /// - override protected void OnClose() - { - // Flush the buffer on close - Flush(true); - } - - /// - /// This method is called by the method. - /// - /// the event to log - /// - /// - /// Stores the in the cyclic buffer. - /// - /// - /// The buffer will be sent (i.e. passed to the - /// method) if one of the following conditions is met: - /// - /// - /// - /// The cyclic buffer is full and this appender is - /// marked as not lossy (see ) - /// - /// - /// An is set and - /// it is triggered for the - /// specified. - /// - /// - /// - /// Before the event is stored in the buffer it is fixed - /// (see ) to ensure that - /// any data referenced by the event will be valid when the buffer - /// is processed. - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - // If the buffer size is set to 1 or less then the buffer will be - // sent immediately because there is not enough space in the buffer - // to buffer up more than 1 event. Therefore as a special case - // we don't use the buffer at all. - if (m_cb == null || m_bufferSize <= 1) - { - // Only send the event if we are in non lossy mode or the event is a triggering event - if ((!m_lossy) || - (m_evaluator != null && m_evaluator.IsTriggeringEvent(loggingEvent)) || - (m_lossyEvaluator != null && m_lossyEvaluator.IsTriggeringEvent(loggingEvent))) - { - if (m_eventMustBeFixed) - { - // Derive class expects fixed events - loggingEvent.Fix = this.Fix; - } - - // Not buffering events, send immediately - SendBuffer(new LoggingEvent[] { loggingEvent } ); - } - } - else - { - // Because we are caching the LoggingEvent beyond the - // lifetime of the Append() method we must fix any - // volatile data in the event. - loggingEvent.Fix = this.Fix; - - // Add to the buffer, returns the event discarded from the buffer if there is no space remaining after the append - LoggingEvent discardedLoggingEvent = m_cb.Append(loggingEvent); - - if (discardedLoggingEvent != null) - { - // Buffer is full and has had to discard an event - if (!m_lossy) - { - // Not lossy, must send all events - SendFromBuffer(discardedLoggingEvent, m_cb); - } - else - { - // Check if the discarded event should not be logged - if (m_lossyEvaluator == null || !m_lossyEvaluator.IsTriggeringEvent(discardedLoggingEvent)) - { - // Clear the discarded event as we should not forward it - discardedLoggingEvent = null; - } - - // Check if the event should trigger the whole buffer to be sent - if (m_evaluator != null && m_evaluator.IsTriggeringEvent(loggingEvent)) - { - SendFromBuffer(discardedLoggingEvent, m_cb); - } - else if (discardedLoggingEvent != null) - { - // Just send the discarded event - SendBuffer(new LoggingEvent[] { discardedLoggingEvent } ); - } - } - } - else - { - // Buffer is not yet full - - // Check if the event should trigger the whole buffer to be sent - if (m_evaluator != null && m_evaluator.IsTriggeringEvent(loggingEvent)) - { - SendFromBuffer(null, m_cb); - } - } - } - } - - #endregion Override implementation of AppenderSkeleton - - #region Protected Instance Methods - - /// - /// Sends the contents of the buffer. - /// - /// The first logging event. - /// The buffer containing the events that need to be send. - /// - /// - /// The subclass must override . - /// - /// - virtual protected void SendFromBuffer(LoggingEvent firstLoggingEvent, CyclicBuffer buffer) - { - LoggingEvent[] bufferEvents = buffer.PopAll(); - - if (firstLoggingEvent == null) - { - SendBuffer(bufferEvents); - } - else if (bufferEvents.Length == 0) - { - SendBuffer(new LoggingEvent[] { firstLoggingEvent } ); - } - else - { - // Create new array with the firstLoggingEvent at the head - LoggingEvent[] events = new LoggingEvent[bufferEvents.Length + 1]; - Array.Copy(bufferEvents, 0, events, 1, bufferEvents.Length); - events[0] = firstLoggingEvent; - - SendBuffer(events); - } - } - - #endregion Protected Instance Methods - - /// - /// Sends the events. - /// - /// The events that need to be send. - /// - /// - /// The subclass must override this method to process the buffered events. - /// - /// - abstract protected void SendBuffer(LoggingEvent[] events); - - #region Private Static Fields - - /// - /// The default buffer size. - /// - /// - /// The default size of the cyclic buffer used to store events. - /// This is set to 512 by default. - /// - private const int DEFAULT_BUFFER_SIZE = 512; - - #endregion Private Static Fields - - #region Private Instance Fields - - /// - /// The size of the cyclic buffer used to hold the logging events. - /// - /// - /// Set to by default. - /// - private int m_bufferSize = DEFAULT_BUFFER_SIZE; - - /// - /// The cyclic buffer used to store the logging events. - /// - private CyclicBuffer m_cb; - - /// - /// The triggering event evaluator that causes the buffer to be sent immediately. - /// - /// - /// The object that is used to determine if an event causes the entire - /// buffer to be sent immediately. This field can be null, which - /// indicates that event triggering is not to be done. The evaluator - /// can be set using the property. If this appender - /// has the ( property) set to - /// true then an must be set. - /// - private ITriggeringEventEvaluator m_evaluator; - - /// - /// Indicates if the appender should overwrite events in the cyclic buffer - /// when it becomes full, or if the buffer should be flushed when the - /// buffer is full. - /// - /// - /// If this field is set to true then an must - /// be set. - /// - private bool m_lossy = false; - - /// - /// The triggering event evaluator filters discarded events. - /// - /// - /// The object that is used to determine if an event that is discarded should - /// really be discarded or if it should be sent to the appenders. - /// This field can be null, which indicates that all discarded events will - /// be discarded. - /// - private ITriggeringEventEvaluator m_lossyEvaluator; - - /// - /// Value indicating which fields in the event should be fixed - /// - /// - /// By default all fields are fixed - /// - private FixFlags m_fixFlags = FixFlags.All; - - /// - /// The events delivered to the subclass must be fixed. - /// - private readonly bool m_eventMustBeFixed; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Appender/BufferingForwardingAppender.cs b/src/log4net/Appender/BufferingForwardingAppender.cs deleted file mode 100644 index 17d02b89..00000000 --- a/src/log4net/Appender/BufferingForwardingAppender.cs +++ /dev/null @@ -1,274 +0,0 @@ -#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.Util; -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Buffers events and then forwards them to attached appenders. - /// - /// - /// - /// The events are buffered in this appender until conditions are - /// met to allow the appender to deliver the events to the attached - /// appenders. See for the - /// conditions that cause the buffer to be sent. - /// - /// The forwarding appender can be used to specify different - /// thresholds and filters for the same appender at different locations - /// within the hierarchy. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class BufferingForwardingAppender : BufferingAppenderSkeleton, IAppenderAttachable - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public BufferingForwardingAppender() - { - } - - #endregion Public Instance Constructors - - #region Override implementation of AppenderSkeleton - - /// - /// Closes the appender and releases resources. - /// - /// - /// - /// Releases any resources allocated within the appender such as file handles, - /// network connections, etc. - /// - /// - /// It is a programming error to append to a closed appender. - /// - /// - override protected void OnClose() - { - // Remove all the attached appenders - lock(this) - { - // Delegate to base, which will flush buffers - base.OnClose(); - - if (m_appenderAttachedImpl != null) - { - m_appenderAttachedImpl.RemoveAllAppenders(); - } - } - } - - #endregion Override implementation of AppenderSkeleton - - #region Override implementation of BufferingAppenderSkeleton - - /// - /// Send the events. - /// - /// The events that need to be send. - /// - /// - /// Forwards the events to the attached appenders. - /// - /// - override protected void SendBuffer(LoggingEvent[] events) - { - // Pass the logging event on to the attached appenders - if (m_appenderAttachedImpl != null) - { - m_appenderAttachedImpl.AppendLoopOnAppenders(events); - } - } - - #endregion Override implementation of BufferingAppenderSkeleton - - #region Implementation of IAppenderAttachable - - /// - /// Adds an to the list of appenders of this - /// instance. - /// - /// The to add to this appender. - /// - /// - /// If the specified is already in the list of - /// appenders, then it won't be added again. - /// - /// - virtual public void AddAppender(IAppender newAppender) - { - if (newAppender == null) - { - throw new ArgumentNullException("newAppender"); - } - lock(this) - { - if (m_appenderAttachedImpl == null) - { - m_appenderAttachedImpl = new log4net.Util.AppenderAttachedImpl(); - } - m_appenderAttachedImpl.AddAppender(newAppender); - } - } - - /// - /// Gets the appenders contained in this appender as an - /// . - /// - /// - /// If no appenders can be found, then an - /// is returned. - /// - /// - /// A collection of the appenders in this appender. - /// - virtual public AppenderCollection Appenders - { - get - { - lock(this) - { - if (m_appenderAttachedImpl == null) - { - return AppenderCollection.EmptyCollection; - } - else - { - return m_appenderAttachedImpl.Appenders; - } - } - } - } - - /// - /// Looks for the appender with the specified name. - /// - /// The name of the appender to lookup. - /// - /// The appender with the specified name, or null. - /// - /// - /// - /// Get the named appender attached to this buffering appender. - /// - /// - virtual public IAppender GetAppender(string name) - { - lock(this) - { - if (m_appenderAttachedImpl == null || name == null) - { - return null; - } - - return m_appenderAttachedImpl.GetAppender(name); - } - } - - /// - /// Removes all previously added appenders from this appender. - /// - /// - /// - /// This is useful when re-reading configuration information. - /// - /// - virtual public void RemoveAllAppenders() - { - lock(this) - { - if (m_appenderAttachedImpl != null) - { - m_appenderAttachedImpl.RemoveAllAppenders(); - m_appenderAttachedImpl = null; - } - } - } - - /// - /// Removes the specified appender from the list of appenders. - /// - /// The appender to remove. - /// The appender removed from the list - /// - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - virtual public IAppender RemoveAppender(IAppender appender) - { - lock(this) - { - if (appender != null && m_appenderAttachedImpl != null) - { - return m_appenderAttachedImpl.RemoveAppender(appender); - } - } - return null; - } - - /// - /// Removes the appender with the specified name from the list of appenders. - /// - /// The name of the appender to remove. - /// The appender removed from the list - /// - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - virtual public IAppender RemoveAppender(string name) - { - lock(this) - { - if (name != null && m_appenderAttachedImpl != null) - { - return m_appenderAttachedImpl.RemoveAppender(name); - } - } - return null; - } - - #endregion Implementation of IAppenderAttachable - - #region Private Instance Fields - - /// - /// Implementation of the interface - /// - private AppenderAttachedImpl m_appenderAttachedImpl; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Appender/ColoredConsoleAppender.cs b/src/log4net/Appender/ColoredConsoleAppender.cs deleted file mode 100644 index a39e0900..00000000 --- a/src/log4net/Appender/ColoredConsoleAppender.cs +++ /dev/null @@ -1,623 +0,0 @@ -#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 - -// .NET Compact Framework has no support for Win32 Console API's -#if !NETCF - -using System; -using System.Globalization; -using System.Runtime.InteropServices; - -using log4net.Layout; -using log4net.Util; - -namespace log4net.Appender -{ - /// - /// Appends logging events to the console. - /// - /// - /// - /// ColoredConsoleAppender appends log events to the standard output stream - /// or the error output stream using a layout specified by the - /// user. It also allows the color of a specific type of message to be set. - /// - /// - /// By default, all output is written to the console's standard output stream. - /// The property can be set to direct the output to the - /// error stream. - /// - /// - /// NOTE: This appender writes directly to the application's attached console - /// not to the System.Console.Out or System.Console.Error TextWriter. - /// The System.Console.Out and System.Console.Error streams can be - /// programmatically redirected (for example NUnit does this to capture program output). - /// This appender will ignore these redirections because it needs to use Win32 - /// API calls to colorize the output. To respect these redirections the - /// must be used. - /// - /// - /// When configuring the colored console appender, mapping should be - /// specified to map a logging level to a color. For example: - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The Level is the standard log4net logging level and ForeColor and BackColor can be any - /// combination of the following values: - /// - /// Blue - /// Green - /// Red - /// White - /// Yellow - /// Purple - /// Cyan - /// HighIntensity - /// - /// - /// - /// Rick Hobbs - /// Nicko Cadell - public class ColoredConsoleAppender : AppenderSkeleton - { - #region Colors Enum - - /// - /// The enum of possible color values for use with the color mapping method - /// - /// - /// - /// The following flags can be combined together to - /// form the colors. - /// - /// - /// - [Flags] - public enum Colors : int - { - /// - /// color is blue - /// - Blue = 0x0001, - - /// - /// color is green - /// - Green = 0x0002, - - /// - /// color is red - /// - Red = 0x0004, - - /// - /// color is white - /// - White = Blue | Green | Red, - - /// - /// color is yellow - /// - Yellow = Red | Green, - - /// - /// color is purple - /// - Purple = Red | Blue, - - /// - /// color is cyan - /// - Cyan = Green | Blue, - - /// - /// color is intensified - /// - HighIntensity = 0x0008, - } - - #endregion // Colors Enum - - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// The instance of the class is set up to write - /// to the standard output stream. - /// - public ColoredConsoleAppender() - { - } - - #endregion // Public Instance Constructors - - #region Public Instance Properties - - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - virtual public string Target - { - get { return m_writeToErrorStream ? ConsoleError : ConsoleOut; } - set - { - string v = value.Trim(); - - if (string.Compare(ConsoleError, v, true, CultureInfo.InvariantCulture) == 0) - { - m_writeToErrorStream = true; - } - else - { - m_writeToErrorStream = false; - } - } - } - - /// - /// Add a mapping of level to color - done by the config file - /// - /// The mapping to add - /// - /// - /// Add a mapping to this appender. - /// Each mapping defines the foreground and background colors - /// for a level. - /// - /// - public void AddMapping(LevelColors mapping) - { - m_levelMapping.Add(mapping); - } - - #endregion // Public Instance Properties - - #region Override implementation of AppenderSkeleton - - /// - /// This method is called by the method. - /// - /// The event to log. - /// - /// - /// Writes the event to the console. - /// - /// - /// The format of the output will depend on the appender's layout. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] - override protected void Append(log4net.Core.LoggingEvent loggingEvent) - { - if (m_consoleOutputWriter != null) - { - IntPtr consoleHandle = IntPtr.Zero; - if (m_writeToErrorStream) - { - // Write to the error stream - consoleHandle = GetStdHandle(STD_ERROR_HANDLE); - } - else - { - // Write to the output stream - consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); - } - - // Default to white on black - ushort colorInfo = (ushort)Colors.White; - - // see if there is a specified lookup - LevelColors levelColors = m_levelMapping.Lookup(loggingEvent.Level) as LevelColors; - if (levelColors != null) - { - colorInfo = levelColors.CombinedColor; - } - - // Render the event to a string - string strLoggingMessage = RenderLoggingEvent(loggingEvent); - - // get the current console color - to restore later - CONSOLE_SCREEN_BUFFER_INFO bufferInfo; - GetConsoleScreenBufferInfo(consoleHandle, out bufferInfo); - - // set the console colors - SetConsoleTextAttribute(consoleHandle, colorInfo); - - // Using WriteConsoleW seems to be unreliable. - // If a large buffer is written, say 15,000 chars - // Followed by a larger buffer, say 20,000 chars - // then WriteConsoleW will fail, last error 8 - // 'Not enough storage is available to process this command.' - // - // Although the documentation states that the buffer must - // be less that 64KB (i.e. 32,000 WCHARs) the longest string - // that I can write out a the first call to WriteConsoleW - // is only 30,704 chars. - // - // Unlike the WriteFile API the WriteConsoleW method does not - // seem to be able to partially write out from the input buffer. - // It does have a lpNumberOfCharsWritten parameter, but this is - // either the length of the input buffer if any output was written, - // or 0 when an error occurs. - // - // All results above were observed on Windows XP SP1 running - // .NET runtime 1.1 SP1. - // - // Old call to WriteConsoleW: - // - // WriteConsoleW( - // consoleHandle, - // strLoggingMessage, - // (UInt32)strLoggingMessage.Length, - // out (UInt32)ignoreWrittenCount, - // IntPtr.Zero); - // - // Instead of calling WriteConsoleW we use WriteFile which - // handles large buffers correctly. Because WriteFile does not - // handle the codepage conversion as WriteConsoleW does we - // need to use a System.IO.StreamWriter with the appropriate - // Encoding. The WriteFile calls are wrapped up in the - // System.IO.__ConsoleStream internal class obtained through - // the System.Console.OpenStandardOutput method. - // - // See the ActivateOptions method below for the code that - // retrieves and wraps the stream. - - - // The windows console uses ScrollConsoleScreenBuffer internally to - // scroll the console buffer when the display buffer of the console - // has been used up. ScrollConsoleScreenBuffer fills the area uncovered - // by moving the current content with the background color - // currently specified on the console. This means that it fills the - // whole line in front of the cursor position with the current - // background color. - // This causes an issue when writing out text with a non default - // background color. For example; We write a message with a Blue - // background color and the scrollable area of the console is full. - // When we write the newline at the end of the message the console - // needs to scroll the buffer to make space available for the new line. - // The ScrollConsoleScreenBuffer internals will fill the newly created - // space with the current background color: Blue. - // We then change the console color back to default (White text on a - // Black background). We write some text to the console, the text is - // written correctly in White with a Black background, however the - // remainder of the line still has a Blue background. - // - // This causes a disjointed appearance to the output where the background - // colors change. - // - // This can be remedied by restoring the console colors before causing - // the buffer to scroll, i.e. before writing the last newline. This does - // assume that the rendered message will end with a newline. - // - // Therefore we identify a trailing newline in the message and don't - // write this to the output, then we restore the console color and write - // a newline. Note that we must AutoFlush before we restore the console - // color otherwise we will have no effect. - // - // There will still be a slight artefact for the last line of the message - // will have the background extended to the end of the line, however this - // is unlikely to cause any user issues. - // - // Note that none of the above is visible while the console buffer is scrollable - // within the console window viewport, the effects only arise when the actual - // buffer is full and needs to be scrolled. - - char[] messageCharArray = strLoggingMessage.ToCharArray(); - int arrayLength = messageCharArray.Length; - bool appendNewline = false; - - // Trim off last newline, if it exists - if (arrayLength > 1 && messageCharArray[arrayLength-2] == '\r' && messageCharArray[arrayLength-1] == '\n') - { - arrayLength -= 2; - appendNewline = true; - } - - // Write to the output stream - m_consoleOutputWriter.Write(messageCharArray, 0, arrayLength); - - // Restore the console back to its previous color scheme - SetConsoleTextAttribute(consoleHandle, bufferInfo.wAttributes); - - if (appendNewline) - { - // Write the newline, after changing the color scheme - m_consoleOutputWriter.Write(s_windowsNewline, 0, 2); - } - } - } - - private static readonly char[] s_windowsNewline = {'\r', '\n'}; - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - /// - /// Initialize the options for this appender - /// - /// - /// - /// Initialize the level to color mappings set on this appender. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode=true)] - public override void ActivateOptions() - { - base.ActivateOptions(); - m_levelMapping.ActivateOptions(); - - System.IO.Stream consoleOutputStream = null; - - // Use the Console methods to open a Stream over the console std handle - if (m_writeToErrorStream) - { - // Write to the error stream - consoleOutputStream = Console.OpenStandardError(); - } - else - { - // Write to the output stream - consoleOutputStream = Console.OpenStandardOutput(); - } - - // Lookup the codepage encoding for the console - System.Text.Encoding consoleEncoding = System.Text.Encoding.GetEncoding(GetConsoleOutputCP()); - - // Create a writer around the console stream - m_consoleOutputWriter = new System.IO.StreamWriter(consoleOutputStream, consoleEncoding, 0x100); - - m_consoleOutputWriter.AutoFlush = true; - - // SuppressFinalize on m_consoleOutputWriter because all it will do is flush - // and close the file handle. Because we have set AutoFlush the additional flush - // is not required. The console file handle should not be closed, so we don't call - // Dispose, Close or the finalizer. - GC.SuppressFinalize(m_consoleOutputWriter); - } - - #endregion // Override implementation of AppenderSkeleton - - #region Public Static Fields - - /// - /// The to use when writing to the Console - /// standard output stream. - /// - /// - /// - /// The to use when writing to the Console - /// standard output stream. - /// - /// - public const string ConsoleOut = "Console.Out"; - - /// - /// The to use when writing to the Console - /// standard error output stream. - /// - /// - /// - /// The to use when writing to the Console - /// standard error output stream. - /// - /// - public const string ConsoleError = "Console.Error"; - - #endregion // Public Static Fields - - #region Private Instances Fields - - /// - /// Flag to write output to the error stream rather than the standard output stream - /// - private bool m_writeToErrorStream = false; - - /// - /// Mapping from level object to color value - /// - private LevelMapping m_levelMapping = new LevelMapping(); - - /// - /// The console output stream writer to write to - /// - /// - /// - /// This writer is not thread safe. - /// - /// - private System.IO.StreamWriter m_consoleOutputWriter = null; - - #endregion // Private Instances Fields - - #region Win32 Methods - - [DllImport("Kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] - private static extern int GetConsoleOutputCP(); - - [DllImport("Kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] - private static extern bool SetConsoleTextAttribute( - IntPtr consoleHandle, - ushort attributes); - - [DllImport("Kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] - private static extern bool GetConsoleScreenBufferInfo( - IntPtr consoleHandle, - out CONSOLE_SCREEN_BUFFER_INFO bufferInfo); - -// [DllImport("Kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)] -// private static extern bool WriteConsoleW( -// IntPtr hConsoleHandle, -// [MarshalAs(UnmanagedType.LPWStr)] string strBuffer, -// UInt32 bufferLen, -// out UInt32 written, -// IntPtr reserved); - - //private const UInt32 STD_INPUT_HANDLE = unchecked((UInt32)(-10)); - private const UInt32 STD_OUTPUT_HANDLE = unchecked((UInt32)(-11)); - private const UInt32 STD_ERROR_HANDLE = unchecked((UInt32)(-12)); - - [DllImport("Kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] - private static extern IntPtr GetStdHandle( - UInt32 type); - - [StructLayout(LayoutKind.Sequential)] - private struct COORD - { - public UInt16 x; - public UInt16 y; - } - - [StructLayout(LayoutKind.Sequential)] - private struct SMALL_RECT - { - public UInt16 Left; - public UInt16 Top; - public UInt16 Right; - public UInt16 Bottom; - } - - [StructLayout(LayoutKind.Sequential)] - private struct CONSOLE_SCREEN_BUFFER_INFO - { - public COORD dwSize; - public COORD dwCursorPosition; - public ushort wAttributes; - public SMALL_RECT srWindow; - public COORD dwMaximumWindowSize; - } - - #endregion // Win32 Methods - - #region LevelColors LevelMapping Entry - - /// - /// A class to act as a mapping between the level that a logging call is made at and - /// the color it should be displayed as. - /// - /// - /// - /// Defines the mapping between a level and the color it should be displayed in. - /// - /// - public class LevelColors : LevelMappingEntry - { - private Colors m_foreColor; - private Colors m_backColor; - private ushort m_combinedColor = 0; - - /// - /// The mapped foreground color for the specified level - /// - /// - /// - /// Required property. - /// The mapped foreground color for the specified level. - /// - /// - public Colors ForeColor - { - get { return m_foreColor; } - set { m_foreColor = value; } - } - - /// - /// The mapped background color for the specified level - /// - /// - /// - /// Required property. - /// The mapped background color for the specified level. - /// - /// - public Colors BackColor - { - get { return m_backColor; } - set { m_backColor = value; } - } - - /// - /// Initialize the options for the object - /// - /// - /// - /// Combine the and together. - /// - /// - public override void ActivateOptions() - { - base.ActivateOptions(); - m_combinedColor = (ushort)( (int)m_foreColor + (((int)m_backColor) << 4) ); - } - - /// - /// The combined and suitable for - /// setting the console color. - /// - internal ushort CombinedColor - { - get { return m_combinedColor; } - } - } - - #endregion // LevelColors LevelMapping Entry - } -} - -#endif // !NETCF diff --git a/src/log4net/Appender/ConsoleAppender.cs b/src/log4net/Appender/ConsoleAppender.cs deleted file mode 100644 index 312e348a..00000000 --- a/src/log4net/Appender/ConsoleAppender.cs +++ /dev/null @@ -1,183 +0,0 @@ -#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 System.Globalization; - -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Appends logging events to the console. - /// - /// - /// - /// ConsoleAppender appends log events to the standard output stream - /// or the error output stream using a layout specified by the - /// user. - /// - /// - /// By default, all output is written to the console's standard output stream. - /// The property can be set to direct the output to the - /// error stream. - /// - /// - /// NOTE: This appender writes each message to the System.Console.Out or - /// System.Console.Error that is set at the time the event is appended. - /// Therefore it is possible to programmatically redirect the output of this appender - /// (for example NUnit does this to capture program output). While this is the desired - /// behavior of this appender it may have security implications in your application. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class ConsoleAppender : AppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// The instance of the class is set up to write - /// to the standard output stream. - /// - public ConsoleAppender() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - virtual public string Target - { - get { return m_writeToErrorStream ? ConsoleError : ConsoleOut; } - set - { - string v = value.Trim(); - - if (string.Compare(ConsoleError, v, true, CultureInfo.InvariantCulture) == 0) - { - m_writeToErrorStream = true; - } - else - { - m_writeToErrorStream = false; - } - } - } - - #endregion Public Instance Properties - - #region Override implementation of AppenderSkeleton - - /// - /// This method is called by the method. - /// - /// The event to log. - /// - /// - /// Writes the event to the console. - /// - /// - /// The format of the output will depend on the appender's layout. - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - if (m_writeToErrorStream) - { - // Write to the error stream - Console.Error.Write(RenderLoggingEvent(loggingEvent)); - } - else - { - // Write to the output stream - Console.Write(RenderLoggingEvent(loggingEvent)); - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion Override implementation of AppenderSkeleton - - #region Public Static Fields - - /// - /// The to use when writing to the Console - /// standard output stream. - /// - /// - /// - /// The to use when writing to the Console - /// standard output stream. - /// - /// - public const string ConsoleOut = "Console.Out"; - - /// - /// The to use when writing to the Console - /// standard error output stream. - /// - /// - /// - /// The to use when writing to the Console - /// standard error output stream. - /// - /// - public const string ConsoleError = "Console.Error"; - - #endregion Public Static Fields - - #region Private Instances Fields - - private bool m_writeToErrorStream = false; - - #endregion Private Instances Fields - } -} diff --git a/src/log4net/Appender/DebugAppender.cs b/src/log4net/Appender/DebugAppender.cs deleted file mode 100644 index d9b1c0dd..00000000 --- a/src/log4net/Appender/DebugAppender.cs +++ /dev/null @@ -1,155 +0,0 @@ -#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 - -#define DEBUG - -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Appends log events to the system. - /// - /// - /// - /// The application configuration file can be used to control what listeners - /// are actually used. See the MSDN documentation for the - /// class for details on configuring the - /// debug system. - /// - /// - /// Events are written using the - /// method. The event's logger name is passed as the value for the category name to the Write method. - /// - /// - /// Nicko Cadell - public class DebugAppender : AppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the . - /// - /// - /// - /// Default constructor. - /// - /// - public DebugAppender() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets a value that indicates whether the appender will - /// flush at the end of each write. - /// - /// - /// The default behavior is to flush at the end of each - /// write. If the option is set tofalse, then the underlying - /// stream can defer writing to physical medium to a later time. - /// - /// - /// Avoiding the flush operation at the end of each append results - /// in a performance gain of 10 to 20 percent. However, there is safety - /// trade-off involved in skipping flushing. Indeed, when flushing is - /// skipped, then it is likely that the last few log events will not - /// be recorded on disk when the application exits. This is a high - /// price to pay even for a 20% performance gain. - /// - /// - public bool ImmediateFlush - { - get { return m_immediateFlush; } - set { m_immediateFlush = value; } - } - - #endregion Public Instance Properties - - #region Override implementation of AppenderSkeleton - - /// - /// Writes the logging event to the system. - /// - /// The event to log. - /// - /// - /// Writes the logging event to the system. - /// If is true then the - /// is called. - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - // - // Write the string to the Debug system - // - System.Diagnostics.Debug.Write(RenderLoggingEvent(loggingEvent), loggingEvent.LoggerName); - - // - // Flush the Debug system if needed - // - if (m_immediateFlush) - { - System.Diagnostics.Debug.Flush(); - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion Override implementation of AppenderSkeleton - - #region Private Instance Fields - - /// - /// Immediate flush means that the underlying writer or output stream - /// will be flushed at the end of each append operation. - /// - /// - /// - /// Immediate flush is slower but ensures that each append request is - /// actually written. If is set to - /// false, then there is a good chance that the last few - /// logs events are not actually written to persistent media if and - /// when the application crashes. - /// - /// - /// The default value is true. - /// - private bool m_immediateFlush = true; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Appender/EventLogAppender.cs b/src/log4net/Appender/EventLogAppender.cs deleted file mode 100644 index 1d78cd13..00000000 --- a/src/log4net/Appender/EventLogAppender.cs +++ /dev/null @@ -1,661 +0,0 @@ -#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 - -#if !NETCF - -using System; -using System.Diagnostics; -using System.Globalization; - -using log4net.Util; -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Writes events to the system event log. - /// - /// - /// - /// The appender will fail if you try to write using an event source that doesn't exist unless it is running with local administrator privileges. - /// See also http://logging.apache.org/log4net/release/faq.html#trouble-EventLog - /// - /// - /// The EventID of the event log entry can be - /// set using the EventID property () - /// on the . - /// - /// - /// The Category of the event log entry can be - /// set using the Category property () - /// on the . - /// - /// - /// There is a limit of 32K characters for an event log message - /// - /// - /// When configuring the EventLogAppender a mapping can be - /// specified to map a logging level to an event log entry type. For example: - /// - /// - /// <mapping> - /// <level value="ERROR" /> - /// <eventLogEntryType value="Error" /> - /// </mapping> - /// <mapping> - /// <level value="DEBUG" /> - /// <eventLogEntryType value="Information" /> - /// </mapping> - /// - /// - /// The Level is the standard log4net logging level and eventLogEntryType can be any value - /// from the enum, i.e.: - /// - /// Erroran error event - /// Warninga warning event - /// Informationan informational event - /// - /// - /// - /// Aspi Havewala - /// Douglas de la Torre - /// Nicko Cadell - /// Gert Driesen - /// Thomas Voss - public class EventLogAppender : AppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public EventLogAppender() - { - m_applicationName = System.Threading.Thread.GetDomain().FriendlyName; - m_logName = "Application"; // Defaults to application log - m_machineName = "."; // Only log on the local machine - } - - #endregion // Public Instance Constructors - - #region Public Instance Properties - - /// - /// The name of the log where messages will be stored. - /// - /// - /// The string name of the log where messages will be stored. - /// - /// - /// This is the name of the log as it appears in the Event Viewer - /// tree. The default value is to log into the Application - /// log, this is where most applications write their events. However - /// if you need a separate log for your application (or applications) - /// then you should set the appropriately. - /// This should not be used to distinguish your event log messages - /// from those of other applications, the - /// property should be used to distinguish events. This property should be - /// used to group together events into a single log. - /// - /// - public string LogName - { - get { return m_logName; } - set { m_logName = value; } - } - - /// - /// Property used to set the Application name. This appears in the - /// event logs when logging. - /// - /// - /// The string used to distinguish events from different sources. - /// - /// - /// Sets the event log source property. - /// - public string ApplicationName - { - get { return m_applicationName; } - set { m_applicationName = value; } - } - - /// - /// This property is used to return the name of the computer to use - /// when accessing the event logs. Currently, this is the current - /// computer, denoted by a dot "." - /// - /// - /// The string name of the machine holding the event log that - /// will be logged into. - /// - /// - /// This property cannot be changed. It is currently set to '.' - /// i.e. the local machine. This may be changed in future. - /// - public string MachineName - { - get { return m_machineName; } - set { /* Currently we do not allow the machine name to be changed */; } - } - - /// - /// Add a mapping of level to - done by the config file - /// - /// The mapping to add - /// - /// - /// Add a mapping to this appender. - /// Each mapping defines the event log entry type for a level. - /// - /// - public void AddMapping(Level2EventLogEntryType mapping) - { - m_levelMapping.Add(mapping); - } - - /// - /// Gets or sets the used to write to the EventLog. - /// - /// - /// The used to write to the EventLog. - /// - /// - /// - /// The system security context used to write to the EventLog. - /// - /// - /// Unless a specified here for this appender - /// the is queried for the - /// security context to use. The default behavior is to use the security context - /// of the current thread. - /// - /// - public SecurityContext SecurityContext - { - get { return m_securityContext; } - set { m_securityContext = value; } - } - - /// - /// Gets or sets the EventId to use unless one is explicitly specified via the LoggingEvent's properties. - /// - /// - /// - /// The EventID of the event log entry will normally be - /// set using the EventID property () - /// on the . - /// This property provides the fallback value which defaults to 0. - /// - /// - public int EventId { - get { return m_eventId; } - set { m_eventId = value; } - } - - - /// - /// Gets or sets the Category to use unless one is explicitly specified via the LoggingEvent's properties. - /// - /// - /// - /// The Category of the event log entry will normally be - /// set using the Category property () - /// on the . - /// This property provides the fallback value which defaults to 0. - /// - /// - public short Category - { - get { return m_category; } - set { m_category = value; } - } - #endregion // Public Instance Properties - - #region Implementation of IOptionHandler - - /// - /// Initialize the appender based on the options set - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - override public void ActivateOptions() - { - try - { - base.ActivateOptions(); - - if (m_securityContext == null) - { - m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); - } - - bool sourceAlreadyExists = false; - string currentLogName = null; - - using (SecurityContext.Impersonate(this)) - { - sourceAlreadyExists = EventLog.SourceExists(m_applicationName); - if (sourceAlreadyExists) { - currentLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); - } - } - - if (sourceAlreadyExists && currentLogName != m_logName) - { - LogLog.Debug(declaringType, "Changing event source [" + m_applicationName + "] from log [" + currentLogName + "] to log [" + m_logName + "]"); - } - else if (!sourceAlreadyExists) - { - LogLog.Debug(declaringType, "Creating event source Source [" + m_applicationName + "] in log " + m_logName + "]"); - } - - string registeredLogName = null; - - using (SecurityContext.Impersonate(this)) - { - if (sourceAlreadyExists && currentLogName != m_logName) - { - // - // Re-register this to the current application if the user has changed - // the application / logfile association - // - EventLog.DeleteEventSource(m_applicationName, m_machineName); - CreateEventSource(m_applicationName, m_logName, m_machineName); - - registeredLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); - } - else if (!sourceAlreadyExists) - { - CreateEventSource(m_applicationName, m_logName, m_machineName); - - registeredLogName = EventLog.LogNameFromSourceName(m_applicationName, m_machineName); - } - } - - m_levelMapping.ActivateOptions(); - - LogLog.Debug(declaringType, "Source [" + m_applicationName + "] is registered to log [" + registeredLogName + "]"); - } - catch (System.Security.SecurityException ex) - { - ErrorHandler.Error("Caught a SecurityException trying to access the EventLog. Most likely the event source " - + m_applicationName - + " doesn't exist and must be created by a local administrator. Will disable EventLogAppender." - + " See http://logging.apache.org/log4net/release/faq.html#trouble-EventLog", - ex); - Threshold = Level.Off; - } - } - - #endregion // Implementation of IOptionHandler - - /// - /// Create an event log source - /// - private static void CreateEventSource(string source, string logName, string machineName) - { - EventSourceCreationData eventSourceCreationData = new EventSourceCreationData(source, logName); - eventSourceCreationData.MachineName = machineName; - EventLog.CreateEventSource(eventSourceCreationData); - } - - #region Override implementation of AppenderSkeleton - - /// - /// This method is called by the - /// method. - /// - /// the event to log - /// - /// Writes the event to the system event log using the - /// . - /// - /// If the event has an EventID property (see ) - /// set then this integer will be used as the event log event id. - /// - /// - /// There is a limit of 32K characters for an event log message - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - // - // Write the resulting string to the event log system - // - int eventID = m_eventId; - - // Look for the EventID property - object eventIDPropertyObj = loggingEvent.LookupProperty("EventID"); - if (eventIDPropertyObj != null) - { - if (eventIDPropertyObj is int) - { - eventID = (int)eventIDPropertyObj; - } - else - { - string eventIDPropertyString = eventIDPropertyObj as string; - if (eventIDPropertyString == null) - { - eventIDPropertyString = eventIDPropertyObj.ToString(); - } - if (eventIDPropertyString != null && eventIDPropertyString.Length > 0) - { - // Read the string property into a number - int intVal; - if (SystemInfo.TryParse(eventIDPropertyString, out intVal)) - { - eventID = intVal; - } - else - { - ErrorHandler.Error("Unable to parse event ID property [" + eventIDPropertyString + "]."); - } - } - } - } - - short category = m_category; - // Look for the Category property - object categoryPropertyObj = loggingEvent.LookupProperty("Category"); - if (categoryPropertyObj != null) - { - if (categoryPropertyObj is short) - { - category = (short) categoryPropertyObj; - } - else - { - string categoryPropertyString = categoryPropertyObj as string; - if (categoryPropertyString == null) - { - categoryPropertyString = categoryPropertyObj.ToString(); - } - if (categoryPropertyString != null && categoryPropertyString.Length > 0) - { - // Read the string property into a number - short shortVal; - if (SystemInfo.TryParse(categoryPropertyString, out shortVal)) - { - category = shortVal; - } - else - { - ErrorHandler.Error("Unable to parse event category property [" + categoryPropertyString + "]."); - } - } - } - } - - // Write to the event log - try - { - string eventTxt = RenderLoggingEvent(loggingEvent); - - // There is a limit of about 32K characters for an event log message - if (eventTxt.Length > MAX_EVENTLOG_MESSAGE_SIZE) - { - eventTxt = eventTxt.Substring(0, MAX_EVENTLOG_MESSAGE_SIZE); - } - - EventLogEntryType entryType = GetEntryType(loggingEvent.Level); - - using(SecurityContext.Impersonate(this)) - { - EventLog.WriteEntry(m_applicationName, eventTxt, entryType, eventID, category); - } - } - catch(Exception ex) - { - ErrorHandler.Error("Unable to write to event log [" + m_logName + "] using source [" + m_applicationName + "]", ex); - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion // Override implementation of AppenderSkeleton - - #region Protected Instance Methods - - /// - /// Get the equivalent for a - /// - /// the Level to convert to an EventLogEntryType - /// The equivalent for a - /// - /// Because there are fewer applicable - /// values to use in logging levels than there are in the - /// this is a one way mapping. There is - /// a loss of information during the conversion. - /// - virtual protected EventLogEntryType GetEntryType(Level level) - { - // see if there is a specified lookup. - Level2EventLogEntryType entryType = m_levelMapping.Lookup(level) as Level2EventLogEntryType; - if (entryType != null) - { - return entryType.EventLogEntryType; - } - - // Use default behavior - - if (level >= Level.Error) - { - return EventLogEntryType.Error; - } - else if (level == Level.Warn) - { - return EventLogEntryType.Warning; - } - - // Default setting - return EventLogEntryType.Information; - } - - #endregion // Protected Instance Methods - - #region Private Instance Fields - - /// - /// The log name is the section in the event logs where the messages - /// are stored. - /// - private string m_logName; - - /// - /// Name of the application to use when logging. This appears in the - /// application column of the event log named by . - /// - private string m_applicationName; - - /// - /// The name of the machine which holds the event log. This is - /// currently only allowed to be '.' i.e. the current machine. - /// - private string m_machineName; - - /// - /// Mapping from level object to EventLogEntryType - /// - private LevelMapping m_levelMapping = new LevelMapping(); - - /// - /// The security context to use for privileged calls - /// - private SecurityContext m_securityContext; - - /// - /// The event ID to use unless one is explicitly specified via the LoggingEvent's properties. - /// - private int m_eventId = 0; - - /// - /// The event category to use unless one is explicitly specified via the LoggingEvent's properties. - /// - private short m_category = 0; - - #endregion // Private Instance Fields - - #region Level2EventLogEntryType LevelMapping Entry - - /// - /// A class to act as a mapping between the level that a logging call is made at and - /// the color it should be displayed as. - /// - /// - /// - /// Defines the mapping between a level and its event log entry type. - /// - /// - public class Level2EventLogEntryType : LevelMappingEntry - { - private EventLogEntryType m_entryType; - - /// - /// The for this entry - /// - /// - /// - /// Required property. - /// The for this entry - /// - /// - public EventLogEntryType EventLogEntryType - { - get { return m_entryType; } - set { m_entryType = value; } - } - } - - #endregion // LevelColors LevelMapping Entry - - #region Private Static Fields - - /// - /// The fully qualified type of the EventLogAppender class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(EventLogAppender); - - /// - /// The maximum size supported by default. - /// - /// - /// http://msdn.microsoft.com/en-us/library/xzwc042w(v=vs.100).aspx - /// The 32766 documented max size is two bytes shy of 32K (I'm assuming 32766 - /// may leave space for a two byte null terminator of #0#0). The 32766 max - /// length is what the .NET 4.0 source code checks for, but this is WRONG! - /// Strings with a length > 31839 on Windows Vista or higher can CORRUPT - /// the event log! See: System.Diagnostics.EventLogInternal.InternalWriteEvent() - /// for the use of the 32766 max size. - /// - private readonly static int MAX_EVENTLOG_MESSAGE_SIZE_DEFAULT = 32766; - - /// - /// The maximum size supported by a windows operating system that is vista - /// or newer. - /// - /// - /// See ReportEvent API: - /// http://msdn.microsoft.com/en-us/library/aa363679(VS.85).aspx - /// ReportEvent's lpStrings parameter: - /// "A pointer to a buffer containing an array of - /// null-terminated strings that are merged into the message before Event Viewer - /// displays the string to the user. This parameter must be a valid pointer - /// (or NULL), even if wNumStrings is zero. Each string is limited to 31,839 characters." - /// - /// Going beyond the size of 31839 will (at some point) corrupt the event log on Windows - /// Vista or higher! It may succeed for a while...but you will eventually run into the - /// error: "System.ComponentModel.Win32Exception : A device attached to the system is - /// not functioning", and the event log will then be corrupt (I was able to corrupt - /// an event log using a length of 31877 on Windows 7). - /// - /// The max size for Windows Vista or higher is documented here: - /// http://msdn.microsoft.com/en-us/library/xzwc042w(v=vs.100).aspx. - /// Going over this size may succeed a few times but the buffer will overrun and - /// eventually corrupt the log (based on testing). - /// - /// The maxEventMsgSize size is based on the max buffer size of the lpStrings parameter of the ReportEvent API. - /// The documented max size for EventLog.WriteEntry for Windows Vista and higher is 31839, but I'm leaving room for a - /// terminator of #0#0, as we cannot see the source of ReportEvent (though we could use an API monitor to examine the - /// buffer, given enough time). - /// - private readonly static int MAX_EVENTLOG_MESSAGE_SIZE_VISTA_OR_NEWER = 31839 - 2; - - /// - /// The maximum size that the operating system supports for - /// a event log message. - /// - /// - /// Used to determine the maximum string length that can be written - /// to the operating system event log and eventually truncate a string - /// that exceeds the limits. - /// - private readonly static int MAX_EVENTLOG_MESSAGE_SIZE = GetMaxEventLogMessageSize(); - - /// - /// This method determines the maximum event log message size allowed for - /// the current environment. - /// - /// - private static int GetMaxEventLogMessageSize() - { - if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6) - return MAX_EVENTLOG_MESSAGE_SIZE_VISTA_OR_NEWER; - return MAX_EVENTLOG_MESSAGE_SIZE_DEFAULT; - } - - #endregion Private Static Fields - } -} - -#endif // !NETCF diff --git a/src/log4net/Appender/FileAppender.cs b/src/log4net/Appender/FileAppender.cs deleted file mode 100644 index e4056417..00000000 --- a/src/log4net/Appender/FileAppender.cs +++ /dev/null @@ -1,1324 +0,0 @@ -#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 System.IO; -using System.Text; -using System.Threading; -using log4net.Util; -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ -#if !NETCF - /// - /// Appends logging events to a file. - /// - /// - /// - /// Logging events are sent to the file specified by - /// the property. - /// - /// - /// The file can be opened in either append or overwrite mode - /// by specifying the property. - /// If the file path is relative it is taken as relative from - /// the application base directory. The file encoding can be - /// specified by setting the property. - /// - /// - /// The layout's and - /// values will be written each time the file is opened and closed - /// respectively. If the property is - /// then the file may contain multiple copies of the header and footer. - /// - /// - /// This appender will first try to open the file for writing when - /// is called. This will typically be during configuration. - /// If the file cannot be opened for writing the appender will attempt - /// to open the file again each time a message is logged to the appender. - /// If the file cannot be opened for writing when a message is logged then - /// the message will be discarded by this appender. - /// - /// - /// The supports pluggable file locking models via - /// the property. - /// The default behavior, implemented by - /// is to obtain an exclusive write lock on the file until this appender is closed. - /// The alternative models only hold a - /// write lock while the appender is writing a logging event () - /// or synchronize by using a named system wide Mutex (). - /// - /// - /// All locking strategies have issues and you should seriously consider using a different strategy that - /// avoids having multiple processes logging to the same file. - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Rodrigo B. de Oliveira - /// Douglas de la Torre - /// Niall Daley -#else - /// - /// Appends logging events to a file. - /// - /// - /// - /// Logging events are sent to the file specified by - /// the property. - /// - /// - /// The file can be opened in either append or overwrite mode - /// by specifying the property. - /// If the file path is relative it is taken as relative from - /// the application base directory. The file encoding can be - /// specified by setting the property. - /// - /// - /// The layout's and - /// values will be written each time the file is opened and closed - /// respectively. If the property is - /// then the file may contain multiple copies of the header and footer. - /// - /// - /// This appender will first try to open the file for writing when - /// is called. This will typically be during configuration. - /// If the file cannot be opened for writing the appender will attempt - /// to open the file again each time a message is logged to the appender. - /// If the file cannot be opened for writing when a message is logged then - /// the message will be discarded by this appender. - /// - /// - /// The supports pluggable file locking models via - /// the property. - /// The default behavior, implemented by - /// is to obtain an exclusive write lock on the file until this appender is closed. - /// The alternative model only holds a - /// write lock while the appender is writing a logging event (). - /// - /// - /// All locking strategies have issues and you should seriously consider using a different strategy that - /// avoids having multiple processes logging to the same file. - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Rodrigo B. de Oliveira - /// Douglas de la Torre - /// Niall Daley -#endif - public class FileAppender : TextWriterAppender - { - #region LockingStream Inner Class - - /// - /// Write only that uses the - /// to manage access to an underlying resource. - /// - private sealed class LockingStream : Stream, IDisposable - { - public sealed class LockStateException : LogException - { - public LockStateException(string message): base(message) - { - } - } - - private Stream m_realStream=null; - private LockingModelBase m_lockingModel=null; - private int m_readTotal=-1; - private int m_lockLevel=0; - - public LockingStream(LockingModelBase locking) : base() - { - if (locking==null) - { - throw new ArgumentException("Locking model may not be null","locking"); - } - m_lockingModel=locking; - } - - #region Override Implementation of Stream - - // Methods - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - AssertLocked(); - IAsyncResult ret=m_realStream.BeginRead(buffer,offset,count,callback,state); - m_readTotal=EndRead(ret); - return ret; - } - - /// - /// True asynchronous writes are not supported, the implementation forces a synchronous write. - /// - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - AssertLocked(); - IAsyncResult ret=m_realStream.BeginWrite(buffer,offset,count,callback,state); - EndWrite(ret); - return ret; - } - - public override void Close() - { - m_lockingModel.CloseFile(); - } - - public override int EndRead(IAsyncResult asyncResult) - { - AssertLocked(); - return m_readTotal; - } - public override void EndWrite(IAsyncResult asyncResult) - { - //No-op, it has already been handled - } - public override void Flush() - { - AssertLocked(); - m_realStream.Flush(); - } - public override int Read(byte[] buffer, int offset, int count) - { - return m_realStream.Read(buffer,offset,count); - } - public override int ReadByte() - { - return m_realStream.ReadByte(); - } - public override long Seek(long offset, SeekOrigin origin) - { - AssertLocked(); - return m_realStream.Seek(offset,origin); - } - public override void SetLength(long value) - { - AssertLocked(); - m_realStream.SetLength(value); - } - void IDisposable.Dispose() - { - Close(); - } - public override void Write(byte[] buffer, int offset, int count) - { - AssertLocked(); - m_realStream.Write(buffer,offset,count); - } - public override void WriteByte(byte value) - { - AssertLocked(); - m_realStream.WriteByte(value); - } - - // Properties - public override bool CanRead - { - get { return false; } - } - public override bool CanSeek - { - get - { - AssertLocked(); - return m_realStream.CanSeek; - } - } - public override bool CanWrite - { - get - { - AssertLocked(); - return m_realStream.CanWrite; - } - } - public override long Length - { - get - { - AssertLocked(); - return m_realStream.Length; - } - } - public override long Position - { - get - { - AssertLocked(); - return m_realStream.Position; - } - set - { - AssertLocked(); - m_realStream.Position=value; - } - } - - #endregion Override Implementation of Stream - - #region Locking Methods - - private void AssertLocked() - { - if (m_realStream == null) - { - throw new LockStateException("The file is not currently locked"); - } - } - - public bool AcquireLock() - { - bool ret=false; - lock(this) - { - if (m_lockLevel==0) - { - // If lock is already acquired, nop - m_realStream=m_lockingModel.AcquireLock(); - } - if (m_realStream!=null) - { - m_lockLevel++; - ret=true; - } - } - return ret; - } - - public void ReleaseLock() - { - lock(this) - { - m_lockLevel--; - if (m_lockLevel==0) - { - // If already unlocked, nop - m_lockingModel.ReleaseLock(); - m_realStream=null; - } - } - } - - #endregion Locking Methods - } - - #endregion LockingStream Inner Class - - #region Locking Models - - /// - /// Locking model base class - /// - /// - /// - /// Base class for the locking models available to the derived loggers. - /// - /// - public abstract class LockingModelBase - { - private FileAppender m_appender=null; - - /// - /// Open the output file - /// - /// The filename to use - /// Whether to append to the file, or overwrite - /// The encoding to use - /// - /// - /// Open the file specified and prepare for logging. - /// No writes will be made until is called. - /// Must be called before any calls to , - /// and . - /// - /// - public abstract void OpenFile(string filename, bool append,Encoding encoding); - - /// - /// Close the file - /// - /// - /// - /// Close the file. No further writes will be made. - /// - /// - public abstract void CloseFile(); - - /// - /// Acquire the lock on the file - /// - /// A stream that is ready to be written to. - /// - /// - /// Acquire the lock on the file in preparation for writing to it. - /// Return a stream pointing to the file. - /// must be called to release the lock on the output file. - /// - /// - public abstract Stream AcquireLock(); - - /// - /// Release the lock on the file - /// - /// - /// - /// Release the lock on the file. No further writes will be made to the - /// stream until is called again. - /// - /// - public abstract void ReleaseLock(); - - /// - /// Gets or sets the for this LockingModel - /// - /// - /// The for this LockingModel - /// - /// - /// - /// The file appender this locking model is attached to and working on - /// behalf of. - /// - /// - /// The file appender is used to locate the security context and the error handler to use. - /// - /// - /// The value of this property will be set before is - /// called. - /// - /// - public FileAppender CurrentAppender - { - get { return m_appender; } - set { m_appender = value; } - } - - /// - /// Helper method that creates a FileStream under CurrentAppender's SecurityContext. - /// - /// - /// - /// Typically called during OpenFile or AcquireLock. - /// - /// - /// If the directory portion of the does not exist, it is created - /// via Directory.CreateDirecctory. - /// - /// - /// - /// - /// - /// - protected Stream CreateStream(string filename, bool append, FileShare fileShare) - { - using (CurrentAppender.SecurityContext.Impersonate(this)) - { - // Ensure that the directory structure exists - string directoryFullName = Path.GetDirectoryName(filename); - - // Only create the directory if it does not exist - // doing this check here resolves some permissions failures - if (!Directory.Exists(directoryFullName)) - { - Directory.CreateDirectory(directoryFullName); - } - - FileMode fileOpenMode = append ? FileMode.Append : FileMode.Create; - return new FileStream(filename, fileOpenMode, FileAccess.Write, fileShare); - } - } - - /// - /// Helper method to close under CurrentAppender's SecurityContext. - /// - /// - /// Does not set to null. - /// - /// - protected void CloseStream(Stream stream) - { - using (CurrentAppender.SecurityContext.Impersonate(this)) - { - stream.Close(); - } - } - } - - /// - /// Hold an exclusive lock on the output file - /// - /// - /// - /// Open the file once for writing and hold it open until is called. - /// Maintains an exclusive lock on the file during this time. - /// - /// - public class ExclusiveLock : LockingModelBase - { - private Stream m_stream = null; - - /// - /// Open the file specified and prepare for logging. - /// - /// The filename to use - /// Whether to append to the file, or overwrite - /// The encoding to use - /// - /// - /// Open the file specified and prepare for logging. - /// No writes will be made until is called. - /// Must be called before any calls to , - /// and . - /// - /// - public override void OpenFile(string filename, bool append,Encoding encoding) - { - try - { - m_stream = CreateStream(filename, append, FileShare.Read); - } - catch (Exception e1) - { - CurrentAppender.ErrorHandler.Error("Unable to acquire lock on file "+filename+". "+e1.Message); - } - } - - /// - /// Close the file - /// - /// - /// - /// Close the file. No further writes will be made. - /// - /// - public override void CloseFile() - { - CloseStream(m_stream); - m_stream = null; - } - - /// - /// Acquire the lock on the file - /// - /// A stream that is ready to be written to. - /// - /// - /// Does nothing. The lock is already taken - /// - /// - public override Stream AcquireLock() - { - return m_stream; - } - - /// - /// Release the lock on the file - /// - /// - /// - /// Does nothing. The lock will be released when the file is closed. - /// - /// - public override void ReleaseLock() - { - //NOP - } - } - - /// - /// Acquires the file lock for each write - /// - /// - /// - /// Opens the file once for each / cycle, - /// thus holding the lock for the minimal amount of time. This method of locking - /// is considerably slower than but allows - /// other processes to move/delete the log file whilst logging continues. - /// - /// - public class MinimalLock : LockingModelBase - { - private string m_filename; - private bool m_append; - private Stream m_stream=null; - - /// - /// Prepares to open the file when the first message is logged. - /// - /// The filename to use - /// Whether to append to the file, or overwrite - /// The encoding to use - /// - /// - /// Open the file specified and prepare for logging. - /// No writes will be made until is called. - /// Must be called before any calls to , - /// and . - /// - /// - public override void OpenFile(string filename, bool append, Encoding encoding) - { - m_filename=filename; - m_append=append; - } - - /// - /// Close the file - /// - /// - /// - /// Close the file. No further writes will be made. - /// - /// - public override void CloseFile() - { - // NOP - } - - /// - /// Acquire the lock on the file - /// - /// A stream that is ready to be written to. - /// - /// - /// Acquire the lock on the file in preparation for writing to it. - /// Return a stream pointing to the file. - /// must be called to release the lock on the output file. - /// - /// - public override Stream AcquireLock() - { - if (m_stream==null) - { - try - { - m_stream = CreateStream(m_filename, m_append, FileShare.Read); - m_append = true; - } - catch (Exception e1) - { - CurrentAppender.ErrorHandler.Error("Unable to acquire lock on file "+m_filename+". "+e1.Message); - } - } - return m_stream; - } - - /// - /// Release the lock on the file - /// - /// - /// - /// Release the lock on the file. No further writes will be made to the - /// stream until is called again. - /// - /// - public override void ReleaseLock() - { - CloseStream(m_stream); - m_stream = null; - } - } - -#if !NETCF - /// - /// Provides cross-process file locking. - /// - /// Ron Grabowski - /// Steve Wranovsky - public class InterProcessLock : LockingModelBase - { - private Mutex m_mutex = null; - private bool m_mutexClosed = false; - private Stream m_stream = null; - - /// - /// Open the file specified and prepare for logging. - /// - /// The filename to use - /// Whether to append to the file, or overwrite - /// The encoding to use - /// - /// - /// Open the file specified and prepare for logging. - /// No writes will be made until is called. - /// Must be called before any calls to , - /// - and . - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - public override void OpenFile(string filename, bool append, Encoding encoding) - { - try - { - m_stream = CreateStream(filename, append, FileShare.ReadWrite); - - string mutextFriendlyFilename = filename - .Replace("\\", "_") - .Replace(":", "_") - .Replace("/", "_"); - - m_mutex = new Mutex(false, mutextFriendlyFilename); - m_mutexClosed = false; - } - catch (Exception e1) - { - CurrentAppender.ErrorHandler.Error("Unable to acquire lock on file " + filename + ". " + e1.Message); - } - } - - /// - /// Close the file - /// - /// - /// - /// Close the file. No further writes will be made. - /// - /// - public override void CloseFile() - { - try { - CloseStream(m_stream); - m_stream = null; - } - finally { - m_mutex.ReleaseMutex(); - m_mutex.Close(); - m_mutexClosed = true; - } - } - - /// - /// Acquire the lock on the file - /// - /// A stream that is ready to be written to. - /// - /// - /// Does nothing. The lock is already taken - /// - /// - public override Stream AcquireLock() - { - if (m_mutex != null) { - // TODO: add timeout? - m_mutex.WaitOne(); - - // should always be true (and fast) for FileStream - if (m_stream.CanSeek) { - m_stream.Seek(0, SeekOrigin.End); - } - } - - return m_stream; - } - - /// - /// - /// - public override void ReleaseLock() - { - if (m_mutexClosed == false && m_mutex != null) - { - m_mutex.ReleaseMutex(); - } - } - } -#endif - - #endregion Locking Models - - #region Public Instance Constructors - - /// - /// Default constructor - /// - /// - /// - /// Default constructor - /// - /// - public FileAppender() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the path to the file that logging will be written to. - /// - /// - /// The path to the file that logging will be written to. - /// - /// - /// - /// If the path is relative it is taken as relative from - /// the application base directory. - /// - /// - virtual public string File - { - get { return m_fileName; } - set { m_fileName = value; } - } - - /// - /// Gets or sets a flag that indicates whether the file should be - /// appended to or overwritten. - /// - /// - /// Indicates whether the file should be appended to or overwritten. - /// - /// - /// - /// If the value is set to false then the file will be overwritten, if - /// it is set to true then the file will be appended to. - /// - /// The default value is true. - /// - public bool AppendToFile - { - get { return m_appendToFile; } - set { m_appendToFile = value; } - } - - /// - /// Gets or sets used to write to the file. - /// - /// - /// The used to write to the file. - /// - /// - /// - /// The default encoding set is - /// which is the encoding for the system's current ANSI code page. - /// - /// - public Encoding Encoding - { - get { return m_encoding; } - set { m_encoding = value; } - } - - /// - /// Gets or sets the used to write to the file. - /// - /// - /// The used to write to the file. - /// - /// - /// - /// Unless a specified here for this appender - /// the is queried for the - /// security context to use. The default behavior is to use the security context - /// of the current thread. - /// - /// - public SecurityContext SecurityContext - { - get { return m_securityContext; } - set { m_securityContext = value; } - } - -#if NETCF - /// - /// Gets or sets the used to handle locking of the file. - /// - /// - /// The used to lock the file. - /// - /// - /// - /// Gets or sets the used to handle locking of the file. - /// - /// - /// There are two built in locking models, and . - /// The first locks the file from the start of logging to the end, the - /// second locks only for the minimal amount of time when logging each message - /// and the last synchronizes processes using a named system wide Mutex. - /// - /// - /// The default locking model is the . - /// - /// -#else - /// - /// Gets or sets the used to handle locking of the file. - /// - /// - /// The used to lock the file. - /// - /// - /// - /// Gets or sets the used to handle locking of the file. - /// - /// - /// There are three built in locking models, , and . - /// The first locks the file from the start of logging to the end, the - /// second locks only for the minimal amount of time when logging each message - /// and the last synchronizes processes using a named system wide Mutex. - /// - /// - /// The default locking model is the . - /// - /// -#endif - public FileAppender.LockingModelBase LockingModel - { - get { return m_lockingModel; } - set { m_lockingModel = value; } - } - - #endregion Public Instance Properties - - #region Override implementation of AppenderSkeleton - - /// - /// Activate the options on the file appender. - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// This will cause the file to be opened. - /// - /// - override public void ActivateOptions() - { - base.ActivateOptions(); - - if (m_securityContext == null) - { - m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); - } - - if (m_lockingModel == null) - { - m_lockingModel = new FileAppender.ExclusiveLock(); - } - - m_lockingModel.CurrentAppender=this; - - if (m_fileName != null) - { - using(SecurityContext.Impersonate(this)) - { - m_fileName = ConvertToFullPath(m_fileName.Trim()); - } - SafeOpenFile(m_fileName, m_appendToFile); - } - else - { - LogLog.Warn(declaringType, "FileAppender: File option not set for appender ["+Name+"]."); - LogLog.Warn(declaringType, "FileAppender: Are you using FileAppender instead of ConsoleAppender?"); - } - } - - #endregion Override implementation of AppenderSkeleton - - #region Override implementation of TextWriterAppender - - /// - /// Closes any previously opened file and calls the parent's . - /// - /// - /// - /// Resets the filename and the file stream. - /// - /// - override protected void Reset() - { - base.Reset(); - m_fileName = null; - } - - /// - /// Called to initialize the file writer - /// - /// - /// - /// Will be called for each logged message until the file is - /// successfully opened. - /// - /// - override protected void PrepareWriter() - { - SafeOpenFile(m_fileName, m_appendToFile); - } - - /// - /// This method is called by the - /// method. - /// - /// The event to log. - /// - /// - /// Writes a log statement to the output stream if the output stream exists - /// and is writable. - /// - /// - /// The format of the output will depend on the appender's layout. - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - if (m_stream.AcquireLock()) - { - try - { - base.Append(loggingEvent); - } - finally - { - m_stream.ReleaseLock(); - } - } - } - - /// - /// This method is called by the - /// method. - /// - /// The array of events to log. - /// - /// - /// Acquires the output file locks once before writing all the events to - /// the stream. - /// - /// - override protected void Append(LoggingEvent[] loggingEvents) - { - if (m_stream.AcquireLock()) - { - try - { - base.Append(loggingEvents); - } - finally - { - m_stream.ReleaseLock(); - } - } - } - - /// - /// Writes a footer as produced by the embedded layout's property. - /// - /// - /// - /// Writes a footer as produced by the embedded layout's property. - /// - /// - protected override void WriteFooter() - { - if (m_stream!=null) - { - //WriteFooter can be called even before a file is opened - m_stream.AcquireLock(); - try - { - base.WriteFooter(); - } - finally - { - m_stream.ReleaseLock(); - } - } - } - - /// - /// Writes a header produced by the embedded layout's property. - /// - /// - /// - /// Writes a header produced by the embedded layout's property. - /// - /// - protected override void WriteHeader() - { - if (m_stream!=null) - { - if (m_stream.AcquireLock()) - { - try - { - base.WriteHeader(); - } - finally - { - m_stream.ReleaseLock(); - } - } - } - } - - /// - /// Closes the underlying . - /// - /// - /// - /// Closes the underlying . - /// - /// - protected override void CloseWriter() - { - if (m_stream!=null) - { - m_stream.AcquireLock(); - try - { - base.CloseWriter(); - } - finally - { - m_stream.ReleaseLock(); - } - } - } - - #endregion Override implementation of TextWriterAppender - - #region Public Instance Methods - - /// - /// Closes the previously opened file. - /// - /// - /// - /// Writes the to the file and then - /// closes the file. - /// - /// - protected void CloseFile() - { - WriteFooterAndCloseWriter(); - } - - #endregion Public Instance Methods - - #region Protected Instance Methods - - /// - /// Sets and opens the file where the log output will go. The specified file must be writable. - /// - /// The path to the log file. Must be a fully qualified path. - /// If true will append to fileName. Otherwise will truncate fileName - /// - /// - /// Calls but guarantees not to throw an exception. - /// Errors are passed to the . - /// - /// - virtual protected void SafeOpenFile(string fileName, bool append) - { - try - { - OpenFile(fileName, append); - } - catch(Exception e) - { - ErrorHandler.Error("OpenFile("+fileName+","+append+") call failed.", e, ErrorCode.FileOpenFailure); - } - } - - /// - /// Sets and opens the file where the log output will go. The specified file must be writable. - /// - /// The path to the log file. Must be a fully qualified path. - /// If true will append to fileName. Otherwise will truncate fileName - /// - /// - /// If there was already an opened file, then the previous file - /// is closed first. - /// - /// - /// This method will ensure that the directory structure - /// for the specified exists. - /// - /// - virtual protected void OpenFile(string fileName, bool append) - { - if (LogLog.IsErrorEnabled) - { - // Internal check that the fileName passed in is a rooted path - bool isPathRooted = false; - using(SecurityContext.Impersonate(this)) - { - isPathRooted = Path.IsPathRooted(fileName); - } - if (!isPathRooted) - { - LogLog.Error(declaringType, "INTERNAL ERROR. OpenFile("+fileName+"): File name is not fully qualified."); - } - } - - lock(this) - { - Reset(); - - LogLog.Debug(declaringType, "Opening file for writing ["+fileName+"] append ["+append+"]"); - - // Save these for later, allowing retries if file open fails - m_fileName = fileName; - m_appendToFile = append; - - LockingModel.CurrentAppender=this; - LockingModel.OpenFile(fileName,append,m_encoding); - m_stream=new LockingStream(LockingModel); - - if (m_stream != null) - { - m_stream.AcquireLock(); - try - { - SetQWForFiles(new StreamWriter(m_stream, m_encoding)); - } - finally - { - m_stream.ReleaseLock(); - } - } - - WriteHeader(); - } - } - - /// - /// Sets the quiet writer used for file output - /// - /// the file stream that has been opened for writing - /// - /// - /// This implementation of creates a - /// over the and passes it to the - /// method. - /// - /// - /// This method can be overridden by sub classes that want to wrap the - /// in some way, for example to encrypt the output - /// data using a System.Security.Cryptography.CryptoStream. - /// - /// - virtual protected void SetQWForFiles(Stream fileStream) - { - SetQWForFiles(new StreamWriter(fileStream, m_encoding)); - } - - /// - /// Sets the quiet writer being used. - /// - /// the writer over the file stream that has been opened for writing - /// - /// - /// This method can be overridden by sub classes that want to - /// wrap the in some way. - /// - /// - virtual protected void SetQWForFiles(TextWriter writer) - { - QuietWriter = new QuietTextWriter(writer, ErrorHandler); - } - - #endregion Protected Instance Methods - - #region Protected Static Methods - - /// - /// Convert a path into a fully qualified path. - /// - /// The path to convert. - /// The fully qualified path. - /// - /// - /// Converts the path specified to a fully - /// qualified path. If the path is relative it is - /// taken as relative from the application base - /// directory. - /// - /// - protected static string ConvertToFullPath(string path) - { - return SystemInfo.ConvertToFullPath(path); - } - - #endregion Protected Static Methods - - #region Private Instance Fields - - /// - /// Flag to indicate if we should append to the file - /// or overwrite the file. The default is to append. - /// - private bool m_appendToFile = true; - - /// - /// The name of the log file. - /// - private string m_fileName = null; - - /// - /// The encoding to use for the file stream. - /// - private Encoding m_encoding = Encoding.Default; - - /// - /// The security context to use for privileged calls - /// - private SecurityContext m_securityContext; - - /// - /// The stream to log to. Has added locking semantics - /// - private FileAppender.LockingStream m_stream = null; - - /// - /// The locking model to use - /// - private FileAppender.LockingModelBase m_lockingModel = new FileAppender.ExclusiveLock(); - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the FileAppender class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(FileAppender); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Appender/ForwardingAppender.cs b/src/log4net/Appender/ForwardingAppender.cs deleted file mode 100644 index 681f8125..00000000 --- a/src/log4net/Appender/ForwardingAppender.cs +++ /dev/null @@ -1,279 +0,0 @@ -#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.Util; -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// This appender forwards logging events to attached appenders. - /// - /// - /// - /// The forwarding appender can be used to specify different thresholds - /// and filters for the same appender at different locations within the hierarchy. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class ForwardingAppender : AppenderSkeleton, IAppenderAttachable - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public ForwardingAppender() - { - } - - #endregion Public Instance Constructors - - #region Override implementation of AppenderSkeleton - - /// - /// Closes the appender and releases resources. - /// - /// - /// - /// Releases any resources allocated within the appender such as file handles, - /// network connections, etc. - /// - /// - /// It is a programming error to append to a closed appender. - /// - /// - override protected void OnClose() - { - // Remove all the attached appenders - lock(this) - { - if (m_appenderAttachedImpl != null) - { - m_appenderAttachedImpl.RemoveAllAppenders(); - } - } - } - - /// - /// Forward the logging event to the attached appenders - /// - /// The event to log. - /// - /// - /// Delivers the logging event to all the attached appenders. - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - // Pass the logging event on the the attached appenders - if (m_appenderAttachedImpl != null) - { - m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent); - } - } - - /// - /// Forward the logging events to the attached appenders - /// - /// The array of events to log. - /// - /// - /// Delivers the logging events to all the attached appenders. - /// - /// - override protected void Append(LoggingEvent[] loggingEvents) - { - // Pass the logging event on the the attached appenders - if (m_appenderAttachedImpl != null) - { - m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvents); - } - } - - #endregion Override implementation of AppenderSkeleton - - #region Implementation of IAppenderAttachable - - /// - /// Adds an to the list of appenders of this - /// instance. - /// - /// The to add to this appender. - /// - /// - /// If the specified is already in the list of - /// appenders, then it won't be added again. - /// - /// - virtual public void AddAppender(IAppender newAppender) - { - if (newAppender == null) - { - throw new ArgumentNullException("newAppender"); - } - lock(this) - { - if (m_appenderAttachedImpl == null) - { - m_appenderAttachedImpl = new log4net.Util.AppenderAttachedImpl(); - } - m_appenderAttachedImpl.AddAppender(newAppender); - } - } - - /// - /// Gets the appenders contained in this appender as an - /// . - /// - /// - /// If no appenders can be found, then an - /// is returned. - /// - /// - /// A collection of the appenders in this appender. - /// - virtual public AppenderCollection Appenders - { - get - { - lock(this) - { - if (m_appenderAttachedImpl == null) - { - return AppenderCollection.EmptyCollection; - } - else - { - return m_appenderAttachedImpl.Appenders; - } - } - } - } - - /// - /// Looks for the appender with the specified name. - /// - /// The name of the appender to lookup. - /// - /// The appender with the specified name, or null. - /// - /// - /// - /// Get the named appender attached to this appender. - /// - /// - virtual public IAppender GetAppender(string name) - { - lock(this) - { - if (m_appenderAttachedImpl == null || name == null) - { - return null; - } - - return m_appenderAttachedImpl.GetAppender(name); - } - } - - /// - /// Removes all previously added appenders from this appender. - /// - /// - /// - /// This is useful when re-reading configuration information. - /// - /// - virtual public void RemoveAllAppenders() - { - lock(this) - { - if (m_appenderAttachedImpl != null) - { - m_appenderAttachedImpl.RemoveAllAppenders(); - m_appenderAttachedImpl = null; - } - } - } - - /// - /// Removes the specified appender from the list of appenders. - /// - /// The appender to remove. - /// The appender removed from the list - /// - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - virtual public IAppender RemoveAppender(IAppender appender) - { - lock(this) - { - if (appender != null && m_appenderAttachedImpl != null) - { - return m_appenderAttachedImpl.RemoveAppender(appender); - } - } - return null; - } - - /// - /// Removes the appender with the specified name from the list of appenders. - /// - /// The name of the appender to remove. - /// The appender removed from the list - /// - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - virtual public IAppender RemoveAppender(string name) - { - lock(this) - { - if (name != null && m_appenderAttachedImpl != null) - { - return m_appenderAttachedImpl.RemoveAppender(name); - } - } - return null; - } - - #endregion Implementation of IAppenderAttachable - - #region Private Instance Fields - - /// - /// Implementation of the interface - /// - private AppenderAttachedImpl m_appenderAttachedImpl; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Appender/IAppender.cs b/src/log4net/Appender/IAppender.cs deleted file mode 100644 index a644f072..00000000 --- a/src/log4net/Appender/IAppender.cs +++ /dev/null @@ -1,78 +0,0 @@ -#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 log4net.Filter; -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Implement this interface for your own strategies for printing log statements. - /// - /// - /// - /// Implementors should consider extending the - /// class which provides a default implementation of this interface. - /// - /// - /// Appenders can also implement the interface. Therefore - /// they would require that the method - /// be called after the appenders properties have been configured. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IAppender - { - /// - /// Closes the appender and releases resources. - /// - /// - /// - /// Releases any resources allocated within the appender such as file handles, - /// network connections, etc. - /// - /// - /// It is a programming error to append to a closed appender. - /// - /// - void Close(); - - /// - /// Log the logging event in Appender specific way. - /// - /// The event to log - /// - /// - /// This method is called to log a message into this appender. - /// - /// - void DoAppend(LoggingEvent loggingEvent); - - /// - /// Gets or sets the name of this appender. - /// - /// The name of the appender. - /// - /// The name uniquely identifies the appender. - /// - string Name { get; set; } - } -} diff --git a/src/log4net/Appender/IBulkAppender.cs b/src/log4net/Appender/IBulkAppender.cs deleted file mode 100644 index 469eb85a..00000000 --- a/src/log4net/Appender/IBulkAppender.cs +++ /dev/null @@ -1,48 +0,0 @@ -#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 log4net.Core; - -namespace log4net.Appender -{ - /// - /// Interface for appenders that support bulk logging. - /// - /// - /// - /// This interface extends the interface to - /// support bulk logging of objects. Appenders - /// should only implement this interface if they can bulk log efficiently. - /// - /// - /// Nicko Cadell - public interface IBulkAppender : IAppender - { - /// - /// Log the array of logging events in Appender specific way. - /// - /// The events to log - /// - /// - /// This method is called to log an array of events into this appender. - /// - /// - void DoAppend(LoggingEvent[] loggingEvents); - } -} diff --git a/src/log4net/Appender/LocalSyslogAppender.cs b/src/log4net/Appender/LocalSyslogAppender.cs deleted file mode 100644 index c78c8492..00000000 --- a/src/log4net/Appender/LocalSyslogAppender.cs +++ /dev/null @@ -1,624 +0,0 @@ -#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 - -// .NET Compact Framework has no support for Marshal.StringToHGlobalAnsi -#if !NETCF - -using System; -using System.Runtime.InteropServices; - -using log4net.Core; -using log4net.Appender; -using log4net.Util; -using log4net.Layout; - -namespace log4net.Appender -{ - /// - /// Logs events to a local syslog service. - /// - /// - /// - /// This appender uses the POSIX libc library functions openlog, syslog, and closelog. - /// If these functions are not available on the local system then this appender will not work! - /// - /// - /// The functions openlog, syslog, and closelog are specified in SUSv2 and - /// POSIX 1003.1-2001 standards. These are used to log messages to the local syslog service. - /// - /// - /// This appender talks to a local syslog service. If you need to log to a remote syslog - /// daemon and you cannot configure your local syslog service to do this you may be - /// able to use the to log via UDP. - /// - /// - /// Syslog messages must have a facility and and a severity. The severity - /// is derived from the Level of the logging event. - /// The facility must be chosen from the set of defined syslog - /// values. The facilities list is predefined - /// and cannot be extended. - /// - /// - /// An identifier is specified with each log message. This can be specified - /// by setting the property. The identity (also know - /// as the tag) must not contain white space. The default value for the - /// identity is the application name (from ). - /// - /// - /// Rob Lyon - /// Nicko Cadell - public class LocalSyslogAppender : AppenderSkeleton - { - #region Enumerations - - /// - /// syslog severities - /// - /// - /// - /// The log4net Level maps to a syslog severity using the - /// method and the - /// class. The severity is set on . - /// - /// - public enum SyslogSeverity - { - /// - /// system is unusable - /// - Emergency = 0, - - /// - /// action must be taken immediately - /// - Alert = 1, - - /// - /// critical conditions - /// - Critical = 2, - - /// - /// error conditions - /// - Error = 3, - - /// - /// warning conditions - /// - Warning = 4, - - /// - /// normal but significant condition - /// - Notice = 5, - - /// - /// informational - /// - Informational = 6, - - /// - /// debug-level messages - /// - Debug = 7 - }; - - /// - /// syslog facilities - /// - /// - /// - /// The syslog facility defines which subsystem the logging comes from. - /// This is set on the property. - /// - /// - public enum SyslogFacility - { - /// - /// kernel messages - /// - Kernel = 0, - - /// - /// random user-level messages - /// - User = 1, - - /// - /// mail system - /// - Mail = 2, - - /// - /// system daemons - /// - Daemons = 3, - - /// - /// security/authorization messages - /// - Authorization = 4, - - /// - /// messages generated internally by syslogd - /// - Syslog = 5, - - /// - /// line printer subsystem - /// - Printer = 6, - - /// - /// network news subsystem - /// - News = 7, - - /// - /// UUCP subsystem - /// - Uucp = 8, - - /// - /// clock (cron/at) daemon - /// - Clock = 9, - - /// - /// security/authorization messages (private) - /// - Authorization2 = 10, - - /// - /// ftp daemon - /// - Ftp = 11, - - /// - /// NTP subsystem - /// - Ntp = 12, - - /// - /// log audit - /// - Audit = 13, - - /// - /// log alert - /// - Alert = 14, - - /// - /// clock daemon - /// - Clock2 = 15, - - /// - /// reserved for local use - /// - Local0 = 16, - - /// - /// reserved for local use - /// - Local1 = 17, - - /// - /// reserved for local use - /// - Local2 = 18, - - /// - /// reserved for local use - /// - Local3 = 19, - - /// - /// reserved for local use - /// - Local4 = 20, - - /// - /// reserved for local use - /// - Local5 = 21, - - /// - /// reserved for local use - /// - Local6 = 22, - - /// - /// reserved for local use - /// - Local7 = 23 - } - - #endregion // Enumerations - - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// This instance of the class is set up to write - /// to a local syslog service. - /// - public LocalSyslogAppender() - { - } - - #endregion // Public Instance Constructors - - #region Public Instance Properties - - /// - /// Message identity - /// - /// - /// - /// An identifier is specified with each log message. This can be specified - /// by setting the property. The identity (also know - /// as the tag) must not contain white space. The default value for the - /// identity is the application name (from ). - /// - /// - public string Identity - { - get { return m_identity; } - set { m_identity = value; } - } - - /// - /// Syslog facility - /// - /// - /// Set to one of the values. The list of - /// facilities is predefined and cannot be extended. The default value - /// is . - /// - public SyslogFacility Facility - { - get { return m_facility; } - set { m_facility = value; } - } - - #endregion // Public Instance Properties - - /// - /// Add a mapping of level to severity - /// - /// The mapping to add - /// - /// - /// Adds a to this appender. - /// - /// - public void AddMapping(LevelSeverity mapping) - { - m_levelMapping.Add(mapping); - } - - #region IOptionHandler Implementation - - /// - /// Initialize the appender based on the options set. - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - public override void ActivateOptions() - { - base.ActivateOptions(); - - m_levelMapping.ActivateOptions(); - - string identString = m_identity; - if (identString == null) - { - // Set to app name by default - identString = SystemInfo.ApplicationFriendlyName; - } - - // create the native heap ansi string. Note this is a copy of our string - // so we do not need to hold on to the string itself, holding on to the - // handle will keep the heap ansi string alive. - m_handleToIdentity = Marshal.StringToHGlobalAnsi(identString); - } - - #endregion // IOptionHandler Implementation - - #region AppenderSkeleton Implementation - - /// - /// This method is called by the method. - /// - /// The event to log. - /// - /// - /// Writes the event to a remote syslog daemon. - /// - /// - /// The format of the output will depend on the appender's layout. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] - protected override void Append(LoggingEvent loggingEvent) - { - int priority = GeneratePriority(m_facility, GetSeverity(loggingEvent.Level)); - string message = RenderLoggingEvent(loggingEvent); - - // Call the local libc syslog method - // The second argument is a printf style format string - lock (SYSLOG_LOCK) - { - if (m_handleToIdentity != LAST_IDENTITY) - { - if (LAST_IDENTITY != IntPtr.Zero) - { - closelog(); - } - openlog(LAST_IDENTITY = m_handleToIdentity, 1, m_facility); - } - syslog(priority, "%s", message); - } - } - - /// - /// Close the syslog when the appender is closed - /// - /// - /// - /// Close the syslog when the appender is closed - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - protected override void OnClose() - { - base.OnClose(); - - try - { - // close syslog - closelog(); - } - catch(DllNotFoundException) - { - // Ignore dll not found at this point - } - - if (m_handleToIdentity != IntPtr.Zero) - { - // free global ident - Marshal.FreeHGlobal(m_handleToIdentity); - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion // AppenderSkeleton Implementation - - #region Protected Members - - /// - /// Translates a log4net level to a syslog severity. - /// - /// A log4net level. - /// A syslog severity. - /// - /// - /// Translates a log4net level to a syslog severity. - /// - /// - virtual protected SyslogSeverity GetSeverity(Level level) - { - LevelSeverity levelSeverity = m_levelMapping.Lookup(level) as LevelSeverity; - if (levelSeverity != null) - { - return levelSeverity.Severity; - } - - // - // Fallback to sensible default values - // - - if (level >= Level.Alert) - { - return SyslogSeverity.Alert; - } - else if (level >= Level.Critical) - { - return SyslogSeverity.Critical; - } - else if (level >= Level.Error) - { - return SyslogSeverity.Error; - } - else if (level >= Level.Warn) - { - return SyslogSeverity.Warning; - } - else if (level >= Level.Notice) - { - return SyslogSeverity.Notice; - } - else if (level >= Level.Info) - { - return SyslogSeverity.Informational; - } - // Default setting - return SyslogSeverity.Debug; - } - - #endregion // Protected Members - - #region Public Static Members - - /// - /// Generate a syslog priority. - /// - /// The syslog facility. - /// The syslog severity. - /// A syslog priority. - private static int GeneratePriority(SyslogFacility facility, SyslogSeverity severity) - { - return ((int)facility * 8) + (int)severity; - } - - #endregion // Public Static Members - - #region Private Instances Fields - - /// - /// The facility. The default facility is . - /// - private SyslogFacility m_facility = SyslogFacility.User; - - /// - /// The message identity - /// - private string m_identity; - - /// - /// Marshaled handle to the identity string. We have to hold on to the - /// string as the openlog and syslog APIs just hold the - /// pointer to the ident and dereference it for each log message. - /// - private IntPtr m_handleToIdentity = IntPtr.Zero; - - /// - /// Mapping from level object to syslog severity - /// - private LevelMapping m_levelMapping = new LevelMapping(); - - /// - /// lock object that ensures openlog and syslog - /// actually use the identity configured. - /// - private static readonly object SYSLOG_LOCK = new object(); - - /// - /// Holds the last identity used for openlog in - /// order to avoid redundant calss to openlog. - /// - private static IntPtr LAST_IDENTITY = IntPtr.Zero; - - #endregion // Private Instances Fields - - #region External Members - - /// - /// Open connection to system logger. - /// - [DllImport("libc")] - private static extern void openlog(IntPtr ident, int option, SyslogFacility facility); - - /// - /// Generate a log message. - /// - /// - /// - /// The libc syslog method takes a format string and a variable argument list similar - /// to the classic printf function. As this type of vararg list is not supported - /// by C# we need to specify the arguments explicitly. Here we have specified the - /// format string with a single message argument. The caller must set the format - /// string to "%s". - /// - /// - [DllImport("libc", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] - private static extern void syslog(int priority, string format, string message); - - /// - /// Close descriptor used to write to system logger. - /// - [DllImport("libc")] - private static extern void closelog(); - - #endregion // External Members - - #region LevelSeverity LevelMapping Entry - - /// - /// A class to act as a mapping between the level that a logging call is made at and - /// the syslog severity that is should be logged at. - /// - /// - /// - /// A class to act as a mapping between the level that a logging call is made at and - /// the syslog severity that is should be logged at. - /// - /// - public class LevelSeverity : LevelMappingEntry - { - private SyslogSeverity m_severity; - - /// - /// The mapped syslog severity for the specified level - /// - /// - /// - /// Required property. - /// The mapped syslog severity for the specified level - /// - /// - public SyslogSeverity Severity - { - get { return m_severity; } - set { m_severity = value; } - } - } - - #endregion // LevelSeverity LevelMapping Entry - } -} - -#endif diff --git a/src/log4net/Appender/ManagedColoredConsoleAppender.cs b/src/log4net/Appender/ManagedColoredConsoleAppender.cs deleted file mode 100644 index 60b64b61..00000000 --- a/src/log4net/Appender/ManagedColoredConsoleAppender.cs +++ /dev/null @@ -1,338 +0,0 @@ -#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 - -// Compatibility: -// http://msdn.microsoft.com/en-us/library/system.console.foregroundcolor.aspx -// Disable for unsupported targets -#if !NETCF - -// The original ColoredConsoleAppender was written before the .NET framework -// (and Mono) had built-in support for console colors so it was written using -// Win32 API calls. The AnsiColorTerminalAppender, while it works, isn't -// understood by the Windows command prompt. -// This is a replacement for both that uses the new (.NET 2) Console colors -// and works on both platforms. - -// On Mono/Linux (at least), setting the background color to 'Black' is -// not the same as the default background color, as it is after -// Console.Reset(). The difference becomes apparent while running in a -// terminal application that supports background transparency; the -// default color is treated as transparent while 'Black' isn't. -// For this reason, we always reset the colors and only set those -// explicitly specified in the configuration (Console.BackgroundColor -// isn't set if ommited). - -using System; -using log4net.Layout; -using log4net.Util; -using System.Globalization; - -namespace log4net.Appender -{ - /// - /// Appends colorful logging events to the console, using the .NET 2 - /// built-in capabilities. - /// - /// - /// - /// ManagedColoredConsoleAppender appends log events to the standard output stream - /// or the error output stream using a layout specified by the - /// user. It also allows the color of a specific type of message to be set. - /// - /// - /// By default, all output is written to the console's standard output stream. - /// The property can be set to direct the output to the - /// error stream. - /// - /// - /// When configuring the colored console appender, mappings should be - /// specified to map logging levels to colors. For example: - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The Level is the standard log4net logging level while - /// ForeColor and BackColor are the values of - /// enumeration. - /// - /// - /// Based on the ColoredConsoleAppender - /// - /// - /// Rick Hobbs - /// Nicko Cadell - /// Pavlos Touboulidis - public class ManagedColoredConsoleAppender: AppenderSkeleton - { - /// - /// Initializes a new instance of the class. - /// - /// - /// The instance of the class is set up to write - /// to the standard output stream. - /// - public ManagedColoredConsoleAppender() - { - } - - #region Public Instance Properties - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - /// - /// Target is the value of the console output stream. - /// This is either "Console.Out" or "Console.Error". - /// - /// - virtual public string Target - { - get { return m_writeToErrorStream ? ConsoleError : ConsoleOut; } - set - { - string v = value.Trim(); - - if (string.Compare(ConsoleError, v, true, CultureInfo.InvariantCulture) == 0) - { - m_writeToErrorStream = true; - } - else - { - m_writeToErrorStream = false; - } - } - } - - /// - /// Add a mapping of level to color - done by the config file - /// - /// The mapping to add - /// - /// - /// Add a mapping to this appender. - /// Each mapping defines the foreground and background colors - /// for a level. - /// - /// - public void AddMapping(LevelColors mapping) - { - m_levelMapping.Add(mapping); - } - #endregion // Public Instance Properties - - #region Override implementation of AppenderSkeleton - /// - /// This method is called by the method. - /// - /// The event to log. - /// - /// - /// Writes the event to the console. - /// - /// - /// The format of the output will depend on the appender's layout. - /// - /// - override protected void Append(log4net.Core.LoggingEvent loggingEvent) - { - System.IO.TextWriter writer; - - if (m_writeToErrorStream) - writer = Console.Error; - else - writer = Console.Out; - - // Reset color - Console.ResetColor(); - - // see if there is a specified lookup - LevelColors levelColors = m_levelMapping.Lookup(loggingEvent.Level) as LevelColors; - if (levelColors != null) - { - // if the backColor has been explicitly set - if (levelColors.HasBackColor) - Console.BackgroundColor = levelColors.BackColor; - // if the foreColor has been explicitly set - if (levelColors.HasForeColor) - Console.ForegroundColor = levelColors.ForeColor; - } - - // Render the event to a string - string strLoggingMessage = RenderLoggingEvent(loggingEvent); - // and write it - writer.Write(strLoggingMessage); - - // Reset color again - Console.ResetColor(); - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - /// - /// Initialize the options for this appender - /// - /// - /// - /// Initialize the level to color mappings set on this appender. - /// - /// - public override void ActivateOptions() - { - base.ActivateOptions(); - m_levelMapping.ActivateOptions(); - } - #endregion // Override implementation of AppenderSkeleton - - #region Public Static Fields - /// - /// The to use when writing to the Console - /// standard output stream. - /// - /// - /// - /// The to use when writing to the Console - /// standard output stream. - /// - /// - public const string ConsoleOut = "Console.Out"; - - /// - /// The to use when writing to the Console - /// standard error output stream. - /// - /// - /// - /// The to use when writing to the Console - /// standard error output stream. - /// - /// - public const string ConsoleError = "Console.Error"; - #endregion // Public Static Fields - - #region Private Instances Fields - /// - /// Flag to write output to the error stream rather than the standard output stream - /// - private bool m_writeToErrorStream = false; - - /// - /// Mapping from level object to color value - /// - private LevelMapping m_levelMapping = new LevelMapping(); - #endregion // Private Instances Fields - - #region LevelColors LevelMapping Entry - /// - /// A class to act as a mapping between the level that a logging call is made at and - /// the color it should be displayed as. - /// - /// - /// - /// Defines the mapping between a level and the color it should be displayed in. - /// - /// - public class LevelColors : LevelMappingEntry - { - /// - /// The mapped foreground color for the specified level - /// - /// - /// - /// Required property. - /// The mapped foreground color for the specified level. - /// - /// - public ConsoleColor ForeColor - { - get { return (this.foreColor); } - // Keep a flag that the color has been set - // and is no longer the default. - set { this.foreColor = value; this.hasForeColor = true; } - } - private ConsoleColor foreColor; - private bool hasForeColor; - internal bool HasForeColor { - get { - return hasForeColor; - } - } - - /// - /// The mapped background color for the specified level - /// - /// - /// - /// Required property. - /// The mapped background color for the specified level. - /// - /// - public ConsoleColor BackColor - { - get { return (this.backColor); } - // Keep a flag that the color has been set - // and is no longer the default. - set { this.backColor = value; this.hasBackColor = true; } - } - private ConsoleColor backColor; - private bool hasBackColor; - internal bool HasBackColor { - get { - return hasBackColor; - } - } - } - #endregion // LevelColors LevelMapping Entry - } -} - -#endif // !NETCF diff --git a/src/log4net/Appender/MemoryAppender.cs b/src/log4net/Appender/MemoryAppender.cs deleted file mode 100644 index 47598085..00000000 --- a/src/log4net/Appender/MemoryAppender.cs +++ /dev/null @@ -1,191 +0,0 @@ -#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 System.Collections.Generic; - -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Stores logging events in an array. - /// - /// - /// - /// The memory appender stores all the logging events - /// that are appended in an in-memory array. - /// - /// - /// Use the method to get - /// and clear the current list of events that have been appended. - /// - /// - /// Use the method to get the current - /// list of events that have been appended. Note there is a - /// race-condition when calling and - /// in pairs, you better use in that case. - /// - /// - /// Use the method to clear the - /// current list of events. Note there is a - /// race-condition when calling and - /// in pairs, you better use in that case. - /// - /// - /// Julian Biddle - /// Nicko Cadell - /// Gert Driesen - public class MemoryAppender : AppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public MemoryAppender() : base() - { - m_eventsList = new List(); - } - - #endregion Protected Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the events that have been logged. - /// - /// The events that have been logged - /// - /// - /// Gets the events that have been logged. - /// - /// - virtual public LoggingEvent[] GetEvents() - { - lock (m_eventsList) - { - return m_eventsList.ToArray(); - } - } - - /// - /// Gets or sets the fields that will be fixed in the event - /// - /// - /// - /// The logging event needs to have certain thread specific values - /// captured before it can be buffered. See - /// for details. - /// - /// - virtual public FixFlags Fix - { - get { return m_fixFlags; } - set { m_fixFlags = value; } - } - - #endregion Public Instance Properties - - #region Override implementation of AppenderSkeleton - - /// - /// This method is called by the method. - /// - /// the event to log - /// - /// Stores the in the events list. - /// - override protected 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.Fix = this.Fix; - - lock (m_eventsList) - { - m_eventsList.Add(loggingEvent); - } - } - - #endregion Override implementation of AppenderSkeleton - - #region Public Instance Methods - - /// - /// Clear the list of events - /// - /// - /// Clear the list of events - /// - virtual public void Clear() - { - lock (m_eventsList) - { - m_eventsList.Clear(); - } - } - - /// - /// Gets the events that have been logged and clears the list of events. - /// - /// The events that have been logged - /// - /// - /// Gets the events that have been logged and clears the list of events. - /// - /// - virtual public LoggingEvent[] PopAllEvents() - { - lock (m_eventsList) - { - LoggingEvent[] tmp = m_eventsList.ToArray(); - m_eventsList.Clear(); - return tmp; - } - } - - #endregion Public Instance Methods - - /// - /// The list of events that have been appended. - /// - private readonly List m_eventsList; - - #region Protected Instance Fields - - /// - /// Value indicating which fields in the event should be fixed - /// - /// - /// By default all fields are fixed - /// - protected FixFlags m_fixFlags = FixFlags.All; - - #endregion Protected Instance Fields - } -} diff --git a/src/log4net/Appender/NetSendAppender.cs b/src/log4net/Appender/NetSendAppender.cs deleted file mode 100644 index d7069cd2..00000000 --- a/src/log4net/Appender/NetSendAppender.cs +++ /dev/null @@ -1,414 +0,0 @@ -#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 - -// .NET Compact Framework has no support for Win32 NetMessageBufferSend API -#if !NETCF - -using System; -using System.Globalization; -using System.Runtime.InteropServices; - -using log4net.Util; -using log4net.Layout; -using log4net.Core; - - -namespace log4net.Appender -{ - /// - /// Logs entries by sending network messages using the - /// native function. - /// - /// - /// - /// You can send messages only to names that are active - /// on the network. If you send the message to a user name, - /// that user must be logged on and running the Messenger - /// service to receive the message. - /// - /// - /// The receiver will get a top most window displaying the - /// messages one at a time, therefore this appender should - /// not be used to deliver a high volume of messages. - /// - /// - /// The following table lists some possible uses for this appender : - /// - /// - /// - /// - /// Action - /// Property Value(s) - /// - /// - /// Send a message to a user account on the local machine - /// - /// - /// = <name of the local machine> - /// - /// - /// = <user name> - /// - /// - /// - /// - /// Send a message to a user account on a remote machine - /// - /// - /// = <name of the remote machine> - /// - /// - /// = <user name> - /// - /// - /// - /// - /// Send a message to a domain user account - /// - /// - /// = <name of a domain controller | uninitialized> - /// - /// - /// = <user name> - /// - /// - /// - /// - /// Send a message to all the names in a workgroup or domain - /// - /// - /// = <workgroup name | domain name>* - /// - /// - /// - /// - /// Send a message from the local machine to a remote machine - /// - /// - /// = <name of the local machine | uninitialized> - /// - /// - /// = <name of the remote machine> - /// - /// - /// - /// - /// - /// - /// Note : security restrictions apply for sending - /// network messages, see - /// for more information. - /// - /// - /// - /// - /// An example configuration section to log information - /// using this appender from the local machine, named - /// LOCAL_PC, to machine OPERATOR_PC : - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class NetSendAppender : AppenderSkeleton - { - #region Member Variables - - /// - /// The DNS or NetBIOS name of the server on which the function is to execute. - /// - private string m_server; - - /// - /// The sender of the network message. - /// - private string m_sender; - - /// - /// The message alias to which the message should be sent. - /// - private string m_recipient; - - /// - /// The security context to use for privileged calls - /// - private SecurityContext m_securityContext; - - #endregion - - #region Constructors - - /// - /// Initializes the appender. - /// - /// - /// The default constructor initializes all fields to their default values. - /// - public NetSendAppender() - { - } - - #endregion - - #region Properties - - /// - /// Gets or sets the sender of the message. - /// - /// - /// The sender of the message. - /// - /// - /// If this property is not specified, the message is sent from the local computer. - /// - public string Sender - { - get { return m_sender; } - set { m_sender = value; } - } - - /// - /// Gets or sets the message alias to which the message should be sent. - /// - /// - /// The recipient of the message. - /// - /// - /// This property should always be specified in order to send a message. - /// - public string Recipient - { - get { return m_recipient; } - set { m_recipient = value; } - } - - /// - /// Gets or sets the DNS or NetBIOS name of the remote server on which the function is to execute. - /// - /// - /// DNS or NetBIOS name of the remote server on which the function is to execute. - /// - /// - /// - /// For Windows NT 4.0 and earlier, the string should begin with \\. - /// - /// - /// If this property is not specified, the local computer is used. - /// - /// - public string Server - { - get { return m_server; } - set { m_server = value; } - } - - /// - /// Gets or sets the used to call the NetSend method. - /// - /// - /// The used to call the NetSend method. - /// - /// - /// - /// Unless a specified here for this appender - /// the is queried for the - /// security context to use. The default behavior is to use the security context - /// of the current thread. - /// - /// - public SecurityContext SecurityContext - { - get { return m_securityContext; } - set { m_securityContext = value; } - } - - #endregion - - #region Implementation of IOptionHandler - - /// - /// Initialize the appender based on the options set. - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// The appender will be ignored if no was specified. - /// - /// - /// The required property was not specified. - public override void ActivateOptions() - { - base.ActivateOptions(); - - if (this.Recipient == null) - { - throw new ArgumentNullException("Recipient", "The required property 'Recipient' was not specified."); - } - - if (m_securityContext == null) - { - m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); - } - } - - #endregion - - #region Override implementation of AppenderSkeleton - - /// - /// This method is called by the method. - /// - /// The event to log. - /// - /// - /// Sends the event using a network message. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] - protected override void Append(LoggingEvent loggingEvent) - { - NativeError nativeError = null; - - // Render the event in the callers security context - string renderedLoggingEvent = RenderLoggingEvent(loggingEvent); - - using(m_securityContext.Impersonate(this)) - { - // Send the message - int returnValue = NetMessageBufferSend(this.Server, this.Recipient, this.Sender, renderedLoggingEvent, renderedLoggingEvent.Length * Marshal.SystemDefaultCharSize); - - // Log the error if the message could not be sent - if (returnValue != 0) - { - // Lookup the native error - nativeError = NativeError.GetError(returnValue); - } - } - - if (nativeError != null) - { - // Handle the error over to the ErrorHandler - ErrorHandler.Error(nativeError.ToString() + " (Params: Server=" + this.Server + ", Recipient=" + this.Recipient + ", Sender=" + this.Sender + ")"); - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion - - #region Stubs For Native Function Calls - - /// - /// Sends a buffer of information to a registered message alias. - /// - /// The DNS or NetBIOS name of the server on which the function is to execute. - /// The message alias to which the message buffer should be sent - /// The originator of the message. - /// The message text. - /// The length, in bytes, of the message text. - /// - /// - /// The following restrictions apply for sending network messages: - /// - /// - /// - /// - /// Platform - /// Requirements - /// - /// - /// Windows NT - /// - /// - /// No special group membership is required to send a network message. - /// - /// - /// Admin, Accounts, Print, or Server Operator group membership is required to - /// successfully send a network message on a remote server. - /// - /// - /// - /// - /// Windows 2000 or later - /// - /// - /// If you send a message on a domain controller that is running Active Directory, - /// access is allowed or denied based on the access control list (ACL) for the securable - /// object. The default ACL permits only Domain Admins and Account Operators to send a network message. - /// - /// - /// On a member server or workstation, only Administrators and Server Operators can send a network message. - /// - /// - /// - /// - /// - /// - /// For more information see Security Requirements for the Network Management Functions. - /// - /// - /// - /// - /// If the function succeeds, the return value is zero. - /// - /// - [DllImport("netapi32.dll", SetLastError=true)] - protected static extern int NetMessageBufferSend( - [MarshalAs(UnmanagedType.LPWStr)] string serverName, - [MarshalAs(UnmanagedType.LPWStr)] string msgName, - [MarshalAs(UnmanagedType.LPWStr)] string fromName, - [MarshalAs(UnmanagedType.LPWStr)] string buffer, - int bufferSize); - - #endregion - } -} - -#endif // !NETCF \ No newline at end of file diff --git a/src/log4net/Appender/OutputDebugStringAppender.cs b/src/log4net/Appender/OutputDebugStringAppender.cs deleted file mode 100644 index edd2c2eb..00000000 --- a/src/log4net/Appender/OutputDebugStringAppender.cs +++ /dev/null @@ -1,117 +0,0 @@ -#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.Runtime.InteropServices; - -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Appends log events to the OutputDebugString system. - /// - /// - /// - /// OutputDebugStringAppender appends log events to the - /// OutputDebugString system. - /// - /// - /// The string is passed to the native OutputDebugString - /// function. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class OutputDebugStringAppender : AppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public OutputDebugStringAppender() - { - } - - #endregion // Public Instance Constructors - - #region Override implementation of AppenderSkeleton - - /// - /// Write the logging event to the output debug string API - /// - /// the event to log - /// - /// - /// Write the logging event to the output debug string API - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#elif !NETCF - [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] -#endif - override protected void Append(LoggingEvent loggingEvent) - { - OutputDebugString(RenderLoggingEvent(loggingEvent)); - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion // Override implementation of AppenderSkeleton - - #region Protected Static Methods - - /// - /// Stub for OutputDebugString native method - /// - /// the string to output - /// - /// - /// Stub for OutputDebugString native method - /// - /// -#if NETCF - [DllImport("CoreDll.dll")] -#else - [DllImport("Kernel32.dll")] -#endif - protected static extern void OutputDebugString(string message); - - #endregion // Protected Static Methods - } -} diff --git a/src/log4net/Appender/RemoteSyslogAppender.cs b/src/log4net/Appender/RemoteSyslogAppender.cs deleted file mode 100644 index 2f23875c..00000000 --- a/src/log4net/Appender/RemoteSyslogAppender.cs +++ /dev/null @@ -1,592 +0,0 @@ -#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; -using log4net.Util; -using log4net.Layout; -using System.Text; - -namespace log4net.Appender -{ - /// - /// Logs events to a remote syslog daemon. - /// - /// - /// - /// The BSD syslog protocol is used to remotely log to - /// a syslog daemon. The syslogd listens for for messages - /// on UDP port 514. - /// - /// - /// The syslog UDP protocol is not authenticated. Most syslog daemons - /// do not accept remote log messages because of the security implications. - /// You may be able to use the LocalSyslogAppender to talk to a local - /// syslog service. - /// - /// - /// There is an RFC 3164 that claims to document the BSD Syslog Protocol. - /// This RFC can be seen here: http://www.faqs.org/rfcs/rfc3164.html. - /// This appender generates what the RFC calls an "Original Device Message", - /// i.e. does not include the TIMESTAMP or HOSTNAME fields. By observation - /// this format of message will be accepted by all current syslog daemon - /// implementations. The daemon will attach the current time and the source - /// hostname or IP address to any messages received. - /// - /// - /// Syslog messages must have a facility and and a severity. The severity - /// is derived from the Level of the logging event. - /// The facility must be chosen from the set of defined syslog - /// values. The facilities list is predefined - /// and cannot be extended. - /// - /// - /// An identifier is specified with each log message. This can be specified - /// by setting the property. The identity (also know - /// as the tag) must not contain white space. The default value for the - /// identity is the application name (from ). - /// - /// - /// Rob Lyon - /// Nicko Cadell - public class RemoteSyslogAppender : UdpAppender - { - /// - /// Syslog port 514 - /// - private const int DefaultSyslogPort = 514; - - #region Enumerations - - /// - /// syslog severities - /// - /// - /// - /// The syslog severities. - /// - /// - public enum SyslogSeverity - { - /// - /// system is unusable - /// - Emergency = 0, - - /// - /// action must be taken immediately - /// - Alert = 1, - - /// - /// critical conditions - /// - Critical = 2, - - /// - /// error conditions - /// - Error = 3, - - /// - /// warning conditions - /// - Warning = 4, - - /// - /// normal but significant condition - /// - Notice = 5, - - /// - /// informational - /// - Informational = 6, - - /// - /// debug-level messages - /// - Debug = 7 - }; - - /// - /// syslog facilities - /// - /// - /// - /// The syslog facilities - /// - /// - public enum SyslogFacility - { - /// - /// kernel messages - /// - Kernel = 0, - - /// - /// random user-level messages - /// - User = 1, - - /// - /// mail system - /// - Mail = 2, - - /// - /// system daemons - /// - Daemons = 3, - - /// - /// security/authorization messages - /// - Authorization = 4, - - /// - /// messages generated internally by syslogd - /// - Syslog = 5, - - /// - /// line printer subsystem - /// - Printer = 6, - - /// - /// network news subsystem - /// - News = 7, - - /// - /// UUCP subsystem - /// - Uucp = 8, - - /// - /// clock (cron/at) daemon - /// - Clock = 9, - - /// - /// security/authorization messages (private) - /// - Authorization2 = 10, - - /// - /// ftp daemon - /// - Ftp = 11, - - /// - /// NTP subsystem - /// - Ntp = 12, - - /// - /// log audit - /// - Audit = 13, - - /// - /// log alert - /// - Alert = 14, - - /// - /// clock daemon - /// - Clock2 = 15, - - /// - /// reserved for local use - /// - Local0 = 16, - - /// - /// reserved for local use - /// - Local1 = 17, - - /// - /// reserved for local use - /// - Local2 = 18, - - /// - /// reserved for local use - /// - Local3 = 19, - - /// - /// reserved for local use - /// - Local4 = 20, - - /// - /// reserved for local use - /// - Local5 = 21, - - /// - /// reserved for local use - /// - Local6 = 22, - - /// - /// reserved for local use - /// - Local7 = 23 - } - - #endregion Enumerations - - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// This instance of the class is set up to write - /// to a remote syslog daemon. - /// - public RemoteSyslogAppender() - { - // syslog udp defaults - this.RemotePort = DefaultSyslogPort; - this.RemoteAddress = System.Net.IPAddress.Parse("127.0.0.1"); - this.Encoding = System.Text.Encoding.ASCII; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Message identity - /// - /// - /// - /// An identifier is specified with each log message. This can be specified - /// by setting the property. The identity (also know - /// as the tag) must not contain white space. The default value for the - /// identity is the application name (from ). - /// - /// - public PatternLayout Identity - { - get { return m_identity; } - set { m_identity = value; } - } - - /// - /// Syslog facility - /// - /// - /// Set to one of the values. The list of - /// facilities is predefined and cannot be extended. The default value - /// is . - /// - public SyslogFacility Facility - { - get { return m_facility; } - set { m_facility = value; } - } - - #endregion Public Instance Properties - - /// - /// Add a mapping of level to severity - /// - /// The mapping to add - /// - /// - /// Add a mapping to this appender. - /// - /// - public void AddMapping(LevelSeverity mapping) - { - m_levelMapping.Add(mapping); - } - - #region AppenderSkeleton Implementation - - /// - /// This method is called by the method. - /// - /// The event to log. - /// - /// - /// Writes the event to a remote syslog daemon. - /// - /// - /// The format of the output will depend on the appender's layout. - /// - /// - protected override void Append(LoggingEvent loggingEvent) - { - try - { - // Priority - int priority = GeneratePriority(m_facility, GetSeverity(loggingEvent.Level)); - - // Identity - string identity; - - if (m_identity != null) - { - identity = m_identity.Format(loggingEvent); - } - else - { - identity = loggingEvent.Domain; - } - - // Message. The message goes after the tag/identity - string message = RenderLoggingEvent(loggingEvent); - - Byte[] buffer; - int i = 0; - char c; - - StringBuilder builder = new StringBuilder(); - - while (i < message.Length) - { - // Clear StringBuilder - builder.Length = 0; - - // Write priority - builder.Append('<'); - builder.Append(priority); - builder.Append('>'); - - // Write identity - builder.Append(identity); - builder.Append(": "); - - for (; i < message.Length; i++) - { - c = message[i]; - - // Accept only visible ASCII characters and space. See RFC 3164 section 4.1.3 - if (((int)c >= 32) && ((int)c <= 126)) - { - builder.Append(c); - } - // If character is newline, break and send the current line - else if ((c == '\r') || (c == '\n')) - { - // Check the next character to handle \r\n or \n\r - if ((message.Length > i + 1) && ((message[i + 1] == '\r') || (message[i + 1] == '\n'))) - { - i++; - } - i++; - break; - } - } - - // Grab as a byte array - buffer = this.Encoding.GetBytes(builder.ToString()); - - this.Client.Send(buffer, buffer.Length, this.RemoteEndPoint); - } - } - catch (Exception e) - { - ErrorHandler.Error( - "Unable to send logging event to remote syslog " + - this.RemoteAddress.ToString() + - " on port " + - this.RemotePort + ".", - e, - ErrorCode.WriteFailure); - } - } - - /// - /// Initialize the options for this appender - /// - /// - /// - /// Initialize the level to syslog severity mappings set on this appender. - /// - /// - public override void ActivateOptions() - { - base.ActivateOptions(); - m_levelMapping.ActivateOptions(); - } - - #endregion AppenderSkeleton Implementation - - #region Protected Members - - /// - /// Translates a log4net level to a syslog severity. - /// - /// A log4net level. - /// A syslog severity. - /// - /// - /// Translates a log4net level to a syslog severity. - /// - /// - virtual protected SyslogSeverity GetSeverity(Level level) - { - LevelSeverity levelSeverity = m_levelMapping.Lookup(level) as LevelSeverity; - if (levelSeverity != null) - { - return levelSeverity.Severity; - } - - // - // Fallback to sensible default values - // - - if (level >= Level.Alert) - { - return SyslogSeverity.Alert; - } - else if (level >= Level.Critical) - { - return SyslogSeverity.Critical; - } - else if (level >= Level.Error) - { - return SyslogSeverity.Error; - } - else if (level >= Level.Warn) - { - return SyslogSeverity.Warning; - } - else if (level >= Level.Notice) - { - return SyslogSeverity.Notice; - } - else if (level >= Level.Info) - { - return SyslogSeverity.Informational; - } - // Default setting - return SyslogSeverity.Debug; - } - - #endregion Protected Members - - #region Public Static Members - - /// - /// Generate a syslog priority. - /// - /// The syslog facility. - /// The syslog severity. - /// A syslog priority. - /// - /// - /// Generate a syslog priority. - /// - /// - public static int GeneratePriority(SyslogFacility facility, SyslogSeverity severity) - { - if (facility < SyslogFacility.Kernel || facility > SyslogFacility.Local7) - { - throw new ArgumentException("SyslogFacility out of range", "facility"); - } - - if (severity < SyslogSeverity.Emergency || severity > SyslogSeverity.Debug) - { - throw new ArgumentException("SyslogSeverity out of range", "severity"); - } - - unchecked - { - return ((int)facility * 8) + (int)severity; - } - } - - #endregion Public Static Members - - #region Private Instances Fields - - /// - /// The facility. The default facility is . - /// - private SyslogFacility m_facility = SyslogFacility.User; - - /// - /// The message identity - /// - private PatternLayout m_identity; - - /// - /// Mapping from level object to syslog severity - /// - private LevelMapping m_levelMapping = new LevelMapping(); - - /// - /// Initial buffer size - /// - private const int c_renderBufferSize = 256; - - /// - /// Maximum buffer size before it is recycled - /// - private const int c_renderBufferMaxCapacity = 1024; - - #endregion Private Instances Fields - - #region LevelSeverity LevelMapping Entry - /// - /// A class to act as a mapping between the level that a logging call is made at and - /// the syslog severity that is should be logged at. - /// - /// - /// - /// A class to act as a mapping between the level that a logging call is made at and - /// the syslog severity that is should be logged at. - /// - /// - public class LevelSeverity : LevelMappingEntry - { - private SyslogSeverity m_severity; - - /// - /// The mapped syslog severity for the specified level - /// - /// - /// - /// Required property. - /// The mapped syslog severity for the specified level - /// - /// - public SyslogSeverity Severity - { - get { return m_severity; } - set { m_severity = value; } - } - } - - #endregion // LevelSeverity LevelMapping Entry - } -} diff --git a/src/log4net/Appender/RemotingAppender.cs b/src/log4net/Appender/RemotingAppender.cs deleted file mode 100644 index 97f45c3e..00000000 --- a/src/log4net/Appender/RemotingAppender.cs +++ /dev/null @@ -1,328 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for System.Runtime.Remoting -#if !NETCF - -using System; -using System.Collections; -using System.Threading; - -using System.Runtime.Remoting.Messaging; - -using log4net.Layout; -using log4net.Core; -using log4net.Util; - -namespace log4net.Appender -{ - /// - /// Delivers logging events to a remote logging sink. - /// - /// - /// - /// This Appender is designed to deliver events to a remote sink. - /// That is any object that implements the - /// interface. It delivers the events using .NET remoting. The - /// object to deliver events to is specified by setting the - /// appenders property. - /// - /// The RemotingAppender buffers events before sending them. This allows it to - /// make more efficient use of the remoting infrastructure. - /// - /// Once the buffer is full the events are still not sent immediately. - /// They are scheduled to be sent using a pool thread. The effect is that - /// the send occurs asynchronously. This is very important for a - /// number of non obvious reasons. The remoting infrastructure will - /// flow thread local variables (stored in the ), - /// if they are marked as , across the - /// remoting boundary. If the server is not contactable then - /// the remoting infrastructure will clear the - /// objects from the . To prevent a logging failure from - /// having side effects on the calling application the remoting call must be made - /// from a separate thread to the one used by the application. A - /// thread is used for this. If no thread is available then - /// the events will block in the thread pool manager until a thread is available. - /// - /// Because the events are sent asynchronously using pool threads it is possible to close - /// this appender before all the queued events have been sent. - /// When closing the appender attempts to wait until all the queued events have been sent, but - /// this will timeout after 30 seconds regardless. - /// - /// If this appender is being closed because the - /// event has fired it may not be possible to send all the queued events. During process - /// exit the runtime limits the time that a - /// event handler is allowed to run for. If the runtime terminates the threads before - /// the queued events have been sent then they will be lost. To ensure that all events - /// are sent the appender must be closed before the application exits. See - /// for details on how to shutdown - /// log4net programmatically. - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Daniel Cazzulino - public class RemotingAppender : BufferingAppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public RemotingAppender() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the URL of the well-known object that will accept - /// the logging events. - /// - /// - /// The well-known URL of the remote sink. - /// - /// - /// - /// The URL of the remoting sink that will accept logging events. - /// The sink must implement the - /// interface. - /// - /// - public string Sink - { - get { return m_sinkUrl; } - set { m_sinkUrl = value; } - } - - #endregion Public Instance Properties - - #region Implementation of IOptionHandler - - /// - /// Initialize the appender based on the options set - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - override public void ActivateOptions() - { - base.ActivateOptions(); - - IDictionary channelProperties = new Hashtable(); - channelProperties["typeFilterLevel"] = "Full"; - - m_sinkObj = (IRemoteLoggingSink)Activator.GetObject(typeof(IRemoteLoggingSink), m_sinkUrl, channelProperties); - } - - #endregion - - #region Override implementation of BufferingAppenderSkeleton - - /// - /// Send the contents of the buffer to the remote sink. - /// - /// - /// The events are not sent immediately. They are scheduled to be sent - /// using a pool thread. The effect is that the send occurs asynchronously. - /// This is very important for a number of non obvious reasons. The remoting - /// infrastructure will flow thread local variables (stored in the ), - /// if they are marked as , across the - /// remoting boundary. If the server is not contactable then - /// the remoting infrastructure will clear the - /// objects from the . To prevent a logging failure from - /// having side effects on the calling application the remoting call must be made - /// from a separate thread to the one used by the application. A - /// thread is used for this. If no thread is available then - /// the events will block in the thread pool manager until a thread is available. - /// - /// The events to send. - override protected void SendBuffer(LoggingEvent[] events) - { - // Setup for an async send - BeginAsyncSend(); - - // Send the events - if (!ThreadPool.QueueUserWorkItem(new WaitCallback(SendBufferCallback), events)) - { - // Cancel the async send - EndAsyncSend(); - - ErrorHandler.Error("RemotingAppender ["+Name+"] failed to ThreadPool.QueueUserWorkItem logging events in SendBuffer."); - } - } - - /// - /// Override base class close. - /// - /// - /// - /// This method waits while there are queued work items. The events are - /// sent asynchronously using work items. These items - /// will be sent once a thread pool thread is available to send them, therefore - /// it is possible to close the appender before all the queued events have been - /// sent. - /// - /// This method attempts to wait until all the queued events have been sent, but this - /// method will timeout after 30 seconds regardless. - /// - /// If the appender is being closed because the - /// event has fired it may not be possible to send all the queued events. During process - /// exit the runtime limits the time that a - /// event handler is allowed to run for. - /// - override protected void OnClose() - { - base.OnClose(); - - // Wait for the work queue to become empty before closing, timeout 30 seconds - if (!m_workQueueEmptyEvent.WaitOne(30 * 1000, false)) - { - ErrorHandler.Error("RemotingAppender ["+Name+"] failed to send all queued events before close, in OnClose."); - } - } - - #endregion - - /// - /// A work item is being queued into the thread pool - /// - private void BeginAsyncSend() - { - // The work queue is not empty - m_workQueueEmptyEvent.Reset(); - - // Increment the queued count - Interlocked.Increment(ref m_queuedCallbackCount); - } - - /// - /// A work item from the thread pool has completed - /// - private void EndAsyncSend() - { - // Decrement the queued count - if (Interlocked.Decrement(ref m_queuedCallbackCount) <= 0) - { - // If the work queue is empty then set the event - m_workQueueEmptyEvent.Set(); - } - } - - /// - /// Send the contents of the buffer to the remote sink. - /// - /// - /// This method is designed to be used with the . - /// This method expects to be passed an array of - /// objects in the state param. - /// - /// the logging events to send - private void SendBufferCallback(object state) - { - try - { - LoggingEvent[] events = (LoggingEvent[])state; - - // Send the events - m_sinkObj.LogEvents(events); - } - catch(Exception ex) - { - ErrorHandler.Error("Failed in SendBufferCallback", ex); - } - finally - { - EndAsyncSend(); - } - } - - #region Private Instance Fields - - /// - /// The URL of the remote sink. - /// - private string m_sinkUrl; - - /// - /// The local proxy (.NET remoting) for the remote logging sink. - /// - private IRemoteLoggingSink m_sinkObj; - - /// - /// The number of queued callbacks currently waiting or executing - /// - private int m_queuedCallbackCount = 0; - - /// - /// Event used to signal when there are no queued work items - /// - /// - /// This event is set when there are no queued work items. In this - /// state it is safe to close the appender. - /// - private ManualResetEvent m_workQueueEmptyEvent = new ManualResetEvent(true); - - #endregion Private Instance Fields - - /// - /// Interface used to deliver objects to a remote sink. - /// - /// - /// This interface must be implemented by a remoting sink - /// if the is to be used - /// to deliver logging events to the sink. - /// - public interface IRemoteLoggingSink - { - /// - /// Delivers logging events to the remote sink - /// - /// Array of events to log. - /// - /// - /// Delivers logging events to the remote sink - /// - /// - void LogEvents(LoggingEvent[] events); - } - } -} - -#endif // !NETCF \ No newline at end of file diff --git a/src/log4net/Appender/RollingFileAppender.cs b/src/log4net/Appender/RollingFileAppender.cs deleted file mode 100644 index 3044fc18..00000000 --- a/src/log4net/Appender/RollingFileAppender.cs +++ /dev/null @@ -1,1726 +0,0 @@ -#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 System.Collections; -using System.Globalization; -using System.IO; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Appender -{ -#if CONFIRM_WIN32_FILE_SHAREMODES - // The following sounds good, and I though it was the case, but after - // further testing on Windows I have not been able to confirm it. - - /// On the Windows platform if another process has a write lock on the file - /// that is to be deleted, but allows shared read access to the file then the - /// file can be moved, but cannot be deleted. If the other process also allows - /// shared delete access to the file then the file will be deleted once that - /// process closes the file. If it is necessary to open the log file or any - /// of the backup files outside of this appender for either read or - /// write access please ensure that read and delete share modes are enabled. -#endif - - /// - /// Appender that rolls log files based on size or date or both. - /// - /// - /// - /// RollingFileAppender can roll log files based on size or date or both - /// depending on the setting of the property. - /// When set to the log file will be rolled - /// once its size exceeds the . - /// When set to the log file will be rolled - /// once the date boundary specified in the property - /// is crossed. - /// When set to the log file will be - /// rolled once the date boundary specified in the property - /// is crossed, but within a date boundary the file will also be rolled - /// once its size exceeds the . - /// When set to the log file will be rolled when - /// the appender is configured. This effectively means that the log file can be - /// rolled once per program execution. - /// - /// - /// A of few additional optional features have been added: - /// - /// Attach date pattern for current log file - /// Backup number increments for newer files - /// Infinite number of backups by file size - /// - /// - /// - /// - /// - /// For large or infinite numbers of backup files a - /// greater than zero is highly recommended, otherwise all the backup files need - /// to be renamed each time a new backup is created. - /// - /// - /// When Date/Time based rolling is used setting - /// to will reduce the number of file renamings to few or none. - /// - /// - /// - /// - /// - /// Changing or without clearing - /// the log file directory of backup files will cause unexpected and unwanted side effects. - /// - /// - /// - /// - /// If Date/Time based rolling is enabled this appender will attempt to roll existing files - /// in the directory without a Date/Time tag based on the last write date of the base log file. - /// The appender only rolls the log file when a message is logged. If Date/Time based rolling - /// is enabled then the appender will not roll the log file at the Date/Time boundary but - /// at the point when the next message is logged after the boundary has been crossed. - /// - /// - /// - /// The extends the and - /// has the same behavior when opening the log file. - /// The appender will first try to open the file for writing when - /// is called. This will typically be during configuration. - /// If the file cannot be opened for writing the appender will attempt - /// to open the file again each time a message is logged to the appender. - /// If the file cannot be opened for writing when a message is logged then - /// the message will be discarded by this appender. - /// - /// - /// When rolling a backup file necessitates deleting an older backup file the - /// file to be deleted is moved to a temporary name before being deleted. - /// - /// - /// - /// - /// A maximum number of backup files when rolling on date/time boundaries is not supported. - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Aspi Havewala - /// Douglas de la Torre - /// Edward Smit - public class RollingFileAppender : FileAppender - { - #region Public Enums - - /// - /// Style of rolling to use - /// - /// - /// - /// Style of rolling to use - /// - /// - public enum RollingMode - { - /// - /// Roll files once per program execution - /// - /// - /// - /// Roll files once per program execution. - /// Well really once each time this appender is - /// configured. - /// - /// - /// Setting this option also sets AppendToFile to - /// false on the RollingFileAppender, otherwise - /// this appender would just be a normal file appender. - /// - /// - Once = 0, - - /// - /// Roll files based only on the size of the file - /// - Size = 1, - - /// - /// Roll files based only on the date - /// - Date = 2, - - /// - /// Roll files based on both the size and date of the file - /// - Composite = 3 - } - - #endregion - - #region Protected Enums - - /// - /// The code assumes that the following 'time' constants are in a increasing sequence. - /// - /// - /// - /// The code assumes that the following 'time' constants are in a increasing sequence. - /// - /// - protected enum RollPoint - { - /// - /// Roll the log not based on the date - /// - InvalidRollPoint =-1, - - /// - /// Roll the log for each minute - /// - TopOfMinute = 0, - - /// - /// Roll the log for each hour - /// - TopOfHour = 1, - - /// - /// Roll the log twice a day (midday and midnight) - /// - HalfDay = 2, - - /// - /// Roll the log each day (midnight) - /// - TopOfDay = 3, - - /// - /// Roll the log each week - /// - TopOfWeek = 4, - - /// - /// Roll the log each month - /// - TopOfMonth = 5 - } - - #endregion Protected Enums - - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public RollingFileAppender() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - -#if !NETCF - /// - /// Gets or sets the strategy for determining the current date and time. The default - /// implementation is to use LocalDateTime which internally calls through to DateTime.Now. - /// DateTime.UtcNow may be used on frameworks newer than .NET 1.0 by specifying - /// . - /// - /// - /// An implementation of the interface which returns the current date and time. - /// - /// - /// - /// Gets or sets the used to return the current date and time. - /// - /// - /// There are two built strategies for determining the current date and time, - /// - /// and . - /// - /// - /// The default strategy is . - /// - /// -#else - /// - /// Gets or sets the strategy for determining the current date and time. The default - /// implementation is to use LocalDateTime which internally calls through to DateTime.Now. - /// - /// - /// An implementation of the interface which returns the current date and time. - /// - /// - /// - /// Gets or sets the used to return the current date and time. - /// - /// - /// The default strategy is . - /// - /// -#endif - public IDateTime DateTimeStrategy - { - get { return m_dateTime; } - set { m_dateTime = value; } - } - - /// - /// Gets or sets the date pattern to be used for generating file names - /// when rolling over on date. - /// - /// - /// The date pattern to be used for generating file names when rolling - /// over on date. - /// - /// - /// - /// Takes a string in the same format as expected by - /// . - /// - /// - /// This property determines the rollover schedule when rolling over - /// on date. - /// - /// - public string DatePattern - { - get { return m_datePattern; } - set { m_datePattern = value; } - } - - /// - /// Gets or sets the maximum number of backup files that are kept before - /// the oldest is erased. - /// - /// - /// The maximum number of backup files that are kept before the oldest is - /// erased. - /// - /// - /// - /// If set to zero, then there will be no backup files and the log file - /// will be truncated when it reaches . - /// - /// - /// If a negative number is supplied then no deletions will be made. Note - /// that this could result in very slow performance as a large number of - /// files are rolled over unless is used. - /// - /// - /// The maximum applies to each time based group of files and - /// not the total. - /// - /// - public int MaxSizeRollBackups - { - get { return m_maxSizeRollBackups; } - set { m_maxSizeRollBackups = value; } - } - - /// - /// Gets or sets the maximum size that the output file is allowed to reach - /// before being rolled over to backup files. - /// - /// - /// The maximum size in bytes that the output file is allowed to reach before being - /// rolled over to backup files. - /// - /// - /// - /// This property is equivalent to except - /// that it is required for differentiating the setter taking a - /// argument from the setter taking a - /// argument. - /// - /// - /// The default maximum file size is 10MB (10*1024*1024). - /// - /// - public long MaxFileSize - { - get { return m_maxFileSize; } - set { m_maxFileSize = value; } - } - - /// - /// Gets or sets the maximum size that the output file is allowed to reach - /// before being rolled over to backup files. - /// - /// - /// The maximum size that the output file is allowed to reach before being - /// rolled over to backup files. - /// - /// - /// - /// This property allows you to specify the maximum size with the - /// suffixes "KB", "MB" or "GB" so that the size is interpreted being - /// expressed respectively in kilobytes, megabytes or gigabytes. - /// - /// - /// For example, the value "10KB" will be interpreted as 10240 bytes. - /// - /// - /// The default maximum file size is 10MB. - /// - /// - /// If you have the option to set the maximum file size programmatically - /// consider using the property instead as this - /// allows you to set the size in bytes as a . - /// - /// - public string MaximumFileSize - { - get { return m_maxFileSize.ToString(NumberFormatInfo.InvariantInfo); } - set { m_maxFileSize = OptionConverter.ToFileSize(value, m_maxFileSize + 1); } - } - - /// - /// Gets or sets the rolling file count direction. - /// - /// - /// The rolling file count direction. - /// - /// - /// - /// Indicates if the current file is the lowest numbered file or the - /// highest numbered file. - /// - /// - /// By default newer files have lower numbers ( < 0), - /// i.e. log.1 is most recent, log.5 is the 5th backup, etc... - /// - /// - /// >= 0 does the opposite i.e. - /// log.1 is the first backup made, log.5 is the 5th backup made, etc. - /// For infinite backups use >= 0 to reduce - /// rollover costs. - /// - /// The default file count direction is -1. - /// - public int CountDirection - { - get { return m_countDirection; } - set { m_countDirection = value; } - } - - /// - /// Gets or sets the rolling style. - /// - /// The rolling style. - /// - /// - /// The default rolling style is . - /// - /// - /// When set to this appender's - /// property is set to false, otherwise - /// the appender would append to a single file rather than rolling - /// the file each time it is opened. - /// - /// - public RollingMode RollingStyle - { - get { return m_rollingStyle; } - set - { - m_rollingStyle = value; - switch (m_rollingStyle) - { - case RollingMode.Once: - m_rollDate = false; - m_rollSize = false; - - this.AppendToFile = false; - break; - - case RollingMode.Size: - m_rollDate = false; - m_rollSize = true; - break; - - case RollingMode.Date: - m_rollDate = true; - m_rollSize = false; - break; - - case RollingMode.Composite: - m_rollDate = true; - m_rollSize = true; - break; - } - } - } - - /// - /// Gets or sets a value indicating whether to preserve the file name extension when rolling. - /// - /// - /// true if the file name extension should be preserved. - /// - /// - /// - /// By default file.log is rolled to file.log.yyyy-MM-dd or file.log.curSizeRollBackup. - /// However, under Windows the new file name will loose any program associations as the - /// extension is changed. Optionally file.log can be renamed to file.yyyy-MM-dd.log or - /// file.curSizeRollBackup.log to maintain any program associations. - /// - /// - public bool PreserveLogFileNameExtension - { - get { return m_preserveLogFileNameExtension; } - set { m_preserveLogFileNameExtension = value; } - } - - /// - /// Gets or sets a value indicating whether to always log to - /// the same file. - /// - /// - /// true if always should be logged to the same file, otherwise false. - /// - /// - /// - /// By default file.log is always the current file. Optionally - /// file.log.yyyy-mm-dd for current formatted datePattern can by the currently - /// logging file (or file.log.curSizeRollBackup or even - /// file.log.yyyy-mm-dd.curSizeRollBackup). - /// - /// - /// This will make time based rollovers with a large number of backups - /// much faster as the appender it won't have to rename all the backups! - /// - /// - public bool StaticLogFileName - { - get { return m_staticLogFileName; } - set { m_staticLogFileName = value; } - } - - #endregion Public Instance Properties - - #region Private Static Fields - - /// - /// The fully qualified type of the RollingFileAppender class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(RollingFileAppender); - - #endregion Private Static Fields - - #region Override implementation of FileAppender - - /// - /// Sets the quiet writer being used. - /// - /// - /// This method can be overridden by sub classes. - /// - /// the writer to set - override protected void SetQWForFiles(TextWriter writer) - { - QuietWriter = new CountingQuietTextWriter(writer, ErrorHandler); - } - - /// - /// Write out a logging event. - /// - /// the event to write to file. - /// - /// - /// Handles append time behavior for RollingFileAppender. This checks - /// if a roll over either by date (checked first) or time (checked second) - /// is need and then appends to the file last. - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - AdjustFileBeforeAppend(); - base.Append(loggingEvent); - } - - /// - /// Write out an array of logging events. - /// - /// the events to write to file. - /// - /// - /// Handles append time behavior for RollingFileAppender. This checks - /// if a roll over either by date (checked first) or time (checked second) - /// is need and then appends to the file last. - /// - /// - override protected void Append(LoggingEvent[] loggingEvents) - { - AdjustFileBeforeAppend(); - base.Append(loggingEvents); - } - - /// - /// Performs any required rolling before outputting the next event - /// - /// - /// - /// Handles append time behavior for RollingFileAppender. This checks - /// if a roll over either by date (checked first) or time (checked second) - /// is need and then appends to the file last. - /// - /// - virtual protected void AdjustFileBeforeAppend() - { - if (m_rollDate) - { - DateTime n = m_dateTime.Now; - if (n >= m_nextCheck) - { - m_now = n; - m_nextCheck = NextCheckDate(m_now, m_rollPoint); - - RollOverTime(true); - } - } - - if (m_rollSize) - { - if ((File != null) && ((CountingQuietTextWriter)QuietWriter).Count >= m_maxFileSize) - { - RollOverSize(); - } - } - } - - /// - /// Creates and opens the file for logging. If - /// is false then the fully qualified name is determined and used. - /// - /// the name of the file to open - /// true to append to existing file - /// - /// This method will ensure that the directory structure - /// for the specified exists. - /// - override protected void OpenFile(string fileName, bool append) - { - lock(this) - { - fileName = GetNextOutputFileName(fileName); - - // Calculate the current size of the file - long currentCount = 0; - if (append) - { - using(SecurityContext.Impersonate(this)) - { - if (System.IO.File.Exists(fileName)) - { - currentCount = (new FileInfo(fileName)).Length; - } - } - } - else - { - if (LogLog.IsErrorEnabled) - { - // Internal check that the file is not being overwritten - // If not Appending to an existing file we should have rolled the file out of the - // way. Therefore we should not be over-writing an existing file. - // The only exception is if we are not allowed to roll the existing file away. - if (m_maxSizeRollBackups != 0 && FileExists(fileName)) - { - LogLog.Error(declaringType, "RollingFileAppender: INTERNAL ERROR. Append is False but OutputFile ["+fileName+"] already exists."); - } - } - } - - if (!m_staticLogFileName) - { - m_scheduledFilename = fileName; - } - - // Open the file (call the base class to do it) - base.OpenFile(fileName, append); - - // Set the file size onto the counting writer - ((CountingQuietTextWriter)QuietWriter).Count = currentCount; - } - } - - /// - /// Get the current output file name - /// - /// the base file name - /// the output file name - /// - /// The output file name is based on the base fileName specified. - /// If is set then the output - /// file name is the same as the base file passed in. Otherwise - /// the output file depends on the date pattern, on the count - /// direction or both. - /// - protected string GetNextOutputFileName(string fileName) - { - if (!m_staticLogFileName) - { - fileName = fileName.Trim(); - - if (m_rollDate) - { - fileName = CombinePath(fileName, m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo)); - } - - if (m_countDirection >= 0) - { - fileName = CombinePath(fileName, "." + m_curSizeRollBackups); - } - } - - return fileName; - } - - #endregion - - #region Initialize Options - - /// - /// Determines curSizeRollBackups (only within the current roll point) - /// - private void DetermineCurSizeRollBackups() - { - m_curSizeRollBackups = 0; - - string fullPath = null; - string fileName = null; - - using(SecurityContext.Impersonate(this)) - { - fullPath = System.IO.Path.GetFullPath(m_baseFileName); - fileName = System.IO.Path.GetFileName(fullPath); - } - - ArrayList arrayFiles = GetExistingFiles(fullPath); - InitializeRollBackups(fileName, arrayFiles); - - LogLog.Debug(declaringType, "curSizeRollBackups starts at ["+m_curSizeRollBackups+"]"); - } - - /// - /// Generates a wildcard pattern that can be used to find all files - /// that are similar to the base file name. - /// - /// - /// - private string GetWildcardPatternForFile(string baseFileName) - { - if (m_preserveLogFileNameExtension) - { - return Path.GetFileNameWithoutExtension(baseFileName) + ".*" + Path.GetExtension(baseFileName); - } - else - { - return baseFileName + '*'; - } - } - - /// - /// Builds a list of filenames for all files matching the base filename plus a file - /// pattern. - /// - /// - /// - private ArrayList GetExistingFiles(string baseFilePath) - { - ArrayList alFiles = new ArrayList(); - - string directory = null; - - using(SecurityContext.Impersonate(this)) - { - string fullPath = Path.GetFullPath(baseFilePath); - - directory = Path.GetDirectoryName(fullPath); - if (Directory.Exists(directory)) - { - string baseFileName = Path.GetFileName(fullPath); - - string[] files = Directory.GetFiles(directory, GetWildcardPatternForFile(baseFileName)); - - if (files != null) - { - for (int i = 0; i < files.Length; i++) - { - string curFileName = Path.GetFileName(files[i]); - if (curFileName.StartsWith(Path.GetFileNameWithoutExtension(baseFileName))) - { - alFiles.Add(curFileName); - } - } - } - } - } - LogLog.Debug(declaringType, "Searched for existing files in ["+directory+"]"); - return alFiles; - } - - /// - /// Initiates a roll over if needed for crossing a date boundary since the last run. - /// - private void RollOverIfDateBoundaryCrossing() - { - if (m_staticLogFileName && m_rollDate) - { - if (FileExists(m_baseFileName)) - { - DateTime last; - using(SecurityContext.Impersonate(this)) { -#if !NETCF - if (DateTimeStrategy is UniversalDateTime) - { - last = System.IO.File.GetLastWriteTimeUtc(m_baseFileName); - } - else - { -#endif - last = System.IO.File.GetLastWriteTime(m_baseFileName); -#if !NETCF - } -#endif - } - LogLog.Debug(declaringType, "["+last.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo)+"] vs. ["+m_now.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo)+"]"); - - if (!(last.ToString(m_datePattern,System.Globalization.DateTimeFormatInfo.InvariantInfo).Equals(m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo)))) - { - m_scheduledFilename = CombinePath(m_baseFileName, last.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo)); - LogLog.Debug(declaringType, "Initial roll over to ["+m_scheduledFilename+"]"); - RollOverTime(false); - LogLog.Debug(declaringType, "curSizeRollBackups after rollOver at ["+m_curSizeRollBackups+"]"); - } - } - } - } - - /// - /// Initializes based on existing conditions at time of . - /// - /// - /// - /// Initializes based on existing conditions at time of . - /// The following is done - /// - /// determine curSizeRollBackups (only within the current roll point) - /// initiates a roll over if needed for crossing a date boundary since the last run. - /// - /// - /// - protected void ExistingInit() - { - DetermineCurSizeRollBackups(); - RollOverIfDateBoundaryCrossing(); - - // If file exists and we are not appending then roll it out of the way - if (AppendToFile == false) - { - bool fileExists = false; - string fileName = GetNextOutputFileName(m_baseFileName); - - using(SecurityContext.Impersonate(this)) - { - fileExists = System.IO.File.Exists(fileName); - } - - if (fileExists) - { - if (m_maxSizeRollBackups == 0) - { - LogLog.Debug(declaringType, "Output file ["+fileName+"] already exists. MaxSizeRollBackups is 0; cannot roll. Overwriting existing file."); - } - else - { - LogLog.Debug(declaringType, "Output file ["+fileName+"] already exists. Not appending to file. Rolling existing file out of the way."); - - RollOverRenameFiles(fileName); - } - } - } - } - - /// - /// Does the work of bumping the 'current' file counter higher - /// to the highest count when an incremental file name is seen. - /// The highest count is either the first file (when count direction - /// is greater than 0) or the last file (when count direction less than 0). - /// In either case, we want to know the highest count that is present. - /// - /// - /// - private void InitializeFromOneFile(string baseFile, string curFileName) - { - if (curFileName.StartsWith(Path.GetFileNameWithoutExtension(baseFile)) == false) - { - // This is not a log file, so ignore - return; - } - if (curFileName.Equals(baseFile)) - { - // Base log file is not an incremented logfile (.1 or .2, etc) - return; - } - - /* - if (m_staticLogFileName) - { - int endLength = curFileName.Length - index; - if (baseFile.Length + endLength != curFileName.Length) - { - // file is probably scheduledFilename + .x so I don't care - return; - } - } - */ - - // Only look for files in the current roll point - if (m_rollDate && !m_staticLogFileName) - { - string date = m_dateTime.Now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo); - string prefix = m_preserveLogFileNameExtension ? Path.GetFileNameWithoutExtension(baseFile) + date : baseFile + date; - string suffix = m_preserveLogFileNameExtension ? Path.GetExtension(baseFile) : ""; - if (!curFileName.StartsWith(prefix) || !curFileName.EndsWith(suffix)) - { - LogLog.Debug(declaringType, "Ignoring file ["+curFileName+"] because it is from a different date period"); - return; - } - } - - try - { - // Bump the counter up to the highest count seen so far - int backup = GetBackUpIndex(curFileName); - - // caution: we might get a false positive when certain - // date patterns such as yyyyMMdd are used...those are - // valid number but aren't the kind of back up index - // we're looking for - if (backup > m_curSizeRollBackups) - { - if (0 == m_maxSizeRollBackups) - { - // Stay at zero when zero backups are desired - } - else if (-1 == m_maxSizeRollBackups) - { - // Infinite backups, so go as high as the highest value - m_curSizeRollBackups = backup; - } - else - { - // Backups limited to a finite number - if (m_countDirection >= 0) - { - // Go with the highest file when counting up - m_curSizeRollBackups = backup; - } - else - { - // Clip to the limit when counting down - if (backup <= m_maxSizeRollBackups) - { - m_curSizeRollBackups = backup; - } - } - } - LogLog.Debug(declaringType, "File name [" + curFileName + "] moves current count to [" + m_curSizeRollBackups + "]"); - } - } - catch(FormatException) - { - //this happens when file.log -> file.log.yyyy-MM-dd which is normal - //when staticLogFileName == false - LogLog.Debug(declaringType, "Encountered a backup file not ending in .x ["+curFileName+"]"); - } - } - - /// - /// Attempts to extract a number from the end of the file name that indicates - /// the number of the times the file has been rolled over. - /// - /// - /// Certain date pattern extensions like yyyyMMdd will be parsed as valid backup indexes. - /// - /// - /// - private int GetBackUpIndex(string curFileName) - { - int backUpIndex = -1; - string fileName = curFileName; - - if (m_preserveLogFileNameExtension) - { - fileName = Path.GetFileNameWithoutExtension(fileName); - } - - int index = fileName.LastIndexOf("."); - if (index > 0) - { - // if the "yyyy-MM-dd" component of file.log.yyyy-MM-dd is passed to TryParse - // it will gracefully fail and return backUpIndex will be 0 - SystemInfo.TryParse(fileName.Substring(index + 1), out backUpIndex); - } - - return backUpIndex; - } - - /// - /// Takes a list of files and a base file name, and looks for - /// 'incremented' versions of the base file. Bumps the max - /// count up to the highest count seen. - /// - /// - /// - private void InitializeRollBackups(string baseFile, ArrayList arrayFiles) - { - if (null != arrayFiles) - { - string baseFileLower = baseFile.ToLower(System.Globalization.CultureInfo.InvariantCulture); - - foreach(string curFileName in arrayFiles) - { - InitializeFromOneFile(baseFileLower, curFileName.ToLower(System.Globalization.CultureInfo.InvariantCulture)); - } - } - } - - /// - /// Calculates the RollPoint for the datePattern supplied. - /// - /// the date pattern to calculate the check period for - /// The RollPoint that is most accurate for the date pattern supplied - /// - /// Essentially the date pattern is examined to determine what the - /// most suitable roll point is. The roll point chosen is the roll point - /// with the smallest period that can be detected using the date pattern - /// supplied. i.e. if the date pattern only outputs the year, month, day - /// and hour then the smallest roll point that can be detected would be - /// and hourly roll point as minutes could not be detected. - /// - private RollPoint ComputeCheckPeriod(string datePattern) - { - // s_date1970 is 1970-01-01 00:00:00 this is UniversalSortableDateTimePattern - // (based on ISO 8601) using universal time. This date is used for reference - // purposes to calculate the resolution of the date pattern. - - // Get string representation of base line date - string r0 = s_date1970.ToString(datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo); - - // Check each type of rolling mode starting with the smallest increment. - for(int i = (int)RollPoint.TopOfMinute; i <= (int)RollPoint.TopOfMonth; i++) - { - // Get string representation of next pattern - string r1 = NextCheckDate(s_date1970, (RollPoint)i).ToString(datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo); - - LogLog.Debug(declaringType, "Type = ["+i+"], r0 = ["+r0+"], r1 = ["+r1+"]"); - - // Check if the string representations are different - if (r0 != null && r1 != null && !r0.Equals(r1)) - { - // Found highest precision roll point - return (RollPoint)i; - } - } - - return RollPoint.InvalidRollPoint; // Deliberately head for trouble... - } - - /// - /// Initialize the appender based on the options set - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// Sets initial conditions including date/time roll over information, first check, - /// scheduledFilename, and calls to initialize - /// the current number of backups. - /// - /// - override public void ActivateOptions() - { - if (m_dateTime == null) - { - m_dateTime = new LocalDateTime(); - } - - if (m_rollDate && m_datePattern != null) - { - m_now = m_dateTime.Now; - m_rollPoint = ComputeCheckPeriod(m_datePattern); - - if (m_rollPoint == RollPoint.InvalidRollPoint) - { - throw new ArgumentException("Invalid RollPoint, unable to parse ["+m_datePattern+"]"); - } - - // next line added as this removes the name check in rollOver - m_nextCheck = NextCheckDate(m_now, m_rollPoint); - } - else - { - if (m_rollDate) - { - ErrorHandler.Error("Either DatePattern or rollingStyle options are not set for ["+Name+"]."); - } - } - - if (SecurityContext == null) - { - SecurityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); - } - - using(SecurityContext.Impersonate(this)) - { - // Must convert the FileAppender's m_filePath to an absolute path before we - // call ExistingInit(). This will be done by the base.ActivateOptions() but - // we need to duplicate that functionality here first. - base.File = ConvertToFullPath(base.File.Trim()); - - // Store fully qualified base file name - m_baseFileName = base.File; - } - - if (m_rollDate && File != null && m_scheduledFilename == null) - { - m_scheduledFilename = CombinePath(File, m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo)); - } - - ExistingInit(); - - base.ActivateOptions(); - } - - #endregion - - #region Roll File - - /// - /// - /// - /// - /// .1, .2, .3, etc. - /// - private string CombinePath(string path1, string path2) - { - string extension = Path.GetExtension(path1); - if (m_preserveLogFileNameExtension && extension.Length > 0) - { - return Path.Combine(Path.GetDirectoryName(path1), Path.GetFileNameWithoutExtension(path1) + path2 + extension); - } - else - { - return path1 + path2; - } - } - - /// - /// Rollover the file(s) to date/time tagged file(s). - /// - /// set to true if the file to be rolled is currently open - /// - /// - /// Rollover the file(s) to date/time tagged file(s). - /// Resets curSizeRollBackups. - /// If fileIsOpen is set then the new file is opened (through SafeOpenFile). - /// - /// - protected void RollOverTime(bool fileIsOpen) - { - if (m_staticLogFileName) - { - // Compute filename, but only if datePattern is specified - if (m_datePattern == null) - { - ErrorHandler.Error("Missing DatePattern option in rollOver()."); - return; - } - - //is the new file name equivalent to the 'current' one - //something has gone wrong if we hit this -- we should only - //roll over if the new file will be different from the old - string dateFormat = m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo); - if (m_scheduledFilename.Equals(CombinePath(File, dateFormat))) - { - ErrorHandler.Error("Compare " + m_scheduledFilename + " : " + CombinePath(File, dateFormat)); - return; - } - - if (fileIsOpen) - { - // close current file, and rename it to datedFilename - this.CloseFile(); - } - - //we may have to roll over a large number of backups here - for (int i = 1; i <= m_curSizeRollBackups; i++) - { - string from = CombinePath(File, "." + i); - string to = CombinePath(m_scheduledFilename, "." + i); - RollFile(from, to); - } - - RollFile(File, m_scheduledFilename); - } - - //We've cleared out the old date and are ready for the new - m_curSizeRollBackups = 0; - - //new scheduled name - m_scheduledFilename = CombinePath(File, m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo)); - - if (fileIsOpen) - { - // This will also close the file. This is OK since multiple close operations are safe. - SafeOpenFile(m_baseFileName, false); - } - } - - /// - /// Renames file to file . - /// - /// Name of existing file to roll. - /// New name for file. - /// - /// - /// Renames file to file . It - /// also checks for existence of target file and deletes if it does. - /// - /// - protected void RollFile(string fromFile, string toFile) - { - if (FileExists(fromFile)) - { - // Delete the toFile if it exists - DeleteFile(toFile); - - // We may not have permission to move the file, or the file may be locked - try - { - LogLog.Debug(declaringType, "Moving [" + fromFile + "] -> [" + toFile + "]"); - using(SecurityContext.Impersonate(this)) - { - System.IO.File.Move(fromFile, toFile); - } - } - catch(Exception moveEx) - { - ErrorHandler.Error("Exception while rolling file [" + fromFile + "] -> [" + toFile + "]", moveEx, ErrorCode.GenericFailure); - } - } - else - { - LogLog.Warn(declaringType, "Cannot RollFile [" + fromFile + "] -> [" + toFile + "]. Source does not exist"); - } - } - - /// - /// Test if a file exists at a specified path - /// - /// the path to the file - /// true if the file exists - /// - /// - /// Test if a file exists at a specified path - /// - /// - protected bool FileExists(string path) - { - using(SecurityContext.Impersonate(this)) - { - return System.IO.File.Exists(path); - } - } - - /// - /// Deletes the specified file if it exists. - /// - /// The file to delete. - /// - /// - /// Delete a file if is exists. - /// The file is first moved to a new filename then deleted. - /// This allows the file to be removed even when it cannot - /// be deleted, but it still can be moved. - /// - /// - protected void DeleteFile(string fileName) - { - if (FileExists(fileName)) - { - // We may not have permission to delete the file, or the file may be locked - - string fileToDelete = fileName; - - // Try to move the file to temp name. - // If the file is locked we may still be able to move it - string tempFileName = fileName + "." + Environment.TickCount + ".DeletePending"; - try - { - using(SecurityContext.Impersonate(this)) - { - System.IO.File.Move(fileName, tempFileName); - } - fileToDelete = tempFileName; - } - catch(Exception moveEx) - { - LogLog.Debug(declaringType, "Exception while moving file to be deleted [" + fileName + "] -> [" + tempFileName + "]", moveEx); - } - - // Try to delete the file (either the original or the moved file) - try - { - using(SecurityContext.Impersonate(this)) - { - System.IO.File.Delete(fileToDelete); - } - LogLog.Debug(declaringType, "Deleted file [" + fileName + "]"); - } - catch(Exception deleteEx) - { - if (fileToDelete == fileName) - { - // Unable to move or delete the file - ErrorHandler.Error("Exception while deleting file [" + fileToDelete + "]", deleteEx, ErrorCode.GenericFailure); - } - else - { - // Moved the file, but the delete failed. File is probably locked. - // The file should automatically be deleted when the lock is released. - LogLog.Debug(declaringType, "Exception while deleting temp file [" + fileToDelete + "]", deleteEx); - } - } - } - } - - /// - /// Implements file roll base on file size. - /// - /// - /// - /// If the maximum number of size based backups is reached - /// (curSizeRollBackups == maxSizeRollBackups) then the oldest - /// file is deleted -- its index determined by the sign of countDirection. - /// If countDirection < 0, then files - /// {File.1, ..., File.curSizeRollBackups -1} - /// are renamed to {File.2, ..., - /// File.curSizeRollBackups}. Moreover, File is - /// renamed File.1 and closed. - /// - /// - /// A new file is created to receive further log output. - /// - /// - /// If maxSizeRollBackups is equal to zero, then the - /// File is truncated with no backup files created. - /// - /// - /// If maxSizeRollBackups < 0, then File is - /// renamed if needed and no files are deleted. - /// - /// - protected void RollOverSize() - { - this.CloseFile(); // keep windows happy. - - LogLog.Debug(declaringType, "rolling over count ["+((CountingQuietTextWriter)QuietWriter).Count+"]"); - LogLog.Debug(declaringType, "maxSizeRollBackups ["+m_maxSizeRollBackups+"]"); - LogLog.Debug(declaringType, "curSizeRollBackups ["+m_curSizeRollBackups+"]"); - LogLog.Debug(declaringType, "countDirection ["+m_countDirection+"]"); - - RollOverRenameFiles(File); - - if (!m_staticLogFileName && m_countDirection >= 0) - { - m_curSizeRollBackups++; - } - - // This will also close the file. This is OK since multiple close operations are safe. - SafeOpenFile(m_baseFileName, false); - } - - /// - /// Implements file roll. - /// - /// the base name to rename - /// - /// - /// If the maximum number of size based backups is reached - /// (curSizeRollBackups == maxSizeRollBackups) then the oldest - /// file is deleted -- its index determined by the sign of countDirection. - /// If countDirection < 0, then files - /// {File.1, ..., File.curSizeRollBackups -1} - /// are renamed to {File.2, ..., - /// File.curSizeRollBackups}. - /// - /// - /// If maxSizeRollBackups is equal to zero, then the - /// File is truncated with no backup files created. - /// - /// - /// If maxSizeRollBackups < 0, then File is - /// renamed if needed and no files are deleted. - /// - /// - /// This is called by to rename the files. - /// - /// - protected void RollOverRenameFiles(string baseFileName) - { - // If maxBackups <= 0, then there is no file renaming to be done. - if (m_maxSizeRollBackups != 0) - { - if (m_countDirection < 0) - { - // Delete the oldest file, to keep Windows happy. - if (m_curSizeRollBackups == m_maxSizeRollBackups) - { - DeleteFile(CombinePath(baseFileName, "." + m_maxSizeRollBackups)); - m_curSizeRollBackups--; - } - - // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2} - for (int i = m_curSizeRollBackups; i >= 1; i--) - { - RollFile((CombinePath(baseFileName, "." + i)), (CombinePath(baseFileName, "." + (i + 1)))); - } - - m_curSizeRollBackups++; - - // Rename fileName to fileName.1 - RollFile(baseFileName, CombinePath(baseFileName, ".1")); - } - else - { - //countDirection >= 0 - if (m_curSizeRollBackups >= m_maxSizeRollBackups && m_maxSizeRollBackups > 0) - { - //delete the first and keep counting up. - int oldestFileIndex = m_curSizeRollBackups - m_maxSizeRollBackups; - - // If static then there is 1 file without a number, therefore 1 less archive - if (m_staticLogFileName) - { - oldestFileIndex++; - } - - // If using a static log file then the base for the numbered sequence is the baseFileName passed in - // If not using a static log file then the baseFileName will already have a numbered postfix which - // we must remove, however it may have a date postfix which we must keep! - string archiveFileBaseName = baseFileName; - if (!m_staticLogFileName) - { - int lastDotIndex = archiveFileBaseName.LastIndexOf("."); - if (lastDotIndex >= 0) - { - archiveFileBaseName = archiveFileBaseName.Substring(0, lastDotIndex); - } - } - - // Delete the archive file - DeleteFile(CombinePath(archiveFileBaseName, "." + oldestFileIndex)); - } - - if (m_staticLogFileName) - { - m_curSizeRollBackups++; - RollFile(baseFileName, CombinePath(baseFileName, "." + m_curSizeRollBackups)); - } - } - } - } - - #endregion - - #region NextCheckDate - - /// - /// Get the start time of the next window for the current rollpoint - /// - /// the current date - /// the type of roll point we are working with - /// the start time for the next roll point an interval after the currentDateTime date - /// - /// - /// Returns the date of the next roll point after the currentDateTime date passed to the method. - /// - /// - /// The basic strategy is to subtract the time parts that are less significant - /// than the rollpoint from the current time. This should roll the time back to - /// the start of the time window for the current rollpoint. Then we add 1 window - /// worth of time and get the start time of the next window for the rollpoint. - /// - /// - protected DateTime NextCheckDate(DateTime currentDateTime, RollPoint rollPoint) - { - // Local variable to work on (this does not look very efficient) - DateTime current = currentDateTime; - - // Do slightly different things depending on what the type of roll point we want. - switch(rollPoint) - { - case RollPoint.TopOfMinute: - current = current.AddMilliseconds(-current.Millisecond); - current = current.AddSeconds(-current.Second); - current = current.AddMinutes(1); - break; - - case RollPoint.TopOfHour: - current = current.AddMilliseconds(-current.Millisecond); - current = current.AddSeconds(-current.Second); - current = current.AddMinutes(-current.Minute); - current = current.AddHours(1); - break; - - case RollPoint.HalfDay: - current = current.AddMilliseconds(-current.Millisecond); - current = current.AddSeconds(-current.Second); - current = current.AddMinutes(-current.Minute); - - if (current.Hour < 12) - { - current = current.AddHours(12 - current.Hour); - } - else - { - current = current.AddHours(-current.Hour); - current = current.AddDays(1); - } - break; - - case RollPoint.TopOfDay: - current = current.AddMilliseconds(-current.Millisecond); - current = current.AddSeconds(-current.Second); - current = current.AddMinutes(-current.Minute); - current = current.AddHours(-current.Hour); - current = current.AddDays(1); - break; - - case RollPoint.TopOfWeek: - current = current.AddMilliseconds(-current.Millisecond); - current = current.AddSeconds(-current.Second); - current = current.AddMinutes(-current.Minute); - current = current.AddHours(-current.Hour); - current = current.AddDays(7 - (int)current.DayOfWeek); - break; - - case RollPoint.TopOfMonth: - current = current.AddMilliseconds(-current.Millisecond); - current = current.AddSeconds(-current.Second); - current = current.AddMinutes(-current.Minute); - current = current.AddHours(-current.Hour); - current = current.AddDays(1 - current.Day); /* first day of month is 1 not 0 */ - current = current.AddMonths(1); - break; - } - return current; - } - - #endregion - - #region Private Instance Fields - - /// - /// This object supplies the current date/time. Allows test code to plug in - /// a method to control this class when testing date/time based rolling. The default - /// implementation uses the underlying value of DateTime.Now. - /// - private IDateTime m_dateTime = null; - - /// - /// The date pattern. By default, the pattern is set to ".yyyy-MM-dd" - /// meaning daily rollover. - /// - private string m_datePattern = ".yyyy-MM-dd"; - - /// - /// The actual formatted filename that is currently being written to - /// or will be the file transferred to on roll over - /// (based on staticLogFileName). - /// - private string m_scheduledFilename = null; - - /// - /// The timestamp when we shall next recompute the filename. - /// - private DateTime m_nextCheck = DateTime.MaxValue; - - /// - /// Holds date of last roll over - /// - private DateTime m_now; - - /// - /// The type of rolling done - /// - private RollPoint m_rollPoint; - - /// - /// The default maximum file size is 10MB - /// - private long m_maxFileSize = 10*1024*1024; - - /// - /// There is zero backup files by default - /// - private int m_maxSizeRollBackups = 0; - - /// - /// How many sized based backups have been made so far - /// - private int m_curSizeRollBackups = 0; - - /// - /// The rolling file count direction. - /// - private int m_countDirection = -1; - - /// - /// The rolling mode used in this appender. - /// - private RollingMode m_rollingStyle = RollingMode.Composite; - - /// - /// Cache flag set if we are rolling by date. - /// - private bool m_rollDate = true; - - /// - /// Cache flag set if we are rolling by size. - /// - private bool m_rollSize = true; - - /// - /// Value indicating whether to always log to the same file. - /// - private bool m_staticLogFileName = true; - - /// - /// Value indicating whether to preserve the file name extension when rolling. - /// - private bool m_preserveLogFileNameExtension = false; - - - /// - /// FileName provided in configuration. Used for rolling properly - /// - private string m_baseFileName; - - #endregion Private Instance Fields - - #region Static Members - - /// - /// The 1st of January 1970 in UTC - /// - private static readonly DateTime s_date1970 = new DateTime(1970, 1, 1); - - #endregion - - #region DateTime - - /// - /// This interface is used to supply Date/Time information to the . - /// - /// - /// This interface is used to supply Date/Time information to the . - /// Used primarily to allow test classes to plug themselves in so they can - /// supply test date/times. - /// - public interface IDateTime - { - /// - /// Gets the current time. - /// - /// The current time. - /// - /// - /// Gets the current time. - /// - /// - DateTime Now { get; } - } - - /// - /// Default implementation of that returns the current time. - /// - private class LocalDateTime : IDateTime - { - /// - /// Gets the current time. - /// - /// The current time. - /// - /// - /// Gets the current time. - /// - /// - public DateTime Now - { - get { return DateTime.Now; } - } - } - -#if !NETCF - /// - /// Implementation of that returns the current time as the coordinated universal time (UTC). - /// - private class UniversalDateTime : IDateTime - { - /// - /// Gets the current time. - /// - /// The current time. - /// - /// - /// Gets the current time. - /// - /// - public DateTime Now - { - get { return DateTime.UtcNow; } - } - } -#endif - - #endregion DateTime - } -} diff --git a/src/log4net/Appender/SmtpAppender.cs b/src/log4net/Appender/SmtpAppender.cs deleted file mode 100644 index 2ee363c7..00000000 --- a/src/log4net/Appender/SmtpAppender.cs +++ /dev/null @@ -1,527 +0,0 @@ -#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 - -// .NET Compact Framework has no support for System.Net.Mail -#if !NETCF - -using System; -using System.IO; -using System.Text; - -using System.Net.Mail; - -using log4net.Layout; -using log4net.Core; -using log4net.Util; - -namespace log4net.Appender -{ - /// - /// Send an e-mail when a specific logging event occurs, typically on errors - /// or fatal errors. - /// - /// - /// - /// The number of logging events delivered in this e-mail depend on - /// the value of option. The - /// keeps only the last - /// logging events in its - /// cyclic buffer. This keeps memory requirements at a reasonable level while - /// still delivering useful application context. - /// - /// - /// Authentication is supported by setting the property to - /// either or . - /// If using authentication then the - /// and properties must also be set. - /// - /// - /// To set the SMTP server port use the property. The default port is 25. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class SmtpAppender : BufferingAppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Default constructor - /// - /// - /// - /// Default constructor - /// - /// - public SmtpAppender() - { - } - - #endregion // Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets a comma- or semicolon-delimited list of recipient e-mail addresses (comma is the preferred delimiter). - /// - /// - /// - /// A comma- or semicolon-delimited list of e-mail addresses. - /// - /// - public string To - { - get { return m_to; } - set { m_to = MaybeTrimSeparators(value); } - } - - /// - /// Gets or sets a comma- or semicolon-delimited list of recipient e-mail addresses - /// that will be carbon copied (comma is the preferred delimiter). - /// - /// - /// - /// A comma- or semicolon-delimited list of e-mail addresses. - /// - /// - public string Cc - { - get { return m_cc; } - set { m_cc = MaybeTrimSeparators(value); } - } - - /// - /// Gets or sets a semicolon-delimited list of recipient e-mail addresses - /// that will be blind carbon copied. - /// - /// - /// A comma- or semicolon-delimited list of e-mail addresses. - /// - public string Bcc - { - get { return m_bcc; } - set { m_bcc = MaybeTrimSeparators(value); } - } - - /// - /// Gets or sets the e-mail address of the sender. - /// - /// - /// The e-mail address of the sender. - /// - /// - /// - /// The e-mail address of the sender. - /// - /// - public string From - { - get { return m_from; } - set { m_from = value; } - } - - /// - /// Gets or sets the subject line of the e-mail message. - /// - /// - /// The subject line of the e-mail message. - /// - /// - /// - /// The subject line of the e-mail message. - /// - /// - public string Subject - { - get { return m_subject; } - set { m_subject = value; } - } - - /// - /// Gets or sets the name of the SMTP relay mail server to use to send - /// the e-mail messages. - /// - /// - /// The name of the e-mail relay server. If SmtpServer is not set, the - /// name of the local SMTP server is used. - /// - /// - /// - /// The name of the e-mail relay server. If SmtpServer is not set, the - /// name of the local SMTP server is used. - /// - /// - public string SmtpHost - { - get { return m_smtpHost; } - set { m_smtpHost = value; } - } - - /// - /// The mode to use to authentication with the SMTP server - /// - /// - /// - /// Valid Authentication mode values are: , - /// , and . - /// The default value is . When using - /// you must specify the - /// and to use to authenticate. - /// When using the Windows credentials for the current - /// thread, if impersonating, or the process will be used to authenticate. - /// - /// - public SmtpAuthentication Authentication - { - get { return m_authentication; } - set { m_authentication = value; } - } - - /// - /// The username to use to authenticate with the SMTP server - /// - /// - /// - /// A and must be specified when - /// is set to , - /// otherwise the username will be ignored. - /// - /// - public string Username - { - get { return m_username; } - set { m_username = value; } - } - - /// - /// The password to use to authenticate with the SMTP server - /// - /// - /// - /// A and must be specified when - /// is set to , - /// otherwise the password will be ignored. - /// - /// - public string Password - { - get { return m_password; } - set { m_password = value; } - } - - /// - /// The port on which the SMTP server is listening - /// - /// - /// - /// The port on which the SMTP server is listening. The default - /// port is 25. - /// - /// - public int Port - { - get { return m_port; } - set { m_port = value; } - } - - /// - /// Gets or sets the priority of the e-mail message - /// - /// - /// One of the values. - /// - /// - /// - /// Sets the priority of the e-mails generated by this - /// appender. The default priority is . - /// - /// - /// If you are using this appender to report errors then - /// you may want to set the priority to . - /// - /// - public MailPriority Priority - { - get { return m_mailPriority; } - set { m_mailPriority = value; } - } - - /// - /// Enable or disable use of SSL when sending e-mail message - /// - public bool EnableSsl - { - get { return m_enableSsl; } - set { m_enableSsl = value; } - } - - /// - /// Gets or sets the reply-to e-mail address. - /// - public string ReplyTo - { - get { return m_replyTo; } - set { m_replyTo = value; } - } - - /// - /// Gets or sets the subject encoding to be used. - /// - /// - /// The default encoding is the operating system's current ANSI codepage. - /// - public Encoding SubjectEncoding - { - get { return m_subjectEncoding; } - set { m_subjectEncoding = value; } - } - - /// - /// Gets or sets the body encoding to be used. - /// - /// - /// The default encoding is the operating system's current ANSI codepage. - /// - public Encoding BodyEncoding - { - get { return m_bodyEncoding; } - set { m_bodyEncoding = value; } - } - - /// - /// Gets or sets a value indicating whether the mail message body is in HTML. - /// - virtual public bool IsBodyHTML - { - get { return isBodyHTML; } - set { isBodyHTML = value; } - } - - #endregion // Public Instance Properties - - #region Override implementation of BufferingAppenderSkeleton - - /// - /// Sends the contents of the cyclic buffer as an e-mail message. - /// - /// The logging events to send. - override protected void SendBuffer(LoggingEvent[] events) - { - // Note: this code already owns the monitor for this - // appender. This frees us from needing to synchronize again. - try - { - SendEmail(GetMailMessageBody(events)); - } - catch (Exception e) - { - ErrorHandler.Error("Error occurred while sending e-mail notification.", e); - } - } - - #endregion // Override implementation of BufferingAppenderSkeleton - - #region Override implementation of AppenderSkeleton - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion // Override implementation of AppenderSkeleton - - #region Protected Methods - - /// - /// Creates the body of the message to send - /// - /// - /// - virtual protected string GetMailMessageBody(LoggingEvent[] events) - { - StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture); - - string t = Layout.Header; - if (t != null) - { - writer.Write(t); - } - - for (int i = 0; i < events.Length; i++) - { - // Render the event and append the text to the buffer - RenderLoggingEvent(writer, events[i]); - } - - t = Layout.Footer; - if (t != null) - { - writer.Write(t); - } - - return writer.ToString(); - } - - /// - /// Send the email message - /// - /// the body text to include in the mail - virtual protected void SendEmail(string messageBody) - { - // Create and configure the smtp client - SmtpClient smtpClient = new SmtpClient(); - if (!String.IsNullOrEmpty(m_smtpHost)) - { - smtpClient.Host = m_smtpHost; - } - smtpClient.Port = m_port; - smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network; - smtpClient.EnableSsl = m_enableSsl; - - if (m_authentication == SmtpAuthentication.Basic) - { - // Perform basic authentication - smtpClient.Credentials = new System.Net.NetworkCredential(m_username, m_password); - } - else if (m_authentication == SmtpAuthentication.Ntlm) - { - // Perform integrated authentication (NTLM) - smtpClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials; - } - - using (MailMessage mailMessage = new MailMessage()) - { - mailMessage.Body = messageBody; - mailMessage.BodyEncoding = m_bodyEncoding; - mailMessage.IsBodyHtml = IsBodyHTML; - mailMessage.From = new MailAddress(m_from); - mailMessage.To.Add(m_to); - if (!String.IsNullOrEmpty(m_cc)) - { - mailMessage.CC.Add(m_cc); - } - if (!String.IsNullOrEmpty(m_bcc)) - { - mailMessage.Bcc.Add(m_bcc); - } - if (!String.IsNullOrEmpty(m_replyTo)) - { - // .NET 4.0 warning CS0618: 'System.Net.Mail.MailMessage.ReplyTo' is obsolete: - // 'ReplyTo is obsoleted for this type. Please use ReplyToList instead which can accept multiple addresses. http://go.microsoft.com/fwlink/?linkid=14202' -#if !FRAMEWORK_4_0_OR_ABOVE - mailMessage.ReplyTo = new MailAddress(m_replyTo); -#else - mailMessage.ReplyToList.Add(new MailAddress(m_replyTo)); -#endif - } - mailMessage.Subject = m_subject; - mailMessage.SubjectEncoding = m_subjectEncoding; - mailMessage.Priority = m_mailPriority; - - // TODO: Consider using SendAsync to send the message without blocking. We would need a SendCompletedCallback to log errors. - smtpClient.Send(mailMessage); - } - } - - #endregion // Protected Methods - - #region Private Instance Fields - - private string m_to; - private string m_cc; - private string m_bcc; - private string m_from; - private string m_subject; - private string m_smtpHost; - private Encoding m_subjectEncoding = Encoding.UTF8; - private Encoding m_bodyEncoding = Encoding.UTF8; - private bool isBodyHTML = false; - - // authentication fields - private SmtpAuthentication m_authentication = SmtpAuthentication.None; - private string m_username; - private string m_password; - - // server port, default port 25 - private int m_port = 25; - - private MailPriority m_mailPriority = MailPriority.Normal; - - private bool m_enableSsl = false; - private string m_replyTo; - - #endregion // Private Instance Fields - - #region SmtpAuthentication Enum - - /// - /// Values for the property. - /// - /// - /// - /// SMTP authentication modes. - /// - /// - public enum SmtpAuthentication - { - /// - /// No authentication - /// - None, - - /// - /// Basic authentication. - /// - /// - /// Requires a username and password to be supplied - /// - Basic, - - /// - /// Integrated authentication - /// - /// - /// Uses the Windows credentials from the current thread or process to authenticate. - /// - Ntlm - } - - #endregion // SmtpAuthentication Enum - - private static readonly char[] ADDRESS_DELIMITERS = new char[] { ',', ';' }; - - /// - /// trims leading and trailing commas or semicolons - /// - private static string MaybeTrimSeparators(string s) { - return string.IsNullOrEmpty(s) ? s : s.Trim(ADDRESS_DELIMITERS); - } - } -} - -#endif // !NETCF diff --git a/src/log4net/Appender/SmtpPickupDirAppender.cs b/src/log4net/Appender/SmtpPickupDirAppender.cs deleted file mode 100644 index 288d5b23..00000000 --- a/src/log4net/Appender/SmtpPickupDirAppender.cs +++ /dev/null @@ -1,317 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Layout; -using log4net.Core; -using log4net.Util; - -namespace log4net.Appender -{ - /// - /// Send an email when a specific logging event occurs, typically on errors - /// or fatal errors. Rather than sending via smtp it writes a file into the - /// directory specified by . This allows services such - /// as the IIS SMTP agent to manage sending the messages. - /// - /// - /// - /// The configuration for this appender is identical to that of the SMTPAppender, - /// except that instead of specifying the SMTPAppender.SMTPHost you specify - /// . - /// - /// - /// The number of logging events delivered in this e-mail depend on - /// the value of option. The - /// keeps only the last - /// logging events in its - /// cyclic buffer. This keeps memory requirements at a reasonable level while - /// still delivering useful application context. - /// - /// - /// Niall Daley - /// Nicko Cadell - public class SmtpPickupDirAppender : BufferingAppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Default constructor - /// - /// - /// - /// Default constructor - /// - /// - public SmtpPickupDirAppender() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets a semicolon-delimited list of recipient e-mail addresses. - /// - /// - /// A semicolon-delimited list of e-mail addresses. - /// - /// - /// - /// A semicolon-delimited list of e-mail addresses. - /// - /// - public string To - { - get { return m_to; } - set { m_to = value; } - } - - /// - /// Gets or sets the e-mail address of the sender. - /// - /// - /// The e-mail address of the sender. - /// - /// - /// - /// The e-mail address of the sender. - /// - /// - public string From - { - get { return m_from; } - set { m_from = value; } - } - - /// - /// Gets or sets the subject line of the e-mail message. - /// - /// - /// The subject line of the e-mail message. - /// - /// - /// - /// The subject line of the e-mail message. - /// - /// - public string Subject - { - get { return m_subject; } - set { m_subject = value; } - } - - /// - /// Gets or sets the path to write the messages to. - /// - /// - /// - /// Gets or sets the path to write the messages to. This should be the same - /// as that used by the agent sending the messages. - /// - /// - public string PickupDir - { - get { return m_pickupDir; } - set { m_pickupDir = value; } - } - - /// - /// Gets or sets the used to write to the pickup directory. - /// - /// - /// The used to write to the pickup directory. - /// - /// - /// - /// Unless a specified here for this appender - /// the is queried for the - /// security context to use. The default behavior is to use the security context - /// of the current thread. - /// - /// - public SecurityContext SecurityContext - { - get { return m_securityContext; } - set { m_securityContext = value; } - } - - #endregion Public Instance Properties - - #region Override implementation of BufferingAppenderSkeleton - - /// - /// Sends the contents of the cyclic buffer as an e-mail message. - /// - /// The logging events to send. - /// - /// - /// Sends the contents of the cyclic buffer as an e-mail message. - /// - /// - override protected void SendBuffer(LoggingEvent[] events) - { - // Note: this code already owns the monitor for this - // appender. This frees us from needing to synchronize again. - try - { - string filePath = null; - StreamWriter writer = null; - - // Impersonate to open the file - using(SecurityContext.Impersonate(this)) - { - filePath = Path.Combine(m_pickupDir, SystemInfo.NewGuid().ToString("N")); - writer = File.CreateText(filePath); - } - - if (writer == null) - { - ErrorHandler.Error("Failed to create output file for writing ["+filePath+"]", null, ErrorCode.FileOpenFailure); - } - else - { - using(writer) - { - writer.WriteLine("To: " + m_to); - writer.WriteLine("From: " + m_from); - writer.WriteLine("Subject: " + m_subject); - writer.WriteLine(""); - - string t = Layout.Header; - if (t != null) - { - writer.Write(t); - } - - for(int i = 0; i < events.Length; i++) - { - // Render the event and append the text to the buffer - RenderLoggingEvent(writer, events[i]); - } - - t = Layout.Footer; - if (t != null) - { - writer.Write(t); - } - - writer.WriteLine(""); - writer.WriteLine("."); - } - } - } - catch(Exception e) - { - ErrorHandler.Error("Error occurred while sending e-mail notification.", e); - } - } - - #endregion Override implementation of BufferingAppenderSkeleton - - #region Override implementation of AppenderSkeleton - - /// - /// Activate the options on this appender. - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - override public void ActivateOptions() - { - base.ActivateOptions(); - - if (m_securityContext == null) - { - m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); - } - - using(SecurityContext.Impersonate(this)) - { - m_pickupDir = ConvertToFullPath(m_pickupDir.Trim()); - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion Override implementation of AppenderSkeleton - - #region Protected Static Methods - - /// - /// Convert a path into a fully qualified path. - /// - /// The path to convert. - /// The fully qualified path. - /// - /// - /// Converts the path specified to a fully - /// qualified path. If the path is relative it is - /// taken as relative from the application base - /// directory. - /// - /// - protected static string ConvertToFullPath(string path) - { - return SystemInfo.ConvertToFullPath(path); - } - - #endregion Protected Static Methods - - #region Private Instance Fields - - private string m_to; - private string m_from; - private string m_subject; - private string m_pickupDir; - - /// - /// The security context to use for privileged calls - /// - private SecurityContext m_securityContext; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Appender/TelnetAppender.cs b/src/log4net/Appender/TelnetAppender.cs deleted file mode 100644 index fc028016..00000000 --- a/src/log4net/Appender/TelnetAppender.cs +++ /dev/null @@ -1,517 +0,0 @@ -#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 System.Collections; -using System.Globalization; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.IO; -using System.Threading; - -using log4net.Layout; -using log4net.Core; -using log4net.Util; - -namespace log4net.Appender -{ - /// - /// Appender that allows clients to connect via Telnet to receive log messages - /// - /// - /// - /// The TelnetAppender accepts socket connections and streams logging messages - /// back to the client. - /// The output is provided in a telnet-friendly way so that a log can be monitored - /// over a TCP/IP socket. - /// This allows simple remote monitoring of application logging. - /// - /// - /// The default is 23 (the telnet port). - /// - /// - /// Keith Long - /// Nicko Cadell - public class TelnetAppender : AppenderSkeleton - { - private SocketHandler m_handler; - private int m_listeningPort = 23; - - #region Constructor - - /// - /// Default constructor - /// - /// - /// - /// Default constructor - /// - /// - public TelnetAppender() - { - } - - #endregion - - #region Private Static Fields - - /// - /// The fully qualified type of the TelnetAppender class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(TelnetAppender); - - #endregion Private Static Fields - - /// - /// Gets or sets the TCP port number on which this will listen for connections. - /// - /// - /// An integer value in the range to - /// indicating the TCP port number on which this will listen for connections. - /// - /// - /// - /// The default value is 23 (the telnet port). - /// - /// - /// The value specified is less than - /// or greater than . - public int Port - { - get - { - return m_listeningPort; - } - set - { - if (value < IPEndPoint.MinPort || value > IPEndPoint.MaxPort) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("value", (object)value, - "The value specified for Port is less than " + - IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + - " or greater than " + - IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + "."); - } - else - { - m_listeningPort = value; - } - } - } - - #region Override implementation of AppenderSkeleton - - /// - /// Overrides the parent method to close the socket handler - /// - /// - /// - /// Closes all the outstanding connections. - /// - /// - protected override void OnClose() - { - base.OnClose(); - - if (m_handler != null) - { - m_handler.Dispose(); - m_handler = null; - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - protected override bool RequiresLayout - { - get { return true; } - } - - /// - /// Initialize the appender based on the options set. - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// Create the socket handler and wait for connections - /// - /// - public override void ActivateOptions() - { - base.ActivateOptions(); - try - { - LogLog.Debug(declaringType, "Creating SocketHandler to listen on port ["+m_listeningPort+"]"); - m_handler = new SocketHandler(m_listeningPort); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Failed to create SocketHandler", ex); - throw; - } - } - - /// - /// Writes the logging event to each connected client. - /// - /// The event to log. - /// - /// - /// Writes the logging event to each connected client. - /// - /// - protected override void Append(LoggingEvent loggingEvent) - { - if (m_handler != null && m_handler.HasConnections) - { - m_handler.Send(RenderLoggingEvent(loggingEvent)); - } - } - - #endregion - - #region SocketHandler helper class - - /// - /// Helper class to manage connected clients - /// - /// - /// - /// The SocketHandler class is used to accept connections from - /// clients. It is threaded so that clients can connect/disconnect - /// asynchronously. - /// - /// - protected class SocketHandler : IDisposable - { - private const int MAX_CONNECTIONS = 20; - - private Socket m_serverSocket; - private ArrayList m_clients = new ArrayList(); - - /// - /// Class that represents a client connected to this handler - /// - /// - /// - /// Class that represents a client connected to this handler - /// - /// - protected class SocketClient : IDisposable - { - private Socket m_socket; - private StreamWriter m_writer; - - /// - /// Create this for the specified - /// - /// the client's socket - /// - /// - /// Opens a stream writer on the socket. - /// - /// - public SocketClient(Socket socket) - { - m_socket = socket; - - try - { - m_writer = new StreamWriter(new NetworkStream(socket)); - } - catch - { - Dispose(); - throw; - } - } - - /// - /// Write a string to the client - /// - /// string to send - /// - /// - /// Write a string to the client - /// - /// - public void Send(String message) - { - m_writer.Write(message); - m_writer.Flush(); - } - - #region IDisposable Members - - /// - /// Cleanup the clients connection - /// - /// - /// - /// Close the socket connection. - /// - /// - public void Dispose() - { - try - { - if (m_writer != null) - { - m_writer.Close(); - m_writer = null; - } - } - catch { } - - if (m_socket != null) - { - try - { - m_socket.Shutdown(SocketShutdown.Both); - } - catch { } - - try - { - m_socket.Close(); - } - catch { } - - m_socket = null; - } - } - - #endregion - } - - /// - /// Opens a new server port on - /// - /// the local port to listen on for connections - /// - /// - /// Creates a socket handler on the specified local server port. - /// - /// - public SocketHandler(int port) - { - m_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - m_serverSocket.Bind(new IPEndPoint(IPAddress.Any, port)); - m_serverSocket.Listen(5); - m_serverSocket.BeginAccept(new AsyncCallback(OnConnect), null); - } - - /// - /// Sends a string message to each of the connected clients - /// - /// the text to send - /// - /// - /// Sends a string message to each of the connected clients - /// - /// - public void Send(String message) - { - ArrayList localClients = m_clients; - - foreach (SocketClient client in localClients) - { - try - { - client.Send(message); - } - catch (Exception) - { - // The client has closed the connection, remove it from our list - client.Dispose(); - RemoveClient(client); - } - } - } - - /// - /// Add a client to the internal clients list - /// - /// client to add - private void AddClient(SocketClient client) - { - lock(this) - { - ArrayList clientsCopy = (ArrayList)m_clients.Clone(); - clientsCopy.Add(client); - m_clients = clientsCopy; - } - } - - /// - /// Remove a client from the internal clients list - /// - /// client to remove - private void RemoveClient(SocketClient client) - { - lock(this) - { - ArrayList clientsCopy = (ArrayList)m_clients.Clone(); - clientsCopy.Remove(client); - m_clients = clientsCopy; - } - } - - /// - /// Test if this handler has active connections - /// - /// - /// true if this handler has active connections - /// - /// - /// - /// This property will be true while this handler has - /// active connections, that is at least one connection that - /// the handler will attempt to send a message to. - /// - /// - public bool HasConnections - { - get - { - ArrayList localClients = m_clients; - - return (localClients != null && localClients.Count > 0); - } - } - - /// - /// Callback used to accept a connection on the server socket - /// - /// The result of the asynchronous operation - /// - /// - /// On connection adds to the list of connections - /// if there are two many open connections you will be disconnected - /// - /// - private void OnConnect(IAsyncResult asyncResult) - { - try - { - // Block until a client connects - Socket socket = m_serverSocket.EndAccept(asyncResult); - - LogLog.Debug(declaringType, "Accepting connection from ["+socket.RemoteEndPoint.ToString()+"]"); - SocketClient client = new SocketClient(socket); - - int currentActiveConnectionsCount = m_clients.Count; - if (currentActiveConnectionsCount < MAX_CONNECTIONS) - { - try - { - client.Send("TelnetAppender v1.0 (" + (currentActiveConnectionsCount + 1) + " active connections)\r\n\r\n"); - AddClient(client); - } - catch - { - client.Dispose(); - } - } - else - { - client.Send("Sorry - Too many connections.\r\n"); - client.Dispose(); - } - } - catch - { - } - finally - { - if (m_serverSocket != null) - { - m_serverSocket.BeginAccept(new AsyncCallback(OnConnect), null); - } - } - } - - #region IDisposable Members - - /// - /// Close all network connections - /// - /// - /// - /// Make sure we close all network connections - /// - /// - public void Dispose() - { - ArrayList localClients = m_clients; - - foreach (SocketClient client in localClients) - { - client.Dispose(); - } - m_clients.Clear(); - - Socket localSocket = m_serverSocket; - m_serverSocket = null; - try - { - localSocket.Shutdown(SocketShutdown.Both); - } - catch - { - } - - try - { - localSocket.Close(); - } - catch - { - } - } - - #endregion - } - - #endregion - } -} diff --git a/src/log4net/Appender/TextWriterAppender.cs b/src/log4net/Appender/TextWriterAppender.cs deleted file mode 100644 index 4139d443..00000000 --- a/src/log4net/Appender/TextWriterAppender.cs +++ /dev/null @@ -1,447 +0,0 @@ -#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 System.IO; - -using log4net.Util; -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Sends logging events to a . - /// - /// - /// - /// An Appender that writes to a . - /// - /// - /// This appender may be used stand alone if initialized with an appropriate - /// writer, however it is typically used as a base class for an appender that - /// can open a to write to. - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Douglas de la Torre - public class TextWriterAppender : AppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public TextWriterAppender() - { - } - - #endregion - - #region Public Instance Properties - - /// - /// Gets or set whether the appender will flush at the end - /// of each append operation. - /// - /// - /// - /// The default behavior is to flush at the end of each - /// append operation. - /// - /// - /// If this option is set to false, then the underlying - /// stream can defer persisting the logging event to a later - /// time. - /// - /// - /// - /// Avoiding the flush operation at the end of each append results in - /// a performance gain of 10 to 20 percent. However, there is safety - /// trade-off involved in skipping flushing. Indeed, when flushing is - /// skipped, then it is likely that the last few log events will not - /// be recorded on disk when the application exits. This is a high - /// price to pay even for a 20% performance gain. - /// - public bool ImmediateFlush - { - get { return m_immediateFlush; } - set { m_immediateFlush = value; } - } - - /// - /// Sets the where the log output will go. - /// - /// - /// - /// The specified must be open and writable. - /// - /// - /// The will be closed when the appender - /// instance is closed. - /// - /// - /// Note: Logging to an unopened will fail. - /// - /// - virtual public TextWriter Writer - { - get { return m_qtw; } - set - { - lock(this) - { - Reset(); - if (value != null) - { - m_qtw = new QuietTextWriter(value, ErrorHandler); - WriteHeader(); - } - } - } - } - - #endregion Public Instance Properties - - #region Override implementation of AppenderSkeleton - - /// - /// This method determines if there is a sense in attempting to append. - /// - /// - /// - /// This method checks if an output target has been set and if a - /// layout has been set. - /// - /// - /// false if any of the preconditions fail. - override protected bool PreAppendCheck() - { - if (!base.PreAppendCheck()) - { - return false; - } - - if (m_qtw == null) - { - // Allow subclass to lazily create the writer - PrepareWriter(); - - if (m_qtw == null) - { - ErrorHandler.Error("No output stream or file set for the appender named ["+ Name +"]."); - return false; - } - } - if (m_qtw.Closed) - { - ErrorHandler.Error("Output stream for appender named ["+ Name +"] has been closed."); - return false; - } - - return true; - } - - /// - /// This method is called by the - /// method. - /// - /// The event to log. - /// - /// - /// Writes a log statement to the output stream if the output stream exists - /// and is writable. - /// - /// - /// The format of the output will depend on the appender's layout. - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - RenderLoggingEvent(m_qtw, loggingEvent); - - if (m_immediateFlush) - { - m_qtw.Flush(); - } - } - - /// - /// This method is called by the - /// method. - /// - /// The array of events to log. - /// - /// - /// This method writes all the bulk logged events to the output writer - /// before flushing the stream. - /// - /// - override protected void Append(LoggingEvent[] loggingEvents) - { - foreach(LoggingEvent loggingEvent in loggingEvents) - { - RenderLoggingEvent(m_qtw, loggingEvent); - } - - if (m_immediateFlush) - { - m_qtw.Flush(); - } - } - - /// - /// Close this appender instance. The underlying stream or writer is also closed. - /// - /// - /// Closed appenders cannot be reused. - /// - override protected void OnClose() - { - lock(this) - { - Reset(); - } - } - - /// - /// Gets or set the and the underlying - /// , if any, for this appender. - /// - /// - /// The for this appender. - /// - override public IErrorHandler ErrorHandler - { - get { return base.ErrorHandler; } - set - { - lock(this) - { - if (value == null) - { - LogLog.Warn(declaringType, "TextWriterAppender: You have tried to set a null error-handler."); - } - else - { - base.ErrorHandler = value; - if (m_qtw != null) - { - m_qtw.ErrorHandler = value; - } - } - } - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion Override implementation of AppenderSkeleton - - #region Protected Instance Methods - - /// - /// Writes the footer and closes the underlying . - /// - /// - /// - /// Writes the footer and closes the underlying . - /// - /// - virtual protected void WriteFooterAndCloseWriter() - { - WriteFooter(); - CloseWriter(); - } - - /// - /// Closes the underlying . - /// - /// - /// - /// Closes the underlying . - /// - /// - virtual protected void CloseWriter() - { - if (m_qtw != null) - { - try - { - m_qtw.Close(); - } - catch(Exception e) - { - ErrorHandler.Error("Could not close writer ["+m_qtw+"]", e); - // do need to invoke an error handler - // at this late stage - } - } - } - - /// - /// Clears internal references to the underlying - /// and other variables. - /// - /// - /// - /// Subclasses can override this method for an alternate closing behavior. - /// - /// - virtual protected void Reset() - { - WriteFooterAndCloseWriter(); - m_qtw = null; - } - - /// - /// Writes a footer as produced by the embedded layout's property. - /// - /// - /// - /// Writes a footer as produced by the embedded layout's property. - /// - /// - virtual protected void WriteFooter() - { - if (Layout != null && m_qtw != null && !m_qtw.Closed) - { - string f = Layout.Footer; - if (f != null) - { - m_qtw.Write(f); - } - } - } - - /// - /// Writes a header produced by the embedded layout's property. - /// - /// - /// - /// Writes a header produced by the embedded layout's property. - /// - /// - virtual protected void WriteHeader() - { - if (Layout != null && m_qtw != null && !m_qtw.Closed) - { - string h = Layout.Header; - if (h != null) - { - m_qtw.Write(h); - } - } - } - - /// - /// Called to allow a subclass to lazily initialize the writer - /// - /// - /// - /// This method is called when an event is logged and the or - /// have not been set. This allows a subclass to - /// attempt to initialize the writer multiple times. - /// - /// - virtual protected void PrepareWriter() - { - } - - /// - /// Gets or sets the where logging events - /// will be written to. - /// - /// - /// The where logging events are written. - /// - /// - /// - /// This is the where logging events - /// will be written to. - /// - /// - protected QuietTextWriter QuietWriter - { - get { return m_qtw; } - set { m_qtw = value; } - } - - #endregion Protected Instance Methods - - #region Private Instance Fields - - /// - /// This is the where logging events - /// will be written to. - /// - private QuietTextWriter m_qtw; - - /// - /// Immediate flush means that the underlying - /// or output stream will be flushed at the end of each append operation. - /// - /// - /// - /// Immediate flush is slower but ensures that each append request is - /// actually written. If is set to - /// false, then there is a good chance that the last few - /// logging events are not actually persisted if and when the application - /// crashes. - /// - /// - /// The default value is true. - /// - /// - private bool m_immediateFlush = true; - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the TextWriterAppender class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(TextWriterAppender); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Appender/TraceAppender.cs b/src/log4net/Appender/TraceAppender.cs deleted file mode 100644 index b6c0e9cd..00000000 --- a/src/log4net/Appender/TraceAppender.cs +++ /dev/null @@ -1,194 +0,0 @@ -#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 - -#define TRACE - -using log4net.Layout; -using log4net.Core; - -namespace log4net.Appender -{ - /// - /// Appends log events to the system. - /// - /// - /// - /// The application configuration file can be used to control what listeners - /// are actually used. See the MSDN documentation for the - /// class for details on configuring the - /// trace system. - /// - /// - /// Events are written using the System.Diagnostics.Trace.Write(string,string) - /// method. The event's logger name is the default value for the category parameter - /// of the Write method. - /// - /// - /// Compact Framework
    - /// The Compact Framework does not support the - /// class for any operation except Assert. When using the Compact Framework this - /// appender will write to the system rather than - /// the Trace system. This appender will therefore behave like the . - ///
    - ///
    - /// Douglas de la Torre - /// Nicko Cadell - /// Gert Driesen - /// Ron Grabowski - public class TraceAppender : AppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the . - /// - /// - /// - /// Default constructor. - /// - /// - public TraceAppender() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets a value that indicates whether the appender will - /// flush at the end of each write. - /// - /// - /// The default behavior is to flush at the end of each - /// write. If the option is set tofalse, then the underlying - /// stream can defer writing to physical medium to a later time. - /// - /// - /// Avoiding the flush operation at the end of each append results - /// in a performance gain of 10 to 20 percent. However, there is safety - /// trade-off involved in skipping flushing. Indeed, when flushing is - /// skipped, then it is likely that the last few log events will not - /// be recorded on disk when the application exits. This is a high - /// price to pay even for a 20% performance gain. - /// - /// - public bool ImmediateFlush - { - get { return m_immediateFlush; } - set { m_immediateFlush = value; } - } - - /// - /// The category parameter sent to the Trace method. - /// - /// - /// - /// Defaults to %logger which will use the logger name of the current - /// as the category parameter. - /// - /// - /// - /// - public PatternLayout Category - { - get { return m_category; } - set { m_category = value; } - } - - #endregion Public Instance Properties - - #region Override implementation of AppenderSkeleton - - /// - /// Writes the logging event to the system. - /// - /// The event to log. - /// - /// - /// Writes the logging event to the system. - /// - /// - override protected void Append(LoggingEvent loggingEvent) - { - // - // Write the string to the Trace system - // -#if NETCF - System.Diagnostics.Debug.Write(RenderLoggingEvent(loggingEvent), m_category.Format(loggingEvent)); -#else - System.Diagnostics.Trace.Write(RenderLoggingEvent(loggingEvent), m_category.Format(loggingEvent)); -#endif - - // - // Flush the Trace system if needed - // - if (m_immediateFlush) - { -#if NETCF - System.Diagnostics.Debug.Flush(); -#else - System.Diagnostics.Trace.Flush(); -#endif - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - #endregion Override implementation of AppenderSkeleton - - #region Private Instance Fields - - /// - /// Immediate flush means that the underlying writer or output stream - /// will be flushed at the end of each append operation. - /// - /// - /// - /// Immediate flush is slower but ensures that each append request is - /// actually written. If is set to - /// false, then there is a good chance that the last few - /// logs events are not actually written to persistent media if and - /// when the application crashes. - /// - /// - /// The default value is true. - /// - private bool m_immediateFlush = true; - - /// - /// Defaults to %logger - /// - private PatternLayout m_category = new PatternLayout("%logger"); - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Appender/UdpAppender.cs b/src/log4net/Appender/UdpAppender.cs deleted file mode 100644 index 158a9e14..00000000 --- a/src/log4net/Appender/UdpAppender.cs +++ /dev/null @@ -1,543 +0,0 @@ -#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 System.Globalization; -using System.Net; -using System.Net.Sockets; -using System.Text; - -using log4net.Layout; -using log4net.Core; -using log4net.Util; - -namespace log4net.Appender -{ - /// - /// Sends logging events as connectionless UDP datagrams to a remote host or a - /// multicast group using an . - /// - /// - /// - /// UDP guarantees neither that messages arrive, nor that they arrive in the correct order. - /// - /// - /// To view the logging results, a custom application can be developed that listens for logging - /// events. - /// - /// - /// When decoding events send via this appender remember to use the same encoding - /// to decode the events as was used to send the events. See the - /// property to specify the encoding to use. - /// - /// - /// - /// This example shows how to log receive logging events that are sent - /// on IP address 244.0.0.1 and port 8080 to the console. The event is - /// encoded in the packet as a unicode string and it is decoded as such. - /// - /// IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - /// UdpClient udpClient; - /// byte[] buffer; - /// string loggingEvent; - /// - /// try - /// { - /// udpClient = new UdpClient(8080); - /// - /// while(true) - /// { - /// buffer = udpClient.Receive(ref remoteEndPoint); - /// loggingEvent = System.Text.Encoding.Unicode.GetString(buffer); - /// Console.WriteLine(loggingEvent); - /// } - /// } - /// catch(Exception e) - /// { - /// Console.WriteLine(e.ToString()); - /// } - /// - /// - /// Dim remoteEndPoint as IPEndPoint - /// Dim udpClient as UdpClient - /// Dim buffer as Byte() - /// Dim loggingEvent as String - /// - /// Try - /// remoteEndPoint = new IPEndPoint(IPAddress.Any, 0) - /// udpClient = new UdpClient(8080) - /// - /// While True - /// buffer = udpClient.Receive(ByRef remoteEndPoint) - /// loggingEvent = System.Text.Encoding.Unicode.GetString(buffer) - /// Console.WriteLine(loggingEvent) - /// Wend - /// Catch e As Exception - /// Console.WriteLine(e.ToString()) - /// End Try - /// - /// - /// An example configuration section to log information using this appender to the - /// IP 224.0.0.1 on port 8080: - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Gert Driesen - /// Nicko Cadell - public class UdpAppender : AppenderSkeleton - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// The default constructor initializes all fields to their default values. - /// - public UdpAppender() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the IP address of the remote host or multicast group to which - /// the underlying should sent the logging event. - /// - /// - /// The IP address of the remote host or multicast group to which the logging event - /// will be sent. - /// - /// - /// - /// Multicast addresses are identified by IP class D addresses (in the range 224.0.0.0 to - /// 239.255.255.255). Multicast packets can pass across different networks through routers, so - /// it is possible to use multicasts in an Internet scenario as long as your network provider - /// supports multicasting. - /// - /// - /// Hosts that want to receive particular multicast messages must register their interest by joining - /// the multicast group. Multicast messages are not sent to networks where no host has joined - /// the multicast group. Class D IP addresses are used for multicast groups, to differentiate - /// them from normal host addresses, allowing nodes to easily detect if a message is of interest. - /// - /// - /// Static multicast addresses that are needed globally are assigned by IANA. A few examples are listed in the table below: - /// - /// - /// - /// - /// IP Address - /// Description - /// - /// - /// 224.0.0.1 - /// - /// - /// Sends a message to all system on the subnet. - /// - /// - /// - /// - /// 224.0.0.2 - /// - /// - /// Sends a message to all routers on the subnet. - /// - /// - /// - /// - /// 224.0.0.12 - /// - /// - /// The DHCP server answers messages on the IP address 224.0.0.12, but only on a subnet. - /// - /// - /// - /// - /// - /// - /// A complete list of actually reserved multicast addresses and their owners in the ranges - /// defined by RFC 3171 can be found at the IANA web site. - /// - /// - /// The address range 239.0.0.0 to 239.255.255.255 is reserved for administrative scope-relative - /// addresses. These addresses can be reused with other local groups. Routers are typically - /// configured with filters to prevent multicast traffic in this range from flowing outside - /// of the local network. - /// - /// - public IPAddress RemoteAddress - { - get { return m_remoteAddress; } - set { m_remoteAddress = value; } - } - - /// - /// Gets or sets the TCP port number of the remote host or multicast group to which - /// the underlying should sent the logging event. - /// - /// - /// An integer value in the range to - /// indicating the TCP port number of the remote host or multicast group to which the logging event - /// will be sent. - /// - /// - /// The underlying will send messages to this TCP port number - /// on the remote host or multicast group. - /// - /// The value specified is less than or greater than . - public int RemotePort - { - get { return m_remotePort; } - set - { - if (value < IPEndPoint.MinPort || value > IPEndPoint.MaxPort) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("value", (object)value, - "The value specified is less than " + - IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + - " or greater than " + - IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + "."); - } - else - { - m_remotePort = value; - } - } - } - - /// - /// Gets or sets the TCP port number from which the underlying will communicate. - /// - /// - /// An integer value in the range to - /// indicating the TCP port number from which the underlying will communicate. - /// - /// - /// - /// The underlying will bind to this port for sending messages. - /// - /// - /// Setting the value to 0 (the default) will cause the udp client not to bind to - /// a local port. - /// - /// - /// The value specified is less than or greater than . - public int LocalPort - { - get { return m_localPort; } - set - { - if (value != 0 && (value < IPEndPoint.MinPort || value > IPEndPoint.MaxPort)) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("value", (object)value, - "The value specified is less than " + - IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + - " or greater than " + - IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + "."); - } - else - { - m_localPort = value; - } - } - } - - /// - /// Gets or sets used to write the packets. - /// - /// - /// The used to write the packets. - /// - /// - /// - /// The used to write the packets. - /// - /// - public Encoding Encoding - { - get { return m_encoding; } - set { m_encoding = value; } - } - - #endregion Public Instance Properties - - #region Protected Instance Properties - - /// - /// Gets or sets the underlying . - /// - /// - /// The underlying . - /// - /// - /// creates a to send logging events - /// over a network. Classes deriving from can use this - /// property to get or set this . Use the underlying - /// returned from if you require access beyond that which - /// provides. - /// - protected UdpClient Client - { - get { return this.m_client; } - set { this.m_client = value; } - } - - /// - /// Gets or sets the cached remote endpoint to which the logging events should be sent. - /// - /// - /// The cached remote endpoint to which the logging events will be sent. - /// - /// - /// The method will initialize the remote endpoint - /// with the values of the and - /// properties. - /// - protected IPEndPoint RemoteEndPoint - { - get { return this.m_remoteEndPoint; } - set { this.m_remoteEndPoint = value; } - } - - #endregion Protected Instance Properties - - #region Implementation of IOptionHandler - - /// - /// Initialize the appender based on the options set. - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// The appender will be ignored if no was specified or - /// an invalid remote or local TCP port number was specified. - /// - /// - /// The required property was not specified. - /// The TCP port number assigned to or is less than or greater than . - public override void ActivateOptions() - { - base.ActivateOptions(); - - if (this.RemoteAddress == null) - { - throw new ArgumentNullException("The required property 'Address' was not specified."); - } - else if (this.RemotePort < IPEndPoint.MinPort || this.RemotePort > IPEndPoint.MaxPort) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("this.RemotePort", (object)this.RemotePort, - "The RemotePort is less than " + - IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + - " or greater than " + - IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + "."); - } - else if (this.LocalPort != 0 && (this.LocalPort < IPEndPoint.MinPort || this.LocalPort > IPEndPoint.MaxPort)) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("this.LocalPort", (object)this.LocalPort, - "The LocalPort is less than " + - IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + - " or greater than " + - IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + "."); - } - else - { - this.RemoteEndPoint = new IPEndPoint(this.RemoteAddress, this.RemotePort); - this.InitializeClientConnection(); - } - } - - #endregion - - #region Override implementation of AppenderSkeleton - - /// - /// This method is called by the method. - /// - /// The event to log. - /// - /// - /// Sends the event using an UDP datagram. - /// - /// - /// Exceptions are passed to the . - /// - /// - protected override void Append(LoggingEvent loggingEvent) - { - try - { - Byte [] buffer = m_encoding.GetBytes(RenderLoggingEvent(loggingEvent).ToCharArray()); - this.Client.Send(buffer, buffer.Length, this.RemoteEndPoint); - } - catch (Exception ex) - { - ErrorHandler.Error( - "Unable to send logging event to remote host " + - this.RemoteAddress.ToString() + - " on port " + - this.RemotePort + ".", - ex, - ErrorCode.WriteFailure); - } - } - - /// - /// This appender requires a to be set. - /// - /// true - /// - /// - /// This appender requires a to be set. - /// - /// - override protected bool RequiresLayout - { - get { return true; } - } - - /// - /// Closes the UDP connection and releases all resources associated with - /// this instance. - /// - /// - /// - /// Disables the underlying and releases all managed - /// and unmanaged resources associated with the . - /// - /// - override protected void OnClose() - { - base.OnClose(); - - if (this.Client != null) - { - this.Client.Close(); - this.Client = null; - } - } - - #endregion Override implementation of AppenderSkeleton - - #region Protected Instance Methods - - /// - /// Initializes the underlying connection. - /// - /// - /// - /// The underlying is initialized and binds to the - /// port number from which you intend to communicate. - /// - /// - /// Exceptions are passed to the . - /// - /// - protected virtual void InitializeClientConnection() - { - try - { - if (this.LocalPort == 0) - { -#if NETCF - this.Client = new UdpClient(); -#else - this.Client = new UdpClient(RemoteAddress.AddressFamily); -#endif - } - else - { -#if NETCF - this.Client = new UdpClient(this.LocalPort); -#else - this.Client = new UdpClient(this.LocalPort, RemoteAddress.AddressFamily); -#endif - } - } - catch (Exception ex) - { - ErrorHandler.Error( - "Could not initialize the UdpClient connection on port " + - this.LocalPort.ToString(NumberFormatInfo.InvariantInfo) + ".", - ex, - ErrorCode.GenericFailure); - - this.Client = null; - } - } - - #endregion Protected Instance Methods - - #region Private Instance Fields - - /// - /// The IP address of the remote host or multicast group to which - /// the logging event will be sent. - /// - private IPAddress m_remoteAddress; - - /// - /// The TCP port number of the remote host or multicast group to - /// which the logging event will be sent. - /// - private int m_remotePort; - - /// - /// The cached remote endpoint to which the logging events will be sent. - /// - private IPEndPoint m_remoteEndPoint; - - /// - /// The TCP port number from which the will communicate. - /// - private int m_localPort; - - /// - /// The instance that will be used for sending the - /// logging events. - /// - private UdpClient m_client; - - /// - /// The encoding to use for the packet. - /// - private Encoding m_encoding = Encoding.Default; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/AssemblyInfo.cs b/src/log4net/AssemblyInfo.cs deleted file mode 100644 index 7df0c778..00000000 --- a/src/log4net/AssemblyInfo.cs +++ /dev/null @@ -1,90 +0,0 @@ -#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.Reflection; -using System.Runtime.CompilerServices; - -[assembly: System.Runtime.InteropServices.ComVisible(false)] - -// -// log4net is CLS compliant -// -[assembly: System.CLSCompliant(true)] - -#if (!NETCF) -// -// If log4net is strongly named it still allows partially trusted callers -// -[assembly: System.Security.AllowPartiallyTrustedCallers] -#endif - -#if FRAMEWORK_4_0_OR_ABOVE -// -// Allows partial trust applications (e.g. ASP.NET shared hosting) on .NET 4.0 to work -// given our implementation of ISerializable. -// -[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)] -#endif - -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// - -#if DOTNET -#if FRAMEWORK_4_5_OR_ABOVE -[assembly: AssemblyTitle("Apache log4net for .NET Framework 4.5")] -#elif FRAMEWORK_4_0_OR_ABOVE -#if CLIENT_PROFILE -[assembly: AssemblyTitle("Apache log4net for .NET Framework 4.0 Client Profile")] -#else -[assembly: AssemblyTitle("Apache log4net for .NET Framework 4.0")] -#endif // Client Profile -#elif FRAMEWORK_3_5_OR_ABOVE -#if CLIENT_PROFILE -[assembly: AssemblyTitle("Apache log4net for .NET Framework 3.5 Client Profile")] -#else -[assembly: AssemblyTitle("Apache log4net for .NET Framework 3.5")] -#endif // Client Profile -#else -[assembly: AssemblyTitle("Apache log4net for .NET Framework 2.0")] -#endif // FW 4.0 -#elif NETCF -[assembly: AssemblyTitle("Apache log4net for .NET Compact Framework 2.0")] -#elif MONO -#if FRAMEWORK_4_0_OR_ABOVE -[assembly: AssemblyTitle("Apache log4net for Mono 4.0")] -#elif FRAMEWORK_3_5_OR_ABOVE -[assembly: AssemblyTitle("Apache log4net for Mono 3.5")] -#else -[assembly: AssemblyTitle("Apache log4net for Mono 2.0")] -#endif // Mono subversions -#endif - -#if DEBUG -[assembly: AssemblyConfiguration("Debug")] -#else -[assembly: AssemblyConfiguration("Retail")] -#endif - -[assembly: AssemblyProduct("log4net")] -[assembly: AssemblyDefaultAlias("log4net")] -[assembly: AssemblyCulture("")] - diff --git a/src/log4net/AssemblyVersionInfo.cpp b/src/log4net/AssemblyVersionInfo.cpp deleted file mode 100644 index 93cc2c1e..00000000 --- a/src/log4net/AssemblyVersionInfo.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// 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 - -using namespace System::Reflection; -using namespace System::Runtime::CompilerServices; - -// -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the value or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly: AssemblyVersionAttribute("1.3.0.0")]; -[assembly: AssemblyInformationalVersionAttribute("1.3")]; - -#if !NETCF -[assembly: AssemblyFileVersionAttribute("1.3.0.0")] -#endif - -// -// Shared assembly settings -// - -[assembly: AssemblyCompany("The Apache Software Foundation")]; -[assembly: AssemblyCopyright("Copyright 2004-2015 The Apache Software Foundation.")]; -[assembly: AssemblyTrademark("Apache and Apache log4net are trademarks of The Apache Software Foundation")]; diff --git a/src/log4net/AssemblyVersionInfo.cs b/src/log4net/AssemblyVersionInfo.cs deleted file mode 100644 index 88e91161..00000000 --- a/src/log4net/AssemblyVersionInfo.cs +++ /dev/null @@ -1,44 +0,0 @@ -#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 - -// -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly: System.Reflection.AssemblyVersion("1.3.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.3")] - -#if !NETCF -[assembly: System.Reflection.AssemblyFileVersion("1.3.0.0")] -#endif - -// -// Shared assembly settings -// - -[assembly: System.Reflection.AssemblyCompany("The Apache Software Foundation")] -[assembly: System.Reflection.AssemblyCopyright("Copyright 2004-2015 The Apache Software Foundation.")] -[assembly: System.Reflection.AssemblyTrademark("Apache and Apache log4net are trademarks of The Apache Software Foundation")] diff --git a/src/log4net/AssemblyVersionInfo.js b/src/log4net/AssemblyVersionInfo.js deleted file mode 100644 index 59e26c2b..00000000 --- a/src/log4net/AssemblyVersionInfo.js +++ /dev/null @@ -1,47 +0,0 @@ -// -// 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. -// - - -// -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -// JScript.NET doesn't handle files with only custom attributes very well, adding -// an import functions as a workaround for this issue. -import System.Reflection; - -[assembly: AssemblyVersion("1.3.0.0")] -[assembly: AssemblyInformationalVersionAttribute("1.3")] - -@if (!@NETCF) -[assembly: AssemblyFileVersion("1.3.0.0")] -@end - -// -// Shared assembly settings -// - -[assembly: AssemblyCompany("The Apache Software Foundation")] -[assembly: AssemblyCopyright("Copyright 2004-2015 The Apache Software Foundation.")] -[assembly: AssemblyTrademark("Apache and Apache log4net are trademarks of The Apache Software Foundation")] diff --git a/src/log4net/AssemblyVersionInfo.vb b/src/log4net/AssemblyVersionInfo.vb deleted file mode 100644 index e8a3db2a..00000000 --- a/src/log4net/AssemblyVersionInfo.vb +++ /dev/null @@ -1,44 +0,0 @@ -#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. -' -#End Region - -' -' Version information for an assembly consists of the following four values: -' -' Major Version -' Minor Version -' Build Number -' Revision -' -' You can specify all the values or you can default the Revision and Build Numbers -' by using the '*' as shown below: - - - - -#If NOT NETCF Then - -#End If - -' -' Shared assembly settings -' - - - - diff --git a/src/log4net/Config/AliasRepositoryAttribute.cs b/src/log4net/Config/AliasRepositoryAttribute.cs deleted file mode 100644 index da83b77b..00000000 --- a/src/log4net/Config/AliasRepositoryAttribute.cs +++ /dev/null @@ -1,103 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for reading assembly attributes -#if !NETCF - -using System; - -namespace log4net.Config -{ - /// - /// Assembly level attribute that specifies a repository to alias to this assembly's repository. - /// - /// - /// - /// An assembly's logger repository is defined by its , - /// however this can be overridden by an assembly loaded before the target assembly. - /// - /// - /// An assembly can alias another assembly's repository to its repository by - /// specifying this attribute with the name of the target repository. - /// - /// - /// This attribute can only be specified on the assembly and may be used - /// as many times as necessary to alias all the required repositories. - /// - /// - /// Nicko Cadell - /// Gert Driesen - [AttributeUsage(AttributeTargets.Assembly,AllowMultiple=true)] - [Serializable] - public /*sealed*/ class AliasRepositoryAttribute : Attribute - { - // - // Class is not sealed because AliasDomainAttribute extends it while it is obsoleted - // - - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class with - /// the specified repository to alias to this assembly's repository. - /// - /// The repository to alias to this assemby's repository. - /// - /// - /// Initializes a new instance of the class with - /// the specified repository to alias to this assembly's repository. - /// - /// - public AliasRepositoryAttribute(string name) - { - Name = name; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the repository to alias to this assemby's repository. - /// - /// - /// The repository to alias to this assemby's repository. - /// - /// - /// - /// The name of the repository to alias to this assemby's repository. - /// - /// - public string Name - { - get { return m_name; } - set { m_name = value ; } - } - - #endregion Public Instance Properties - - #region Private Instance Fields - - private string m_name = null; - - #endregion Private Instance Fields - } -} - -#endif // !NETCF \ No newline at end of file diff --git a/src/log4net/Config/BasicConfigurator.cs b/src/log4net/Config/BasicConfigurator.cs deleted file mode 100644 index 8d617b4c..00000000 --- a/src/log4net/Config/BasicConfigurator.cs +++ /dev/null @@ -1,232 +0,0 @@ -#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 System.Collections; -using System.Reflection; - -using log4net.Appender; -using log4net.Layout; -using log4net.Util; -using log4net.Repository; -using log4net.Repository.Hierarchy; - -namespace log4net.Config -{ - /// - /// Use this class to quickly configure a . - /// - /// - /// - /// Allows very simple programmatic configuration of log4net. - /// - /// - /// Only one appender can be configured using this configurator. - /// The appender is set at the root of the hierarchy and all logging - /// events will be delivered to that appender. - /// - /// - /// Appenders can also implement the interface. Therefore - /// they would require that the method - /// be called after the appenders properties have been configured. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class BasicConfigurator - { - #region Private Static Fields - - /// - /// The fully qualified type of the BasicConfigurator class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(BasicConfigurator); - - #endregion Private Static Fields - - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Uses a private access modifier to prevent instantiation of this class. - /// - /// - private BasicConfigurator() - { - } - - #endregion Private Instance Constructors - - #region Public Static Methods - - /// - /// Initializes the log4net system with a default configuration. - /// - /// - /// - /// Initializes the log4net logging system using a - /// that will write to Console.Out. The log messages are - /// formatted using the layout object - /// with the - /// layout style. - /// - /// - static public ICollection Configure() - { - return BasicConfigurator.Configure(LogManager.GetRepository(Assembly.GetCallingAssembly())); - } - - /// - /// Initializes the log4net system using the specified appender. - /// - /// The appender to use to log all logging events. - /// - /// - /// Initializes the log4net system using the specified appender. - /// - /// - static public ICollection Configure(IAppender appender) - { - return Configure(new IAppender[] { appender }); - } - - /// - /// Initializes the log4net system using the specified appenders. - /// - /// The appenders to use to log all logging events. - /// - /// - /// Initializes the log4net system using the specified appenders. - /// - /// - static public ICollection Configure(params IAppender[] appenders) - { - ArrayList configurationMessages = new ArrayList(); - - ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly()); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigure(repository, appenders); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - /// - /// Initializes the with a default configuration. - /// - /// The repository to configure. - /// - /// - /// Initializes the specified repository using a - /// that will write to Console.Out. The log messages are - /// formatted using the layout object - /// with the - /// layout style. - /// - /// - static public ICollection Configure(ILoggerRepository repository) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - // Create the layout - PatternLayout layout = new PatternLayout(); - layout.ConversionPattern = PatternLayout.DetailConversionPattern; - layout.ActivateOptions(); - - // Create the appender - ConsoleAppender appender = new ConsoleAppender(); - appender.Layout = layout; - appender.ActivateOptions(); - - InternalConfigure(repository, appender); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - /// - /// Initializes the using the specified appender. - /// - /// The repository to configure. - /// The appender to use to log all logging events. - /// - /// - /// Initializes the using the specified appender. - /// - /// - static public ICollection Configure(ILoggerRepository repository, IAppender appender) - { - return Configure(repository, new IAppender[] { appender }); - } - - /// - /// Initializes the using the specified appenders. - /// - /// The repository to configure. - /// The appenders to use to log all logging events. - /// - /// - /// Initializes the using the specified appender. - /// - /// - static public ICollection Configure(ILoggerRepository repository, params IAppender[] appenders) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigure(repository, appenders); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - static private void InternalConfigure(ILoggerRepository repository, params IAppender[] appenders) - { - IBasicRepositoryConfigurator configurableRepository = repository as IBasicRepositoryConfigurator; - if (configurableRepository != null) - { - configurableRepository.Configure(appenders); - } - else - { - LogLog.Warn(declaringType, "BasicConfigurator: Repository [" + repository + "] does not support the BasicConfigurator"); - } - } - - #endregion Public Static Methods - } -} diff --git a/src/log4net/Config/ConfiguratorAttribute.cs b/src/log4net/Config/ConfiguratorAttribute.cs deleted file mode 100644 index e3da6745..00000000 --- a/src/log4net/Config/ConfiguratorAttribute.cs +++ /dev/null @@ -1,113 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for reading assembly attributes -#if !NETCF - -using System; -using System.Reflection; - -using log4net.Repository; - -namespace log4net.Config -{ - /// - /// Base class for all log4net configuration attributes. - /// - /// - /// This is an abstract class that must be extended by - /// specific configurators. This attribute allows the - /// configurator to be parameterized by an assembly level - /// attribute. - /// - /// Nicko Cadell - /// Gert Driesen - [AttributeUsage(AttributeTargets.Assembly)] - public abstract class ConfiguratorAttribute : Attribute, IComparable - { - private int m_priority = 0; - - /// - /// Constructor used by subclasses. - /// - /// the ordering priority for this configurator - /// - /// - /// The is used to order the configurator - /// attributes before they are invoked. Higher priority configurators are executed - /// before lower priority ones. - /// - /// - protected ConfiguratorAttribute(int priority) - { - m_priority = priority; - } - - /// - /// Configures the for the specified assembly. - /// - /// The assembly that this attribute was defined on. - /// The repository to configure. - /// - /// - /// Abstract method implemented by a subclass. When this method is called - /// the subclass should configure the . - /// - /// - public abstract void Configure(Assembly sourceAssembly, ILoggerRepository targetRepository); - - /// - /// Compare this instance to another ConfiguratorAttribute - /// - /// the object to compare to - /// see - /// - /// - /// Compares the priorities of the two instances. - /// Sorts by priority in descending order. Objects with the same priority are - /// randomly ordered. - /// - /// - public int CompareTo(object obj) - { - // Reference equals - if ((object)this == obj) - { - return 0; - } - - int result = -1; - - ConfiguratorAttribute target = obj as ConfiguratorAttribute; - if (target != null) - { - // Compare the priorities - result = target.m_priority.CompareTo(m_priority); - if (result == 0) - { - // Same priority, so have to provide some ordering - result = -1; - } - } - return result; - } - } -} - -#endif //!NETCF \ No newline at end of file diff --git a/src/log4net/Config/Log4NetConfigurationSectionHandler.cs b/src/log4net/Config/Log4NetConfigurationSectionHandler.cs deleted file mode 100644 index cc0bfee8..00000000 --- a/src/log4net/Config/Log4NetConfigurationSectionHandler.cs +++ /dev/null @@ -1,92 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for application .config files -#if !NETCF - -using System.Configuration; -using System.Xml; - -namespace log4net.Config -{ - /// - /// Class to register for the log4net section of the configuration file - /// - /// - /// The log4net section of the configuration file needs to have a section - /// handler registered. This is the section handler used. It simply returns - /// the XML element that is the root of the section. - /// - /// - /// Example of registering the log4net section handler : - /// - /// - /// - ///
    - /// - /// - /// log4net configuration XML goes here - /// - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class Log4NetConfigurationSectionHandler : IConfigurationSectionHandler - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public Log4NetConfigurationSectionHandler() - { - } - - #endregion Public Instance Constructors - - #region Implementation of IConfigurationSectionHandler - - /// - /// Parses the configuration section. - /// - /// The configuration settings in a corresponding parent configuration section. - /// The configuration context when called from the ASP.NET configuration system. Otherwise, this parameter is reserved and is a null reference. - /// The for the log4net section. - /// The for the log4net section. - /// - /// - /// Returns the containing the configuration data, - /// - /// - public object Create(object parent, object configContext, XmlNode section) - { - return section; - } - - #endregion Implementation of IConfigurationSectionHandler - } -} - -#endif // !NETCF \ No newline at end of file diff --git a/src/log4net/Config/PluginAttribute.cs b/src/log4net/Config/PluginAttribute.cs deleted file mode 100644 index 3533b253..00000000 --- a/src/log4net/Config/PluginAttribute.cs +++ /dev/null @@ -1,195 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for reading assembly attributes -#if !NETCF - -using System; -using System.Globalization; -using System.Reflection; - -using log4net.Core; -using log4net.Util; -using log4net.Plugin; - -namespace log4net.Config -{ - /// - /// Assembly level attribute that specifies a plugin to attach to - /// the repository. - /// - /// - /// - /// Specifies the type of a plugin to create and attach to the - /// assembly's repository. The plugin type must implement the - /// interface. - /// - /// - /// Nicko Cadell - /// Gert Driesen - [AttributeUsage(AttributeTargets.Assembly,AllowMultiple=true)] - [Serializable] - public sealed class PluginAttribute : Attribute, IPluginFactory - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class - /// with the specified type. - /// - /// The type name of plugin to create. - /// - /// - /// Create the attribute with the plugin type specified. - /// - /// - /// Where possible use the constructor that takes a . - /// - /// - public PluginAttribute(string typeName) - { - m_typeName = typeName; - } - - /// - /// Initializes a new instance of the class - /// with the specified type. - /// - /// The type of plugin to create. - /// - /// - /// Create the attribute with the plugin type specified. - /// - /// - public PluginAttribute(Type type) - { - m_type = type; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the type for the plugin. - /// - /// - /// The type for the plugin. - /// - /// - /// - /// The type for the plugin. - /// - /// - public Type Type - { - get { return m_type; } - set { m_type = value ; } - } - - /// - /// Gets or sets the type name for the plugin. - /// - /// - /// The type name for the plugin. - /// - /// - /// - /// The type name for the plugin. - /// - /// - /// Where possible use the property instead. - /// - /// - public string TypeName - { - get { return m_typeName; } - set { m_typeName = value ; } - } - - #endregion Public Instance Properties - - #region Implementation of IPluginFactory - - /// - /// Creates the plugin object defined by this attribute. - /// - /// - /// - /// Creates the instance of the object as - /// specified by this attribute. - /// - /// - /// The plugin object. - public IPlugin CreatePlugin() - { - Type pluginType = m_type; - if (m_type == null) - { - // Get the plugin object type from the string type name - pluginType = SystemInfo.GetTypeFromString(m_typeName, true, true); - } - - // Check that the type is a plugin - if (!(typeof(IPlugin).IsAssignableFrom(pluginType))) - { - throw new LogException("Plugin type [" + pluginType.FullName + "] does not implement the log4net.IPlugin interface"); - } - - // Create an instance of the plugin using the default constructor - IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); - - return plugin; - } - - #endregion Implementation of IPluginFactory - - #region Override implementation of Object - - /// - /// Returns a representation of the properties of this object. - /// - /// - /// - /// Overrides base class method to - /// return a representation of the properties of this object. - /// - /// - /// A representation of the properties of this object - override public string ToString() - { - if (m_type != null) - { - return "PluginAttribute[Type=" + m_type.FullName + "]"; - } - return "PluginAttribute[Type=" + m_typeName + "]"; - } - - #endregion Override implementation of Object - - #region Private Instance Fields - - private string m_typeName = null; - private Type m_type = null; - - #endregion Private Instance Fields - } -} - -#endif // !NETCF \ No newline at end of file diff --git a/src/log4net/Config/RepositoryAttribute.cs b/src/log4net/Config/RepositoryAttribute.cs deleted file mode 100644 index 56dd9822..00000000 --- a/src/log4net/Config/RepositoryAttribute.cs +++ /dev/null @@ -1,144 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for reading assembly attributes -#if !NETCF - -using System; - -namespace log4net.Config -{ - /// - /// Assembly level attribute that specifies the logging repository for the assembly. - /// - /// - /// - /// Assemblies are mapped to logging repository. This attribute specified - /// on the assembly controls - /// the configuration of the repository. The property specifies the name - /// of the repository that this assembly is a part of. The - /// specifies the type of the object - /// to create for the assembly. If this attribute is not specified or a - /// is not specified then the assembly will be part of the default shared logging repository. - /// - /// - /// This attribute can only be specified on the assembly and may only be used - /// once per assembly. - /// - /// - /// Nicko Cadell - /// Gert Driesen - [AttributeUsage(AttributeTargets.Assembly)] - [Serializable] - public /*sealed*/ class RepositoryAttribute : Attribute - { - // - // Class is not sealed because DomainAttribute extends it while it is obsoleted - // - - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Default constructor. - /// - /// - public RepositoryAttribute() - { - } - - /// - /// Initialize a new instance of the class - /// with the name of the repository. - /// - /// The name of the repository. - /// - /// - /// Initialize the attribute with the name for the assembly's repository. - /// - /// - public RepositoryAttribute(string name) - { - m_name = name; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the name of the logging repository. - /// - /// - /// The string name to use as the name of the repository associated with this - /// assembly. - /// - /// - /// - /// This value does not have to be unique. Several assemblies can share the - /// same repository. They will share the logging configuration of the repository. - /// - /// - public string Name - { - get { return m_name; } - set { m_name = value ; } - } - - /// - /// Gets or sets the type of repository to create for this assembly. - /// - /// - /// The type of repository to create for this assembly. - /// - /// - /// - /// The type of the repository to create for the assembly. - /// The type must implement the - /// interface. - /// - /// - /// This will be the type of repository created when - /// the repository is created. If multiple assemblies reference the - /// same repository then the repository is only created once using the - /// of the first assembly to call into the - /// repository. - /// - /// - public Type RepositoryType - { - get { return m_repositoryType; } - set { m_repositoryType = value ; } - } - - #endregion Public Instance Properties - - #region Private Instance Fields - - private string m_name = null; - private Type m_repositoryType = null; - - #endregion Private Instance Fields - } -} - -#endif // !NETCF \ No newline at end of file diff --git a/src/log4net/Config/SecurityContextProviderAttribute.cs b/src/log4net/Config/SecurityContextProviderAttribute.cs deleted file mode 100644 index c6f85572..00000000 --- a/src/log4net/Config/SecurityContextProviderAttribute.cs +++ /dev/null @@ -1,151 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for reading assembly attributes -#if !NETCF - -using System; -using System.Reflection; - -using log4net.Util; -using log4net.Repository; -using log4net.Core; - -namespace log4net.Config -{ - /// - /// Assembly level attribute to configure the . - /// - /// - /// - /// This attribute may only be used at the assembly scope and can only - /// be used once per assembly. - /// - /// - /// Use this attribute to configure the - /// without calling one of the - /// methods. - /// - /// - /// Nicko Cadell - [AttributeUsage(AttributeTargets.Assembly)] - [Serializable] - public sealed class SecurityContextProviderAttribute : ConfiguratorAttribute - { - #region Constructor - - /// - /// Construct provider attribute with type specified - /// - /// the type of the provider to use - /// - /// - /// The provider specified must subclass the - /// class. - /// - /// - public SecurityContextProviderAttribute(Type providerType) : base(100) /* configurator priority 100 to execute before the XmlConfigurator */ - { - m_providerType = providerType; - } - - #endregion - - #region Public Instance Properties - - /// - /// Gets or sets the type of the provider to use. - /// - /// - /// the type of the provider to use. - /// - /// - /// - /// The provider specified must subclass the - /// class. - /// - /// - public Type ProviderType - { - get { return m_providerType; } - set { m_providerType = value; } - } - - #endregion Public Instance Properties - - #region Override ConfiguratorAttribute - - /// - /// Configures the SecurityContextProvider - /// - /// The assembly that this attribute was defined on. - /// The repository to configure. - /// - /// - /// Creates a provider instance from the specified. - /// Sets this as the default security context provider . - /// - /// - override public void Configure(Assembly sourceAssembly, ILoggerRepository targetRepository) - { - if (m_providerType == null) - { - LogLog.Error(declaringType, "Attribute specified on assembly ["+sourceAssembly.FullName+"] with null ProviderType."); - } - else - { - LogLog.Debug(declaringType, "Creating provider of type ["+ m_providerType.FullName +"]"); - - SecurityContextProvider provider = Activator.CreateInstance(m_providerType) as SecurityContextProvider; - - if (provider == null) - { - LogLog.Error(declaringType, "Failed to create SecurityContextProvider instance of type ["+m_providerType.Name+"]."); - } - else - { - SecurityContextProvider.DefaultProvider = provider; - } - } - } - - #endregion - - #region Private Instance Fields - - private Type m_providerType = null; - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the SecurityContextProviderAttribute class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(SecurityContextProviderAttribute); - - #endregion Private Static Fields - } -} - -#endif // !NETCF \ No newline at end of file diff --git a/src/log4net/Config/XmlConfigurator.cs b/src/log4net/Config/XmlConfigurator.cs deleted file mode 100644 index 50650751..00000000 --- a/src/log4net/Config/XmlConfigurator.cs +++ /dev/null @@ -1,1120 +0,0 @@ -#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 System.Xml; -using System.Collections; -using System.IO; -using System.Reflection; -using System.Threading; -using System.Net; - -using log4net.Appender; -using log4net.Util; -using log4net.Repository; - -namespace log4net.Config -{ - /// - /// Use this class to initialize the log4net environment using an Xml tree. - /// - /// - /// - /// Configures a using an Xml tree. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class XmlConfigurator - { - #region Private Instance Constructors - - /// - /// Private constructor - /// - private XmlConfigurator() - { - } - - #endregion Protected Instance Constructors - - #region Configure static methods - -#if !NETCF - /// - /// Automatically configures the log4net system based on the - /// application's configuration settings. - /// - /// - /// - /// Each application has a configuration file. This has the - /// same name as the application with '.config' appended. - /// This file is XML and calling this function prompts the - /// configurator to look in that file for a section called - /// log4net that contains the configuration data. - /// - /// - /// To use this method to configure log4net you must specify - /// the section - /// handler for the log4net configuration section. See the - /// for an example. - /// - /// - /// -#else - /// - /// Automatically configures the log4net system based on the - /// application's configuration settings. - /// - /// - /// - /// Each application has a configuration file. This has the - /// same name as the application with '.config' appended. - /// This file is XML and calling this function prompts the - /// configurator to look in that file for a section called - /// log4net that contains the configuration data. - /// - /// -#endif - static public ICollection Configure() - { - return Configure(LogManager.GetRepository(Assembly.GetCallingAssembly())); - } - -#if !NETCF - /// - /// Automatically configures the using settings - /// stored in the application's configuration file. - /// - /// - /// - /// Each application has a configuration file. This has the - /// same name as the application with '.config' appended. - /// This file is XML and calling this function prompts the - /// configurator to look in that file for a section called - /// log4net that contains the configuration data. - /// - /// - /// To use this method to configure log4net you must specify - /// the section - /// handler for the log4net configuration section. See the - /// for an example. - /// - /// - /// The repository to configure. -#else - /// - /// Automatically configures the using settings - /// stored in the application's configuration file. - /// - /// - /// - /// Each application has a configuration file. This has the - /// same name as the application with '.config' appended. - /// This file is XML and calling this function prompts the - /// configurator to look in that file for a section called - /// log4net that contains the configuration data. - /// - /// - /// The repository to configure. -#endif - static public ICollection Configure(ILoggerRepository repository) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigure(repository); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - static private void InternalConfigure(ILoggerRepository repository) - { - LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using .config file section"); - - try - { - LogLog.Debug(declaringType, "Application config file is [" + SystemInfo.ConfigurationFileLocation + "]"); - } - catch - { - // ignore error - LogLog.Debug(declaringType, "Application config file location unknown"); - } - -#if NETCF - // No config file reading stuff. Just go straight for the file - Configure(repository, new FileInfo(SystemInfo.ConfigurationFileLocation)); -#else - try - { - XmlElement configElement = null; - configElement = System.Configuration.ConfigurationManager.GetSection("log4net") as XmlElement; - if (configElement == null) - { - // Failed to load the xml config using configuration settings handler - LogLog.Error(declaringType, "Failed to find configuration section 'log4net' in the application's .config file. Check your .config file for the and elements. The configuration section should look like:
    "); - } - else - { - // Configure using the xml loaded from the config file - InternalConfigureFromXml(repository, configElement); - } - } - catch(System.Configuration.ConfigurationException confEx) - { - if (confEx.BareMessage.IndexOf("Unrecognized element") >= 0) - { - // Looks like the XML file is not valid - LogLog.Error(declaringType, "Failed to parse config file. Check your .config file is well formed XML.", confEx); - } - else - { - // This exception is typically due to the assembly name not being correctly specified in the section type. - string configSectionStr = "
    "; - LogLog.Error(declaringType, "Failed to parse config file. Is the specified as: " + configSectionStr, confEx); - } - } -#endif - } - - /// - /// Configures log4net using a log4net element - /// - /// - /// - /// Loads the log4net configuration from the XML element - /// supplied as . - /// - /// - /// The element to parse. - static public ICollection Configure(XmlElement element) - { - ArrayList configurationMessages = new ArrayList(); - - ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly()); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigureFromXml(repository, element); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - /// - /// Configures the using the specified XML - /// element. - /// - /// - /// Loads the log4net configuration from the XML element - /// supplied as . - /// - /// The repository to configure. - /// The element to parse. - static public ICollection Configure(ILoggerRepository repository, XmlElement element) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using XML element"); - - InternalConfigureFromXml(repository, element); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - -#if !NETCF - /// - /// Configures log4net using the specified configuration file. - /// - /// The XML file to load the configuration from. - /// - /// - /// The configuration file must be valid XML. It must contain - /// at least one element called log4net that holds - /// the log4net configuration data. - /// - /// - /// The log4net configuration file can possible be specified in the application's - /// configuration file (either MyAppName.exe.config for a - /// normal application on Web.config for an ASP.NET application). - /// - /// - /// The first element matching <configuration> will be read as the - /// configuration. If this file is also a .NET .config file then you must specify - /// a configuration section for the log4net element otherwise .NET will - /// complain. Set the type for the section handler to , for example: - /// - /// - ///
    - /// - /// - /// - /// - /// The following example configures log4net using a configuration file, of which the - /// location is stored in the application's configuration file : - /// - /// - /// using log4net.Config; - /// using System.IO; - /// using System.Configuration; - /// - /// ... - /// - /// XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"])); - /// - /// - /// In the .config file, the path to the log4net can be specified like this : - /// - /// - /// - /// - /// - /// - /// - /// - /// -#else - /// - /// Configures log4net using the specified configuration file. - /// - /// The XML file to load the configuration from. - /// - /// - /// The configuration file must be valid XML. It must contain - /// at least one element called log4net that holds - /// the log4net configuration data. - /// - /// - /// The following example configures log4net using a configuration file, of which the - /// location is stored in the application's configuration file : - /// - /// - /// using log4net.Config; - /// using System.IO; - /// using System.Configuration; - /// - /// ... - /// - /// XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"])); - /// - /// - /// In the .config file, the path to the log4net can be specified like this : - /// - /// - /// - /// - /// - /// - /// - /// - /// -#endif - static public ICollection Configure(FileInfo configFile) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigure(LogManager.GetRepository(Assembly.GetCallingAssembly()), configFile); - } - - return configurationMessages; - } - - /// - /// Configures log4net using the specified configuration URI. - /// - /// A URI to load the XML configuration from. - /// - /// - /// The configuration data must be valid XML. It must contain - /// at least one element called log4net that holds - /// the log4net configuration data. - /// - /// - /// The must support the URI scheme specified. - /// - /// - static public ICollection Configure(Uri configUri) - { - ArrayList configurationMessages = new ArrayList(); - - ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly()); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigure(repository, configUri); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - /// - /// Configures log4net using the specified configuration data stream. - /// - /// A stream to load the XML configuration from. - /// - /// - /// The configuration data must be valid XML. It must contain - /// at least one element called log4net that holds - /// the log4net configuration data. - /// - /// - /// Note that this method will NOT close the stream parameter. - /// - /// - static public ICollection Configure(Stream configStream) - { - ArrayList configurationMessages = new ArrayList(); - - ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly()); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigure(repository, configStream); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - -#if !NETCF - - /// - /// Configures the using the specified configuration - /// file. - /// - /// The repository to configure. - /// The XML file to load the configuration from. - /// - /// - /// The configuration file must be valid XML. It must contain - /// at least one element called log4net that holds - /// the configuration data. - /// - /// - /// The log4net configuration file can possible be specified in the application's - /// configuration file (either MyAppName.exe.config for a - /// normal application on Web.config for an ASP.NET application). - /// - /// - /// The first element matching <configuration> will be read as the - /// configuration. If this file is also a .NET .config file then you must specify - /// a configuration section for the log4net element otherwise .NET will - /// complain. Set the type for the section handler to , for example: - /// - /// - ///
    - /// - /// - /// - /// - /// The following example configures log4net using a configuration file, of which the - /// location is stored in the application's configuration file : - /// - /// - /// using log4net.Config; - /// using System.IO; - /// using System.Configuration; - /// - /// ... - /// - /// XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"])); - /// - /// - /// In the .config file, the path to the log4net can be specified like this : - /// - /// - /// - /// - /// - /// - /// - /// - /// -#else - /// - /// Configures the using the specified configuration - /// file. - /// - /// The repository to configure. - /// The XML file to load the configuration from. - /// - /// - /// The configuration file must be valid XML. It must contain - /// at least one element called log4net that holds - /// the configuration data. - /// - /// - /// The following example configures log4net using a configuration file, of which the - /// location is stored in the application's configuration file : - /// - /// - /// using log4net.Config; - /// using System.IO; - /// using System.Configuration; - /// - /// ... - /// - /// XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"])); - /// - /// - /// In the .config file, the path to the log4net can be specified like this : - /// - /// - /// - /// - /// - /// - /// - /// - /// -#endif - static public ICollection Configure(ILoggerRepository repository, FileInfo configFile) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigure(repository, configFile); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - static private void InternalConfigure(ILoggerRepository repository, FileInfo configFile) - { - LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using file [" + configFile + "]"); - - if (configFile == null) - { - LogLog.Error(declaringType, "Configure called with null 'configFile' parameter"); - } - else - { - // Have to use File.Exists() rather than configFile.Exists() - // because configFile.Exists() caches the value, not what we want. - if (File.Exists(configFile.FullName)) - { - // Open the file for reading - FileStream fs = null; - - // Try hard to open the file - for(int retry = 5; --retry >= 0; ) - { - try - { - fs = configFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read); - break; - } - catch(IOException ex) - { - if (retry == 0) - { - LogLog.Error(declaringType, "Failed to open XML config file [" + configFile.Name + "]", ex); - - // The stream cannot be valid - fs = null; - } - System.Threading.Thread.Sleep(250); - } - } - - if (fs != null) - { - try - { - // Load the configuration from the stream - InternalConfigure(repository, fs); - } - finally - { - // Force the file closed whatever happens - fs.Close(); - } - } - } - else - { - LogLog.Debug(declaringType, "config file [" + configFile.FullName + "] not found. Configuration unchanged."); - } - } - } - - /// - /// Configures the using the specified configuration - /// URI. - /// - /// The repository to configure. - /// A URI to load the XML configuration from. - /// - /// - /// The configuration data must be valid XML. It must contain - /// at least one element called log4net that holds - /// the configuration data. - /// - /// - /// The must support the URI scheme specified. - /// - /// - static public ICollection Configure(ILoggerRepository repository, Uri configUri) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigure(repository, configUri); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - static private void InternalConfigure(ILoggerRepository repository, Uri configUri) - { - LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using URI ["+configUri+"]"); - - if (configUri == null) - { - LogLog.Error(declaringType, "Configure called with null 'configUri' parameter"); - } - else - { - if (configUri.IsFile) - { - // If URI is local file then call Configure with FileInfo - InternalConfigure(repository, new FileInfo(configUri.LocalPath)); - } - else - { - // NETCF dose not support WebClient - WebRequest configRequest = null; - - try - { - configRequest = WebRequest.Create(configUri); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Failed to create WebRequest for URI ["+configUri+"]", ex); - } - - if (configRequest != null) - { - // authentication may be required, set client to use default credentials - try - { - configRequest.Credentials = CredentialCache.DefaultCredentials; - } - catch - { - // ignore security exception - } - - try - { - WebResponse response = configRequest.GetResponse(); - if (response != null) - { - try - { - // Open stream on config URI - using(Stream configStream = response.GetResponseStream()) - { - InternalConfigure(repository, configStream); - } - } - finally - { - response.Close(); - } - } - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Failed to request config from URI ["+configUri+"]", ex); - } - } - } - } - } - - /// - /// Configures the using the specified configuration - /// file. - /// - /// The repository to configure. - /// The stream to load the XML configuration from. - /// - /// - /// The configuration data must be valid XML. It must contain - /// at least one element called log4net that holds - /// the configuration data. - /// - /// - /// Note that this method will NOT close the stream parameter. - /// - /// - static public ICollection Configure(ILoggerRepository repository, Stream configStream) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigure(repository, configStream); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - static private void InternalConfigure(ILoggerRepository repository, Stream configStream) - { - LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using stream"); - - if (configStream == null) - { - LogLog.Error(declaringType, "Configure called with null 'configStream' parameter"); - } - else - { - // Load the config file into a document - XmlDocument doc = new XmlDocument(); - try - { -#if (NETCF) - // Create a text reader for the file stream - XmlTextReader xmlReader = new XmlTextReader(configStream); -#else - // Allow the DTD to specify entity includes - XmlReaderSettings settings = new XmlReaderSettings(); - // .NET 4.0 warning CS0618: 'System.Xml.XmlReaderSettings.ProhibitDtd' - // is obsolete: 'Use XmlReaderSettings.DtdProcessing property instead.' -#if !FRAMEWORK_4_0_OR_ABOVE - settings.ProhibitDtd = false; -#else - settings.DtdProcessing = DtdProcessing.Parse; -#endif - - // Create a reader over the input stream - XmlReader xmlReader = XmlReader.Create(configStream, settings); -#endif - - // load the data into the document - doc.Load(xmlReader); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Error while loading XML configuration", ex); - - // The document is invalid - doc = null; - } - - if (doc != null) - { - LogLog.Debug(declaringType, "loading XML configuration"); - - // Configure using the 'log4net' element - XmlNodeList configNodeList = doc.GetElementsByTagName("log4net"); - if (configNodeList.Count == 0) - { - LogLog.Debug(declaringType, "XML configuration does not contain a element. Configuration Aborted."); - } - else if (configNodeList.Count > 1) - { - LogLog.Error(declaringType, "XML configuration contains [" + configNodeList.Count + "] elements. Only one is allowed. Configuration Aborted."); - } - else - { - InternalConfigureFromXml(repository, configNodeList[0] as XmlElement); - } - } - } - } - - #endregion Configure static methods - - #region ConfigureAndWatch static methods - -#if !NETCF - - /// - /// Configures log4net using the file specified, monitors the file for changes - /// and reloads the configuration if a change is detected. - /// - /// The XML file to load the configuration from. - /// - /// - /// The configuration file must be valid XML. It must contain - /// at least one element called log4net that holds - /// the configuration data. - /// - /// - /// The configuration file will be monitored using a - /// and depends on the behavior of that class. - /// - /// - /// For more information on how to configure log4net using - /// a separate configuration file, see . - /// - /// - /// - static public ICollection ConfigureAndWatch(FileInfo configFile) - { - ArrayList configurationMessages = new ArrayList(); - - ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly()); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigureAndWatch(repository, configFile); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - /// - /// Configures the using the file specified, - /// monitors the file for changes and reloads the configuration if a change - /// is detected. - /// - /// The repository to configure. - /// The XML file to load the configuration from. - /// - /// - /// The configuration file must be valid XML. It must contain - /// at least one element called log4net that holds - /// the configuration data. - /// - /// - /// The configuration file will be monitored using a - /// and depends on the behavior of that class. - /// - /// - /// For more information on how to configure log4net using - /// a separate configuration file, see . - /// - /// - /// - static public ICollection ConfigureAndWatch(ILoggerRepository repository, FileInfo configFile) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - InternalConfigureAndWatch(repository, configFile); - } - - repository.ConfigurationMessages = configurationMessages; - - return configurationMessages; - } - - static private void InternalConfigureAndWatch(ILoggerRepository repository, FileInfo configFile) - { - LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using file [" + configFile + "] watching for file updates"); - - if (configFile == null) - { - LogLog.Error(declaringType, "ConfigureAndWatch called with null 'configFile' parameter"); - } - else - { - // Configure log4net now - InternalConfigure(repository, configFile); - - try - { - lock (m_repositoryName2ConfigAndWatchHandler) - { - // support multiple repositories each having their own watcher - ConfigureAndWatchHandler handler = - (ConfigureAndWatchHandler)m_repositoryName2ConfigAndWatchHandler[configFile.FullName]; - - if (handler != null) - { - m_repositoryName2ConfigAndWatchHandler.Remove(configFile.FullName); - handler.Dispose(); - } - - // Create and start a watch handler that will reload the - // configuration whenever the config file is modified. - handler = new ConfigureAndWatchHandler(repository, configFile); - m_repositoryName2ConfigAndWatchHandler[configFile.FullName] = handler; - } - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Failed to initialize configuration file watcher for file ["+configFile.FullName+"]", ex); - } - } - } -#endif - - #endregion ConfigureAndWatch static methods - - #region ConfigureAndWatchHandler - -#if !NETCF - /// - /// Class used to watch config files. - /// - /// - /// - /// Uses the to monitor - /// changes to a specified file. Because multiple change notifications - /// may be raised when the file is modified, a timer is used to - /// compress the notifications into a single event. The timer - /// waits for time before delivering - /// the event notification. If any further - /// change notifications arrive while the timer is waiting it - /// is reset and waits again for to - /// elapse. - /// - /// - private sealed class ConfigureAndWatchHandler : IDisposable - { - /// - /// Holds the FileInfo used to configure the XmlConfigurator - /// - private FileInfo m_configFile; - - /// - /// Holds the repository being configured. - /// - private ILoggerRepository m_repository; - - /// - /// The timer used to compress the notification events. - /// - private Timer m_timer; - - /// - /// The default amount of time to wait after receiving notification - /// before reloading the config file. - /// - private const int TimeoutMillis = 500; - - /// - /// Watches file for changes. This object should be disposed when no longer - /// needed to free system handles on the watched resources. - /// - private FileSystemWatcher m_watcher; - - /// - /// Initializes a new instance of the class to - /// watch a specified config file used to configure a repository. - /// - /// The repository to configure. - /// The configuration file to watch. - /// - /// - /// Initializes a new instance of the class. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - public ConfigureAndWatchHandler(ILoggerRepository repository, FileInfo configFile) - { - m_repository = repository; - m_configFile = configFile; - - // Create a new FileSystemWatcher and set its properties. - m_watcher = new FileSystemWatcher(); - - m_watcher.Path = m_configFile.DirectoryName; - m_watcher.Filter = m_configFile.Name; - - // Set the notification filters - m_watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName; - - // Add event handlers. OnChanged will do for all event handlers that fire a FileSystemEventArgs - m_watcher.Changed += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged); - m_watcher.Created += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged); - m_watcher.Deleted += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged); - m_watcher.Renamed += new RenamedEventHandler(ConfigureAndWatchHandler_OnRenamed); - - // Begin watching. - m_watcher.EnableRaisingEvents = true; - - // Create the timer that will be used to deliver events. Set as disabled - m_timer = new Timer(new TimerCallback(OnWatchedFileChange), null, Timeout.Infinite, Timeout.Infinite); - } - - /// - /// Event handler used by . - /// - /// The firing the event. - /// The argument indicates the file that caused the event to be fired. - /// - /// - /// This handler reloads the configuration from the file when the event is fired. - /// - /// - private void ConfigureAndWatchHandler_OnChanged(object source, FileSystemEventArgs e) - { - LogLog.Debug(declaringType, "ConfigureAndWatchHandler: "+e.ChangeType+" [" + m_configFile.FullName + "]"); - - // Deliver the event in TimeoutMillis time - // timer will fire only once - m_timer.Change(TimeoutMillis, Timeout.Infinite); - } - - /// - /// Event handler used by . - /// - /// The firing the event. - /// The argument indicates the file that caused the event to be fired. - /// - /// - /// This handler reloads the configuration from the file when the event is fired. - /// - /// - private void ConfigureAndWatchHandler_OnRenamed(object source, RenamedEventArgs e) - { - LogLog.Debug(declaringType, "ConfigureAndWatchHandler: " + e.ChangeType + " [" + m_configFile.FullName + "]"); - - // Deliver the event in TimeoutMillis time - // timer will fire only once - m_timer.Change(TimeoutMillis, Timeout.Infinite); - } - - /// - /// Called by the timer when the configuration has been updated. - /// - /// null - private void OnWatchedFileChange(object state) - { - XmlConfigurator.InternalConfigure(m_repository, m_configFile); - } - - /// - /// Release the handles held by the watcher and timer. - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - public void Dispose() - { - m_watcher.EnableRaisingEvents = false; - m_watcher.Dispose(); - m_timer.Dispose(); - } - } -#endif - - #endregion ConfigureAndWatchHandler - - #region Private Static Methods - - /// - /// Configures the specified repository using a log4net element. - /// - /// The hierarchy to configure. - /// The element to parse. - /// - /// - /// Loads the log4net configuration from the XML element - /// supplied as . - /// - /// - /// This method is ultimately called by one of the Configure methods - /// to load the configuration from an . - /// - /// - static private void InternalConfigureFromXml(ILoggerRepository repository, XmlElement element) - { - if (element == null) - { - LogLog.Error(declaringType, "ConfigureFromXml called with null 'element' parameter"); - } - else if (repository == null) - { - LogLog.Error(declaringType, "ConfigureFromXml called with null 'repository' parameter"); - } - else - { - LogLog.Debug(declaringType, "Configuring Repository [" + repository.Name + "]"); - - IXmlRepositoryConfigurator configurableRepository = repository as IXmlRepositoryConfigurator; - if (configurableRepository == null) - { - LogLog.Warn(declaringType, "Repository [" + repository + "] does not support the XmlConfigurator"); - } - else - { - // Copy the xml data into the root of a new document - // this isolates the xml config data from the rest of - // the document - XmlDocument newDoc = new XmlDocument(); - XmlElement newElement = (XmlElement)newDoc.AppendChild(newDoc.ImportNode(element, true)); - - // Pass the configurator the config element - configurableRepository.Configure(newElement); - } - } - } - - #endregion Private Static Methods - - #region Private Static Fields - - /// - /// Maps repository names to ConfigAndWatchHandler instances to allow a particular - /// ConfigAndWatchHandler to dispose of its FileSystemWatcher when a repository is - /// reconfigured. - /// - private readonly static Hashtable m_repositoryName2ConfigAndWatchHandler = new Hashtable(); - - /// - /// The fully qualified type of the XmlConfigurator class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(XmlConfigurator); - - #endregion Private Static Fields - } -} - diff --git a/src/log4net/Config/XmlConfiguratorAttribute.cs b/src/log4net/Config/XmlConfiguratorAttribute.cs deleted file mode 100644 index ec389675..00000000 --- a/src/log4net/Config/XmlConfiguratorAttribute.cs +++ /dev/null @@ -1,458 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for reading assembly attributes -#if !NETCF - -using System; -using System.Collections; -using System.Reflection; -using System.IO; - -using log4net.Util; -using log4net.Repository; -using log4net.Repository.Hierarchy; - -namespace log4net.Config -{ - /// - /// Assembly level attribute to configure the . - /// - /// - /// - /// This attribute may only be used at the assembly scope and can only - /// be used once per assembly. - /// - /// - /// Use this attribute to configure the - /// without calling one of the - /// methods. - /// - /// - /// If neither of the or - /// properties are set the configuration is loaded from the application's .config file. - /// If set the property takes priority over the - /// property. The property - /// specifies a path to a file to load the config from. The path is relative to the - /// application's base directory; . - /// The property is used as a postfix to the assembly file name. - /// The config file must be located in the application's base directory; . - /// For example in a console application setting the to - /// config has the same effect as not specifying the or - /// properties. - /// - /// - /// The property can be set to cause the - /// to watch the configuration file for changes. - /// - /// - /// - /// Log4net will only look for assembly level configuration attributes once. - /// When using the log4net assembly level attributes to control the configuration - /// of log4net you must ensure that the first call to any of the - /// methods is made from the assembly with the configuration - /// attributes. - /// - /// - /// If you cannot guarantee the order in which log4net calls will be made from - /// different assemblies you must use programmatic configuration instead, i.e. - /// call the method directly. - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - [AttributeUsage(AttributeTargets.Assembly)] - [Serializable] - public /*sealed*/ class XmlConfiguratorAttribute : ConfiguratorAttribute - { - // - // Class is not sealed because DOMConfiguratorAttribute extends it while it is obsoleted - // - - /// - /// Default constructor - /// - /// - /// - /// Default constructor - /// - /// - public XmlConfiguratorAttribute() : base(0) /* configurator priority 0 */ - { - } - - #region Public Instance Properties - - /// - /// Gets or sets the filename of the configuration file. - /// - /// - /// The filename of the configuration file. - /// - /// - /// - /// If specified, this is the name of the configuration file to use with - /// the . This file path is relative to the - /// application base directory (). - /// - /// - /// The takes priority over the . - /// - /// - public string ConfigFile - { - get { return m_configFile; } - set { m_configFile = value; } - } - - /// - /// Gets or sets the extension of the configuration file. - /// - /// - /// The extension of the configuration file. - /// - /// - /// - /// If specified this is the extension for the configuration file. - /// The path to the config file is built by using the application - /// base directory (), - /// the assembly file name and the config file extension. - /// - /// - /// If the is set to MyExt then - /// possible config file names would be: MyConsoleApp.exe.MyExt or - /// MyClassLibrary.dll.MyExt. - /// - /// - /// The takes priority over the . - /// - /// - public string ConfigFileExtension - { - get { return m_configFileExtension; } - set { m_configFileExtension = value; } - } - - /// - /// Gets or sets a value indicating whether to watch the configuration file. - /// - /// - /// true if the configuration should be watched, false otherwise. - /// - /// - /// - /// If this flag is specified and set to true then the framework - /// will watch the configuration file and will reload the config each time - /// the file is modified. - /// - /// - /// The config file can only be watched if it is loaded from local disk. - /// In a No-Touch (Smart Client) deployment where the application is downloaded - /// from a web server the config file may not reside on the local disk - /// and therefore it may not be able to watch it. - /// - /// - public bool Watch - { - get { return m_configureAndWatch; } - set { m_configureAndWatch = value; } - } - - #endregion Public Instance Properties - - #region Override ConfiguratorAttribute - - /// - /// Configures the for the specified assembly. - /// - /// The assembly that this attribute was defined on. - /// The repository to configure. - /// - /// - /// Configure the repository using the . - /// The specified must extend the - /// class otherwise the will not be able to - /// configure it. - /// - /// - /// The does not extend . - override public void Configure(Assembly sourceAssembly, ILoggerRepository targetRepository) - { - IList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - string applicationBaseDirectory = null; - try - { - applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; - } - catch - { - // Ignore this exception because it is only thrown when ApplicationBaseDirectory is a file - // and the application does not have PathDiscovery permission - } - - if (applicationBaseDirectory == null || (new Uri(applicationBaseDirectory)).IsFile) - { - ConfigureFromFile(sourceAssembly, targetRepository); - } - else - { - ConfigureFromUri(sourceAssembly, targetRepository); - } - } - - targetRepository.ConfigurationMessages = configurationMessages; - } - - #endregion - - /// - /// Attempt to load configuration from the local file system - /// - /// The assembly that this attribute was defined on. - /// The repository to configure. - private void ConfigureFromFile(Assembly sourceAssembly, ILoggerRepository targetRepository) - { - // Work out the full path to the config file - string fullPath2ConfigFile = null; - - // Select the config file - if (m_configFile == null || m_configFile.Length == 0) - { - if (m_configFileExtension == null || m_configFileExtension.Length == 0) - { - // Use the default .config file for the AppDomain - try - { - fullPath2ConfigFile = SystemInfo.ConfigurationFileLocation; - } - catch(Exception ex) - { - LogLog.Error(declaringType, "XmlConfiguratorAttribute: Exception getting ConfigurationFileLocation. Must be able to resolve ConfigurationFileLocation when ConfigFile and ConfigFileExtension properties are not set.", ex); - } - } - else - { - // Force the extension to start with a '.' - if (m_configFileExtension[0] != '.') - { - m_configFileExtension = "." + m_configFileExtension; - } - - string applicationBaseDirectory = null; - try - { - applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Exception getting ApplicationBaseDirectory. Must be able to resolve ApplicationBaseDirectory and AssemblyFileName when ConfigFileExtension property is set.", ex); - } - - if (applicationBaseDirectory != null) - { - fullPath2ConfigFile = Path.Combine(applicationBaseDirectory, SystemInfo.AssemblyFileName(sourceAssembly) + m_configFileExtension); - } - } - } - else - { - string applicationBaseDirectory = null; - try - { - applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; - } - catch(Exception ex) - { - LogLog.Warn(declaringType, "Exception getting ApplicationBaseDirectory. ConfigFile property path ["+m_configFile+"] will be treated as an absolute path.", ex); - } - - if (applicationBaseDirectory != null) - { - // Just the base dir + the config file - fullPath2ConfigFile = Path.Combine(applicationBaseDirectory, m_configFile); - } - else - { - fullPath2ConfigFile = m_configFile; - } - } - - if (fullPath2ConfigFile != null) - { - ConfigureFromFile(targetRepository, new FileInfo(fullPath2ConfigFile)); - } - } - - /// - /// Configure the specified repository using a - /// - /// The repository to configure. - /// the FileInfo pointing to the config file - private void ConfigureFromFile(ILoggerRepository targetRepository, FileInfo configFile) - { - // Do we configure just once or do we configure and then watch? - if (m_configureAndWatch) - { - XmlConfigurator.ConfigureAndWatch(targetRepository, configFile); - } - else - { - XmlConfigurator.Configure(targetRepository, configFile); - } - } - - /// - /// Attempt to load configuration from a URI - /// - /// The assembly that this attribute was defined on. - /// The repository to configure. - private void ConfigureFromUri(Assembly sourceAssembly, ILoggerRepository targetRepository) - { - // Work out the full path to the config file - Uri fullPath2ConfigFile = null; - - // Select the config file - if (m_configFile == null || m_configFile.Length == 0) - { - if (m_configFileExtension == null || m_configFileExtension.Length == 0) - { - string systemConfigFilePath = null; - try - { - systemConfigFilePath = SystemInfo.ConfigurationFileLocation; - } - catch(Exception ex) - { - LogLog.Error(declaringType, "XmlConfiguratorAttribute: Exception getting ConfigurationFileLocation. Must be able to resolve ConfigurationFileLocation when ConfigFile and ConfigFileExtension properties are not set.", ex); - } - - if (systemConfigFilePath != null) - { - Uri systemConfigFileUri = new Uri(systemConfigFilePath); - - // Use the default .config file for the AppDomain - fullPath2ConfigFile = systemConfigFileUri; - } - } - else - { - // Force the extension to start with a '.' - if (m_configFileExtension[0] != '.') - { - m_configFileExtension = "." + m_configFileExtension; - } - - string systemConfigFilePath = null; - try - { - systemConfigFilePath = SystemInfo.ConfigurationFileLocation; - } - catch(Exception ex) - { - LogLog.Error(declaringType, "XmlConfiguratorAttribute: Exception getting ConfigurationFileLocation. Must be able to resolve ConfigurationFileLocation when the ConfigFile property are not set.", ex); - } - - if (systemConfigFilePath != null) - { - UriBuilder builder = new UriBuilder(new Uri(systemConfigFilePath)); - - // Remove the current extension from the systemConfigFileUri path - string path = builder.Path; - int startOfExtension = path.LastIndexOf("."); - if (startOfExtension >= 0) - { - path = path.Substring(0, startOfExtension); - } - path += m_configFileExtension; - - builder.Path = path; - fullPath2ConfigFile = builder.Uri; - } - } - } - else - { - string applicationBaseDirectory = null; - try - { - applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; - } - catch(Exception ex) - { - LogLog.Warn(declaringType, "Exception getting ApplicationBaseDirectory. ConfigFile property path ["+m_configFile+"] will be treated as an absolute URI.", ex); - } - - if (applicationBaseDirectory != null) - { - // Just the base dir + the config file - fullPath2ConfigFile = new Uri(new Uri(applicationBaseDirectory), m_configFile); - } - else - { - fullPath2ConfigFile = new Uri(m_configFile); - } - } - - if (fullPath2ConfigFile != null) - { - if (fullPath2ConfigFile.IsFile) - { - // The m_configFile could be an absolute local path, therefore we have to be - // prepared to switch back to using FileInfos here - ConfigureFromFile(targetRepository, new FileInfo(fullPath2ConfigFile.LocalPath)); - } - else - { - if (m_configureAndWatch) - { - LogLog.Warn(declaringType, "XmlConfiguratorAttribute: Unable to watch config file loaded from a URI"); - } - XmlConfigurator.Configure(targetRepository, fullPath2ConfigFile); - } - } - } - - #region Private Instance Fields - - private string m_configFile = null; - private string m_configFileExtension = null; - private bool m_configureAndWatch = false; - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the XmlConfiguratorAttribute class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(XmlConfiguratorAttribute); - - #endregion Private Static Fields - } -} - -#endif // !NETCF diff --git a/src/log4net/Core/CompactRepositorySelector.cs b/src/log4net/Core/CompactRepositorySelector.cs deleted file mode 100644 index dd46f6d5..00000000 --- a/src/log4net/Core/CompactRepositorySelector.cs +++ /dev/null @@ -1,357 +0,0 @@ -#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 System.Collections; -using System.Reflection; - -using log4net.Appender; -using log4net.Util; -using log4net.Repository; - - -namespace log4net.Core -{ - /// - /// The implementation of the interface suitable - /// for use with the compact framework - /// - /// - /// - /// This implementation is a simple - /// mapping between repository name and - /// object. - /// - /// - /// The .NET Compact Framework 1.0 does not support retrieving assembly - /// level attributes therefore unlike the DefaultRepositorySelector - /// this selector does not examine the calling assembly for attributes. - /// - /// - /// Nicko Cadell - public class CompactRepositorySelector : IRepositorySelector - { - #region Member Variables - - private const string DefaultRepositoryName = "log4net-default-repository"; - - private readonly Hashtable m_name2repositoryMap = new Hashtable(); - private readonly Type m_defaultRepositoryType; - - private event LoggerRepositoryCreationEventHandler m_loggerRepositoryCreatedEvent; - - #endregion - - #region Constructors - - /// - /// Create a new repository selector - /// - /// the type of the repositories to create, must implement - /// - /// - /// Create an new compact repository selector. - /// The default type for repositories must be specified, - /// an appropriate value would be . - /// - /// - /// throw if is null - /// throw if does not implement - public CompactRepositorySelector(Type defaultRepositoryType) - { - if (defaultRepositoryType == null) - { - throw new ArgumentNullException("defaultRepositoryType"); - } - - // Check that the type is a repository - if (! (typeof(ILoggerRepository).IsAssignableFrom(defaultRepositoryType)) ) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("defaultRepositoryType", (object)defaultRepositoryType, "Parameter: defaultRepositoryType, Value: ["+defaultRepositoryType+"] out of range. Argument must implement the ILoggerRepository interface"); - } - - m_defaultRepositoryType = defaultRepositoryType; - - LogLog.Debug(declaringType, "defaultRepositoryType ["+m_defaultRepositoryType+"]"); - } - - #endregion - - #region Implementation of IRepositorySelector - - /// - /// Get the for the specified assembly - /// - /// not used - /// The default - /// - /// - /// The argument is not used. This selector does not create a - /// separate repository for each assembly. - /// - /// - /// As a named repository is not specified the default repository is - /// returned. The default repository is named log4net-default-repository. - /// - /// - public ILoggerRepository GetRepository(Assembly assembly) - { - return CreateRepository(assembly, m_defaultRepositoryType); - } - - /// - /// Get the named - /// - /// the name of the repository to lookup - /// The named - /// - /// - /// Get the named . The default - /// repository is log4net-default-repository. Other repositories - /// must be created using the . - /// If the named repository does not exist an exception is thrown. - /// - /// - /// throw if is null - /// throw if the does not exist - public ILoggerRepository GetRepository(string repositoryName) - { - if (repositoryName == null) - { - throw new ArgumentNullException("repositoryName"); - } - - lock(this) - { - // Lookup in map - ILoggerRepository rep = m_name2repositoryMap[repositoryName] as ILoggerRepository; - if (rep == null) - { - throw new LogException("Repository ["+repositoryName+"] is NOT defined."); - } - return rep; - } - } - - /// - /// Create a new repository for the assembly specified - /// - /// not used - /// the type of repository to create, must implement - /// the repository created - /// - /// - /// The argument is not used. This selector does not create a - /// separate repository for each assembly. - /// - /// - /// If the is null then the - /// default repository type specified to the constructor is used. - /// - /// - /// As a named repository is not specified the default repository is - /// returned. The default repository is named log4net-default-repository. - /// - /// - public ILoggerRepository CreateRepository(Assembly assembly, Type repositoryType) - { - // If the type is not set then use the default type - if (repositoryType == null) - { - repositoryType = m_defaultRepositoryType; - } - - lock(this) - { - // This method should not throw if the default repository already exists. - - // First check that the repository does not exist - ILoggerRepository rep = m_name2repositoryMap[DefaultRepositoryName] as ILoggerRepository; - if (rep == null) - { - // Must create the repository - rep = CreateRepository(DefaultRepositoryName, repositoryType); - } - - return rep; - } - } - - /// - /// Create a new repository for the repository specified - /// - /// the repository to associate with the - /// the type of repository to create, must implement . - /// If this param is null then the default repository type is used. - /// the repository created - /// - /// - /// The created will be associated with the repository - /// specified such that a call to with the - /// same repository specified will return the same repository instance. - /// - /// - /// If the named repository already exists an exception will be thrown. - /// - /// - /// If is null then the default - /// repository type specified to the constructor is used. - /// - /// - /// throw if is null - /// throw if the already exists - public ILoggerRepository CreateRepository(string repositoryName, Type repositoryType) - { - if (repositoryName == null) - { - throw new ArgumentNullException("repositoryName"); - } - - // If the type is not set then use the default type - if (repositoryType == null) - { - repositoryType = m_defaultRepositoryType; - } - - lock(this) - { - ILoggerRepository rep = null; - - // First check that the repository does not exist - rep = m_name2repositoryMap[repositoryName] as ILoggerRepository; - if (rep != null) - { - throw new LogException("Repository ["+repositoryName+"] is already defined. Repositories cannot be redefined."); - } - else - { - LogLog.Debug(declaringType, "Creating repository ["+repositoryName+"] using type ["+repositoryType+"]"); - - // Call the no arg constructor for the repositoryType - rep = (ILoggerRepository)Activator.CreateInstance(repositoryType); - - // Set the name of the repository - rep.Name = repositoryName; - - // Store in map - m_name2repositoryMap[repositoryName] = rep; - - // Notify listeners that the repository has been created - OnLoggerRepositoryCreatedEvent(rep); - } - - return rep; - } - } - - /// - /// Test if a named repository exists - /// - /// the named repository to check - /// true if the repository exists - /// - /// - /// Test if a named repository exists. Use - /// to create a new repository and to retrieve - /// a repository. - /// - /// - public bool ExistsRepository(string repositoryName) - { - lock(this) - { - return m_name2repositoryMap.ContainsKey(repositoryName); - } - } - - /// - /// Gets a list of objects - /// - /// an array of all known objects - /// - /// - /// Gets an array of all of the repositories created by this selector. - /// - /// - public ILoggerRepository[] GetAllRepositories() - { - lock(this) - { - ICollection reps = m_name2repositoryMap.Values; - ILoggerRepository[] all = new ILoggerRepository[reps.Count]; - reps.CopyTo(all, 0); - return all; - } - } - - #endregion - - #region Private Static Fields - - /// - /// The fully qualified type of the CompactRepositorySelector class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(CompactRepositorySelector); - - #endregion Private Static Fields - - /// - /// Event to notify that a logger repository has been created. - /// - /// - /// Event to notify that a logger repository has been created. - /// - /// - /// - /// Event raised when a new repository is created. - /// The event source will be this selector. The event args will - /// be a which - /// holds the newly created . - /// - /// - public event LoggerRepositoryCreationEventHandler LoggerRepositoryCreatedEvent - { - add { m_loggerRepositoryCreatedEvent += value; } - remove { m_loggerRepositoryCreatedEvent -= value; } - } - - /// - /// Notify the registered listeners that the repository has been created - /// - /// The repository that has been created - /// - /// - /// Raises the LoggerRepositoryCreatedEvent - /// event. - /// - /// - protected virtual void OnLoggerRepositoryCreatedEvent(ILoggerRepository repository) - { - LoggerRepositoryCreationEventHandler handler = m_loggerRepositoryCreatedEvent; - if (handler != null) - { - handler(this, new LoggerRepositoryCreationEventArgs(repository)); - } - } - } -} diff --git a/src/log4net/Core/DefaultRepositorySelector.cs b/src/log4net/Core/DefaultRepositorySelector.cs deleted file mode 100644 index d374e5ee..00000000 --- a/src/log4net/Core/DefaultRepositorySelector.cs +++ /dev/null @@ -1,893 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for reading assembly attributes -// and uses the CompactRepositorySelector instead -#if !NETCF - -using System; -using System.Collections; -using System.Configuration; -using System.IO; -using System.Reflection; - -using log4net.Config; -using log4net.Util; -using log4net.Repository; - -namespace log4net.Core -{ - /// - /// The default implementation of the interface. - /// - /// - /// - /// Uses attributes defined on the calling assembly to determine how to - /// configure the hierarchy for the repository. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class DefaultRepositorySelector : IRepositorySelector - { - #region Public Events - - /// - /// Event to notify that a logger repository has been created. - /// - /// - /// Event to notify that a logger repository has been created. - /// - /// - /// - /// Event raised when a new repository is created. - /// The event source will be this selector. The event args will - /// be a which - /// holds the newly created . - /// - /// - public event LoggerRepositoryCreationEventHandler LoggerRepositoryCreatedEvent - { - add { m_loggerRepositoryCreatedEvent += value; } - remove { m_loggerRepositoryCreatedEvent -= value; } - } - - #endregion Public Events - - #region Public Instance Constructors - - /// - /// Creates a new repository selector. - /// - /// The type of the repositories to create, must implement - /// - /// - /// Create an new repository selector. - /// The default type for repositories must be specified, - /// an appropriate value would be . - /// - /// - /// is . - /// does not implement . - public DefaultRepositorySelector(Type defaultRepositoryType) - { - if (defaultRepositoryType == null) - { - throw new ArgumentNullException("defaultRepositoryType"); - } - - // Check that the type is a repository - if (! (typeof(ILoggerRepository).IsAssignableFrom(defaultRepositoryType)) ) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("defaultRepositoryType", defaultRepositoryType, "Parameter: defaultRepositoryType, Value: [" + defaultRepositoryType + "] out of range. Argument must implement the ILoggerRepository interface"); - } - - m_defaultRepositoryType = defaultRepositoryType; - - LogLog.Debug(declaringType, "defaultRepositoryType [" + m_defaultRepositoryType + "]"); - } - - #endregion Public Instance Constructors - - #region Implementation of IRepositorySelector - - /// - /// Gets the for the specified assembly. - /// - /// The assembly use to lookup the . - /// - /// - /// The type of the created and the repository - /// to create can be overridden by specifying the - /// attribute on the . - /// - /// - /// The default values are to use the - /// implementation of the interface and to use the - /// as the name of the repository. - /// - /// - /// The created will be automatically configured using - /// any attributes defined on - /// the . - /// - /// - /// The for the assembly - /// is . - public ILoggerRepository GetRepository(Assembly repositoryAssembly) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - return CreateRepository(repositoryAssembly, m_defaultRepositoryType); - } - - /// - /// Gets the for the specified repository. - /// - /// The repository to use to lookup the . - /// The for the specified repository. - /// - /// - /// Returns the named repository. If is null - /// a is thrown. If the repository - /// does not exist a is thrown. - /// - /// - /// Use to create a repository. - /// - /// - /// is . - /// does not exist. - public ILoggerRepository GetRepository(string repositoryName) - { - if (repositoryName == null) - { - throw new ArgumentNullException("repositoryName"); - } - - lock(this) - { - // Lookup in map - ILoggerRepository rep = m_name2repositoryMap[repositoryName] as ILoggerRepository; - if (rep == null) - { - throw new LogException("Repository [" + repositoryName + "] is NOT defined."); - } - return rep; - } - } - - /// - /// Create a new repository for the assembly specified - /// - /// the assembly to use to create the repository to associate with the . - /// The type of repository to create, must implement . - /// The repository created. - /// - /// - /// The created will be associated with the repository - /// specified such that a call to with the - /// same assembly specified will return the same repository instance. - /// - /// - /// The type of the created and - /// the repository to create can be overridden by specifying the - /// attribute on the - /// . The default values are to use the - /// implementation of the - /// interface and to use the - /// as the name of the repository. - /// - /// - /// The created will be automatically - /// configured using any - /// attributes defined on the . - /// - /// - /// If a repository for the already exists - /// that repository will be returned. An error will not be raised and that - /// repository may be of a different type to that specified in . - /// Also the attribute on the - /// assembly may be used to override the repository type specified in - /// . - /// - /// - /// is . - public ILoggerRepository CreateRepository(Assembly repositoryAssembly, Type repositoryType) - { - return CreateRepository(repositoryAssembly, repositoryType, DefaultRepositoryName, true); - } - - /// - /// Creates a new repository for the assembly specified. - /// - /// the assembly to use to create the repository to associate with the . - /// The type of repository to create, must implement . - /// The name to assign to the created repository - /// Set to true to read and apply the assembly attributes - /// The repository created. - /// - /// - /// The created will be associated with the repository - /// specified such that a call to with the - /// same assembly specified will return the same repository instance. - /// - /// - /// The type of the created and - /// the repository to create can be overridden by specifying the - /// attribute on the - /// . The default values are to use the - /// implementation of the - /// interface and to use the - /// as the name of the repository. - /// - /// - /// The created will be automatically - /// configured using any - /// attributes defined on the . - /// - /// - /// If a repository for the already exists - /// that repository will be returned. An error will not be raised and that - /// repository may be of a different type to that specified in . - /// Also the attribute on the - /// assembly may be used to override the repository type specified in - /// . - /// - /// - /// is . - public ILoggerRepository CreateRepository(Assembly repositoryAssembly, Type repositoryType, string repositoryName, bool readAssemblyAttributes) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - - // If the type is not set then use the default type - if (repositoryType == null) - { - repositoryType = m_defaultRepositoryType; - } - - lock(this) - { - // Lookup in map - ILoggerRepository rep = m_assembly2repositoryMap[repositoryAssembly] as ILoggerRepository; - if (rep == null) - { - // Not found, therefore create - LogLog.Debug(declaringType, "Creating repository for assembly [" + repositoryAssembly + "]"); - - // Must specify defaults - string actualRepositoryName = repositoryName; - Type actualRepositoryType = repositoryType; - - if (readAssemblyAttributes) - { - // Get the repository and type from the assembly attributes - GetInfoForAssembly(repositoryAssembly, ref actualRepositoryName, ref actualRepositoryType); - } - - LogLog.Debug(declaringType, "Assembly [" + repositoryAssembly + "] using repository [" + actualRepositoryName + "] and repository type [" + actualRepositoryType + "]"); - - // Lookup the repository in the map (as this may already be defined) - rep = m_name2repositoryMap[actualRepositoryName] as ILoggerRepository; - if (rep == null) - { - // Create the repository - rep = CreateRepository(actualRepositoryName, actualRepositoryType); - - if (readAssemblyAttributes) - { - try - { - // Look for aliasing attributes - LoadAliases(repositoryAssembly, rep); - - // Look for plugins defined on the assembly - LoadPlugins(repositoryAssembly, rep); - - // Configure the repository using the assembly attributes - ConfigureRepository(repositoryAssembly, rep); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Failed to configure repository [" + actualRepositoryName + "] from assembly attributes.", ex); - } - } - } - else - { - LogLog.Debug(declaringType, "repository [" + actualRepositoryName + "] already exists, using repository type [" + rep.GetType().FullName + "]"); - - if (readAssemblyAttributes) - { - try - { - // Look for plugins defined on the assembly - LoadPlugins(repositoryAssembly, rep); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Failed to configure repository [" + actualRepositoryName + "] from assembly attributes.", ex); - } - } - } - m_assembly2repositoryMap[repositoryAssembly] = rep; - } - return rep; - } - } - - /// - /// Creates a new repository for the specified repository. - /// - /// The repository to associate with the . - /// The type of repository to create, must implement . - /// If this param is then the default repository type is used. - /// The new repository. - /// - /// - /// The created will be associated with the repository - /// specified such that a call to with the - /// same repository specified will return the same repository instance. - /// - /// - /// is . - /// already exists. - public ILoggerRepository CreateRepository(string repositoryName, Type repositoryType) - { - if (repositoryName == null) - { - throw new ArgumentNullException("repositoryName"); - } - - // If the type is not set then use the default type - if (repositoryType == null) - { - repositoryType = m_defaultRepositoryType; - } - - lock(this) - { - ILoggerRepository rep = null; - - // First check that the repository does not exist - rep = m_name2repositoryMap[repositoryName] as ILoggerRepository; - if (rep != null) - { - throw new LogException("Repository [" + repositoryName + "] is already defined. Repositories cannot be redefined."); - } - else - { - // Lookup an alias before trying to create the new repository - ILoggerRepository aliasedRepository = m_alias2repositoryMap[repositoryName] as ILoggerRepository; - if (aliasedRepository != null) - { - // Found an alias - - // Check repository type - if (aliasedRepository.GetType() == repositoryType) - { - // Repository type is compatible - LogLog.Debug(declaringType, "Aliasing repository [" + repositoryName + "] to existing repository [" + aliasedRepository.Name + "]"); - rep = aliasedRepository; - - // Store in map - m_name2repositoryMap[repositoryName] = rep; - } - else - { - // Invalid repository type for alias - LogLog.Error(declaringType, "Failed to alias repository [" + repositoryName + "] to existing repository ["+aliasedRepository.Name+"]. Requested repository type ["+repositoryType.FullName+"] is not compatible with existing type [" + aliasedRepository.GetType().FullName + "]"); - - // We now drop through to create the repository without aliasing - } - } - - // If we could not find an alias - if (rep == null) - { - LogLog.Debug(declaringType, "Creating repository [" + repositoryName + "] using type [" + repositoryType + "]"); - - // Call the no arg constructor for the repositoryType - rep = (ILoggerRepository)Activator.CreateInstance(repositoryType); - - // Set the name of the repository - rep.Name = repositoryName; - - // Store in map - m_name2repositoryMap[repositoryName] = rep; - - // Notify listeners that the repository has been created - OnLoggerRepositoryCreatedEvent(rep); - } - } - - return rep; - } - } - - /// - /// Test if a named repository exists - /// - /// the named repository to check - /// true if the repository exists - /// - /// - /// Test if a named repository exists. Use - /// to create a new repository and to retrieve - /// a repository. - /// - /// - public bool ExistsRepository(string repositoryName) - { - lock(this) - { - return m_name2repositoryMap.ContainsKey(repositoryName); - } - } - - /// - /// Gets a list of objects - /// - /// an array of all known objects - /// - /// - /// Gets an array of all of the repositories created by this selector. - /// - /// - public ILoggerRepository[] GetAllRepositories() - { - lock(this) - { - ICollection reps = m_name2repositoryMap.Values; - ILoggerRepository[] all = new ILoggerRepository[reps.Count]; - reps.CopyTo(all, 0); - return all; - } - } - - #endregion Implementation of IRepositorySelector - - #region Public Instance Methods - - /// - /// Aliases a repository to an existing repository. - /// - /// The repository to alias. - /// The repository that the repository is aliased to. - /// - /// - /// The repository specified will be aliased to the repository when created. - /// The repository must not already exist. - /// - /// - /// When the repository is created it must utilize the same repository type as - /// the repository it is aliased to, otherwise the aliasing will fail. - /// - /// - /// - /// is . - /// -or- - /// is . - /// - public void AliasRepository(string repositoryAlias, ILoggerRepository repositoryTarget) - { - if (repositoryAlias == null) - { - throw new ArgumentNullException("repositoryAlias"); - } - if (repositoryTarget == null) - { - throw new ArgumentNullException("repositoryTarget"); - } - - lock(this) - { - // Check if the alias is already set - if (m_alias2repositoryMap.Contains(repositoryAlias)) - { - // Check if this is a duplicate of the current alias - if (repositoryTarget != ((ILoggerRepository)m_alias2repositoryMap[repositoryAlias])) - { - // Cannot redefine existing alias - throw new InvalidOperationException("Repository [" + repositoryAlias + "] is already aliased to repository [" + ((ILoggerRepository)m_alias2repositoryMap[repositoryAlias]).Name + "]. Aliases cannot be redefined."); - } - } - // Check if the alias is already mapped to a repository - else if (m_name2repositoryMap.Contains(repositoryAlias)) - { - // Check if this is a duplicate of the current mapping - if ( repositoryTarget != ((ILoggerRepository)m_name2repositoryMap[repositoryAlias]) ) - { - // Cannot define alias for already mapped repository - throw new InvalidOperationException("Repository [" + repositoryAlias + "] already exists and cannot be aliased to repository [" + repositoryTarget.Name + "]."); - } - } - else - { - // Set the alias - m_alias2repositoryMap[repositoryAlias] = repositoryTarget; - } - } - } - - #endregion Public Instance Methods - - #region Protected Instance Methods - - /// - /// Notifies the registered listeners that the repository has been created. - /// - /// The repository that has been created. - /// - /// - /// Raises the event. - /// - /// - protected virtual void OnLoggerRepositoryCreatedEvent(ILoggerRepository repository) - { - LoggerRepositoryCreationEventHandler handler = m_loggerRepositoryCreatedEvent; - if (handler != null) - { - handler(this, new LoggerRepositoryCreationEventArgs(repository)); - } - } - - #endregion Protected Instance Methods - - #region Private Instance Methods - - /// - /// Gets the repository name and repository type for the specified assembly. - /// - /// The assembly that has a . - /// in/out param to hold the repository name to use for the assembly, caller should set this to the default value before calling. - /// in/out param to hold the type of the repository to create for the assembly, caller should set this to the default value before calling. - /// is . - private void GetInfoForAssembly(Assembly assembly, ref string repositoryName, ref Type repositoryType) - { - if (assembly == null) - { - throw new ArgumentNullException("assembly"); - } - - try - { - LogLog.Debug(declaringType, "Assembly [" + assembly.FullName + "] Loaded From [" + SystemInfo.AssemblyLocationInfo(assembly) + "]"); - } - catch - { - // Ignore exception from debug call - } - - try - { - // Look for the RepositoryAttribute on the assembly - object[] repositoryAttributes = Attribute.GetCustomAttributes(assembly, typeof(log4net.Config.RepositoryAttribute), false); - if (repositoryAttributes == null || repositoryAttributes.Length == 0) - { - // This is not a problem, but its nice to know what is going on. - LogLog.Debug(declaringType, "Assembly [" + assembly + "] does not have a RepositoryAttribute specified."); - } - else - { - if (repositoryAttributes.Length > 1) - { - LogLog.Error(declaringType, "Assembly [" + assembly + "] has multiple log4net.Config.RepositoryAttribute assembly attributes. Only using first occurrence."); - } - - log4net.Config.RepositoryAttribute domAttr = repositoryAttributes[0] as log4net.Config.RepositoryAttribute; - - if (domAttr == null) - { - LogLog.Error(declaringType, "Assembly [" + assembly + "] has a RepositoryAttribute but it does not!."); - } - else - { - // If the Name property is set then override the default - if (domAttr.Name != null) - { - repositoryName = domAttr.Name; - } - - // If the RepositoryType property is set then override the default - if (domAttr.RepositoryType != null) - { - // Check that the type is a repository - if (typeof(ILoggerRepository).IsAssignableFrom(domAttr.RepositoryType)) - { - repositoryType = domAttr.RepositoryType; - } - else - { - LogLog.Error(declaringType, "DefaultRepositorySelector: Repository Type [" + domAttr.RepositoryType + "] must implement the ILoggerRepository interface."); - } - } - } - } - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Unhandled exception in GetInfoForAssembly", ex); - } - } - - /// - /// Configures the repository using information from the assembly. - /// - /// The assembly containing - /// attributes which define the configuration for the repository. - /// The repository to configure. - /// - /// is . - /// -or- - /// is . - /// - private void ConfigureRepository(Assembly assembly, ILoggerRepository repository) - { - if (assembly == null) - { - throw new ArgumentNullException("assembly"); - } - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - - // Look for the Configurator attributes (e.g. XmlConfiguratorAttribute) on the assembly - object[] configAttributes = Attribute.GetCustomAttributes(assembly, typeof(log4net.Config.ConfiguratorAttribute), false); - if (configAttributes != null && configAttributes.Length > 0) - { - // Sort the ConfiguratorAttributes in priority order - Array.Sort(configAttributes); - - // Delegate to the attribute the job of configuring the repository - foreach(log4net.Config.ConfiguratorAttribute configAttr in configAttributes) - { - if (configAttr != null) - { - try - { - configAttr.Configure(assembly, repository); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Exception calling ["+configAttr.GetType().FullName+"] .Configure method.", ex); - } - } - } - } - - if (repository.Name == DefaultRepositoryName) - { - // Try to configure the default repository using an AppSettings specified config file - // Do this even if the repository has been configured (or claims to be), this allows overriding - // of the default config files etc, if that is required. - - string repositoryConfigFile = SystemInfo.GetAppSetting("log4net.Config"); - if (repositoryConfigFile != null && repositoryConfigFile.Length > 0) - { - string applicationBaseDirectory = null; - try - { - applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; - } - catch(Exception ex) - { - LogLog.Warn(declaringType, "Exception getting ApplicationBaseDirectory. appSettings log4net.Config path ["+repositoryConfigFile+"] will be treated as an absolute URI", ex); - } - - string repositoryConfigFilePath = repositoryConfigFile; - if (applicationBaseDirectory != null) - { - repositoryConfigFilePath = Path.Combine(applicationBaseDirectory, repositoryConfigFile); - } - - // Determine whether to watch the file or not based on an app setting value: - bool watchRepositoryConfigFile = false; -#if !NETCF - Boolean.TryParse(SystemInfo.GetAppSetting("log4net.Config.Watch"), out watchRepositoryConfigFile); -#else - { - string watch = SystemInfo.GetAppSetting("log4net.Config.Watch"); - if (watch != null && watch.Length > 0) - { - try - { - watchRepositoryConfigFile = Boolean.Parse(watch); - } - catch (FormatException) - { - // simply not a Boolean - } - } - } -#endif - - if (watchRepositoryConfigFile) - { - // As we are going to watch the config file it is required to resolve it as a - // physical file system path pass that in a FileInfo object to the Configurator - FileInfo repositoryConfigFileInfo = null; - try - { - repositoryConfigFileInfo = new FileInfo(repositoryConfigFilePath); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "DefaultRepositorySelector: Exception while parsing log4net.Config file physical path [" + repositoryConfigFilePath + "]", ex); - } - try - { - LogLog.Debug(declaringType, "Loading and watching configuration for default repository from AppSettings specified Config path [" + repositoryConfigFilePath + "]"); - - XmlConfigurator.ConfigureAndWatch(repository, repositoryConfigFileInfo); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "DefaultRepositorySelector: Exception calling XmlConfigurator.ConfigureAndWatch method with ConfigFilePath [" + repositoryConfigFilePath + "]", ex); - } - } - else - { - // As we are not going to watch the config file it is easiest to just resolve it as a - // URI and pass that to the Configurator - Uri repositoryConfigUri = null; - try - { - repositoryConfigUri = new Uri(repositoryConfigFilePath); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Exception while parsing log4net.Config file path ["+repositoryConfigFile+"]", ex); - } - - if (repositoryConfigUri != null) - { - LogLog.Debug(declaringType, "Loading configuration for default repository from AppSettings specified Config URI ["+repositoryConfigUri.ToString()+"]"); - - try - { - // TODO: Support other types of configurator - XmlConfigurator.Configure(repository, repositoryConfigUri); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Exception calling XmlConfigurator.Configure method with ConfigUri ["+repositoryConfigUri+"]", ex); - } - } - } - } - } - } - - /// - /// Loads the attribute defined plugins on the assembly. - /// - /// The assembly that contains the attributes. - /// The repository to add the plugins to. - /// - /// is . - /// -or- - /// is . - /// - private void LoadPlugins(Assembly assembly, ILoggerRepository repository) - { - if (assembly == null) - { - throw new ArgumentNullException("assembly"); - } - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - - // Look for the PluginAttribute on the assembly - object[] configAttributes = Attribute.GetCustomAttributes(assembly, typeof(log4net.Config.PluginAttribute), false); - if (configAttributes != null && configAttributes.Length > 0) - { - foreach(log4net.Plugin.IPluginFactory configAttr in configAttributes) - { - try - { - // Create the plugin and add it to the repository - repository.PluginMap.Add(configAttr.CreatePlugin()); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Failed to create plugin. Attribute [" + configAttr.ToString() + "]", ex); - } - } - } - } - - /// - /// Loads the attribute defined aliases on the assembly. - /// - /// The assembly that contains the attributes. - /// The repository to alias to. - /// - /// is . - /// -or- - /// is . - /// - private void LoadAliases(Assembly assembly, ILoggerRepository repository) - { - if (assembly == null) - { - throw new ArgumentNullException("assembly"); - } - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - - // Look for the AliasRepositoryAttribute on the assembly - object[] configAttributes = Attribute.GetCustomAttributes(assembly, typeof(log4net.Config.AliasRepositoryAttribute), false); - if (configAttributes != null && configAttributes.Length > 0) - { - foreach(log4net.Config.AliasRepositoryAttribute configAttr in configAttributes) - { - try - { - AliasRepository(configAttr.Name, repository); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Failed to alias repository [" + configAttr.Name + "]", ex); - } - } - } - } - - #endregion Private Instance Methods - - #region Private Static Fields - - /// - /// The fully qualified type of the DefaultRepositorySelector class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(DefaultRepositorySelector); - - private const string DefaultRepositoryName = "log4net-default-repository"; - - #endregion Private Static Fields - - #region Private Instance Fields - - private readonly Hashtable m_name2repositoryMap = new Hashtable(); - private readonly Hashtable m_assembly2repositoryMap = new Hashtable(); - private readonly Hashtable m_alias2repositoryMap = new Hashtable(); - private readonly Type m_defaultRepositoryType; - - private event LoggerRepositoryCreationEventHandler m_loggerRepositoryCreatedEvent; - - #endregion Private Instance Fields - } -} - -#endif // !NETCF diff --git a/src/log4net/Core/ErrorCode.cs b/src/log4net/Core/ErrorCode.cs deleted file mode 100644 index 9107a249..00000000 --- a/src/log4net/Core/ErrorCode.cs +++ /dev/null @@ -1,70 +0,0 @@ -#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; - -namespace log4net.Core -{ - /// - /// Defined error codes that can be passed to the method. - /// - /// - /// - /// Values passed to the method. - /// - /// - /// Nicko Cadell - public enum ErrorCode : int - { - /// - /// A general error - /// - GenericFailure = 0, - - /// - /// Error while writing output - /// - WriteFailure, - - /// - /// Failed to flush file - /// - FlushFailure, - - /// - /// Failed to close file - /// - CloseFailure, - - /// - /// Unable to open output file - /// - FileOpenFailure, - - /// - /// No layout specified - /// - MissingLayout, - - /// - /// Failed to parse address - /// - AddressParseFailure - } -} diff --git a/src/log4net/Core/ExceptionEvaluator.cs b/src/log4net/Core/ExceptionEvaluator.cs deleted file mode 100644 index 1b462f09..00000000 --- a/src/log4net/Core/ExceptionEvaluator.cs +++ /dev/null @@ -1,130 +0,0 @@ -#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; - -namespace log4net.Core -{ - /// - /// An evaluator that triggers on an Exception type - /// - /// - /// - /// This evaluator will trigger if the type of the Exception - /// passed to - /// is equal to a Type in . /// - /// - /// - /// Drew Schaeffer - public class ExceptionEvaluator : ITriggeringEventEvaluator - { - /// - /// The type that causes the trigger to fire. - /// - private Type m_type; - - /// - /// Causes subclasses of to cause the trigger to fire. - /// - private bool m_triggerOnSubclass; - - /// - /// Default ctor to allow dynamic creation through a configurator. - /// - public ExceptionEvaluator() - { - // empty - } - - /// - /// Constructs an evaluator and initializes to trigger on - /// - /// the type that triggers this evaluator. - /// If true, this evaluator will trigger on subclasses of . - public ExceptionEvaluator(Type exType, bool triggerOnSubClass) - { - if (exType == null) - { - throw new ArgumentNullException("exType"); - } - - m_type = exType; - m_triggerOnSubclass = triggerOnSubClass; - } - - /// - /// The type that triggers this evaluator. - /// - public Type ExceptionType - { - get { return m_type; } - set { m_type = value; } - } - - /// - /// If true, this evaluator will trigger on subclasses of . - /// - public bool TriggerOnSubclass - { - get { return m_triggerOnSubclass; } - set { m_triggerOnSubclass = value; } - } - - #region ITriggeringEventEvaluator Members - - /// - /// Is this the triggering event? - /// - /// The event to check - /// This method returns true, if the logging event Exception - /// Type is . - /// Otherwise it returns false - /// - /// - /// This evaluator will trigger if the Exception Type of the event - /// passed to - /// is . - /// - /// - public bool IsTriggeringEvent(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - if (m_triggerOnSubclass && loggingEvent.ExceptionObject != null) - { - // check if loggingEvent.ExceptionObject is of type ExceptionType or subclass of ExceptionType - Type exceptionObjectType = loggingEvent.ExceptionObject.GetType(); - return exceptionObjectType == m_type || exceptionObjectType.IsSubclassOf(m_type); - } - else if (!m_triggerOnSubclass && loggingEvent.ExceptionObject != null) - { // check if loggingEvent.ExceptionObject is of type ExceptionType - return loggingEvent.ExceptionObject.GetType() == m_type; - } - else - { // loggingEvent.ExceptionObject is null - return false; - } - } - - #endregion - } -} diff --git a/src/log4net/Core/IAppenderAttachable.cs b/src/log4net/Core/IAppenderAttachable.cs deleted file mode 100644 index 9c350c1f..00000000 --- a/src/log4net/Core/IAppenderAttachable.cs +++ /dev/null @@ -1,121 +0,0 @@ -#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.Appender; - -namespace log4net.Core -{ - /// - /// Interface for attaching appenders to objects. - /// - /// - /// - /// Interface for attaching, removing and retrieving appenders. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IAppenderAttachable - { - /// - /// Attaches an appender. - /// - /// The appender to add. - /// - /// - /// Add the specified appender. The implementation may - /// choose to allow or deny duplicate appenders. - /// - /// - void AddAppender(IAppender appender); - - /// - /// Gets all attached appenders. - /// - /// - /// A collection of attached appenders. - /// - /// - /// - /// Gets a collection of attached appenders. - /// If there are no attached appenders the - /// implementation should return an empty - /// collection rather than null. - /// - /// - AppenderCollection Appenders {get;} - - /// - /// Gets an attached appender with the specified name. - /// - /// The name of the appender to get. - /// - /// The appender with the name specified, or null if no appender with the - /// specified name is found. - /// - /// - /// - /// Returns an attached appender with the specified. - /// If no appender with the specified name is found null will be - /// returned. - /// - /// - IAppender GetAppender(string name); - - /// - /// Removes all attached appenders. - /// - /// - /// - /// Removes and closes all attached appenders - /// - /// - void RemoveAllAppenders(); - - /// - /// Removes the specified appender from the list of attached appenders. - /// - /// The appender to remove. - /// The appender removed from the list - /// - /// - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - /// - IAppender RemoveAppender(IAppender appender); - - /// - /// Removes the appender with the specified name from the list of appenders. - /// - /// The name of the appender to remove. - /// The appender removed from the list - /// - /// - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - /// - IAppender RemoveAppender(string name); - } -} diff --git a/src/log4net/Core/IErrorHandler.cs b/src/log4net/Core/IErrorHandler.cs deleted file mode 100644 index 763e5186..00000000 --- a/src/log4net/Core/IErrorHandler.cs +++ /dev/null @@ -1,75 +0,0 @@ -#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; - -namespace log4net.Core -{ - /// - /// Appenders may delegate their error handling to an . - /// - /// - /// - /// Error handling is a particularly tedious to get right because by - /// definition errors are hard to predict and to reproduce. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IErrorHandler - { - /// - /// Handles the error and information about the error condition is passed as - /// a parameter. - /// - /// The message associated with the error. - /// The that was thrown when the error occurred. - /// The error code associated with the error. - /// - /// - /// Handles the error and information about the error condition is passed as - /// a parameter. - /// - /// - void Error(string message, Exception e, ErrorCode errorCode); - - /// - /// Prints the error message passed as a parameter. - /// - /// The message associated with the error. - /// The that was thrown when the error occurred. - /// - /// - /// See . - /// - /// - void Error(string message, Exception e); - - /// - /// Prints the error message passed as a parameter. - /// - /// The message associated with the error. - /// - /// - /// See . - /// - /// - void Error(string message); - } -} diff --git a/src/log4net/Core/IFixingRequired.cs b/src/log4net/Core/IFixingRequired.cs deleted file mode 100644 index 9f05b145..00000000 --- a/src/log4net/Core/IFixingRequired.cs +++ /dev/null @@ -1,58 +0,0 @@ -#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; - -namespace log4net.Core -{ - /// - /// Interface for objects that require fixing. - /// - /// - /// - /// Interface that indicates that the object requires fixing before it - /// can be taken outside the context of the appender's - /// method. - /// - /// - /// When objects that implement this interface are stored - /// in the context properties maps - /// and - /// are fixed - /// (see ) the - /// method will be called. - /// - /// - /// Nicko Cadell - public interface IFixingRequired - { - /// - /// Get a portable version of this object - /// - /// the portable instance of this object - /// - /// - /// Get a portable instance object that represents the current - /// state of this object. The portable object can be stored - /// and logged from any thread with identical results. - /// - /// - object GetFixedObject(); - } -} diff --git a/src/log4net/Core/ILogger.cs b/src/log4net/Core/ILogger.cs deleted file mode 100644 index bbb152c2..00000000 --- a/src/log4net/Core/ILogger.cs +++ /dev/null @@ -1,115 +0,0 @@ -#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.Repository; - -namespace log4net.Core -{ - /// - /// Interface that all loggers implement - /// - /// - /// - /// This interface supports logging events and testing if a level - /// is enabled for logging. - /// - /// - /// These methods will not throw exceptions. Note to implementor, ensure - /// that the implementation of these methods cannot allow an exception - /// to be thrown to the caller. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface ILogger - { - /// - /// Gets the name of the logger. - /// - /// - /// The name of the logger. - /// - /// - /// - /// The name of this logger - /// - /// - string Name { get; } - - /// - /// This generic form is intended to be used by wrappers. - /// - /// The declaring type of the method that is - /// the stack boundary into the logging system for this call. - /// The level of the message to be logged. - /// The message object to log. - /// the exception to log, including its stack trace. Pass null to not log an exception. - /// - /// - /// Generates a logging event for the specified using - /// the and . - /// - /// - void Log(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception); - - /// - /// This is the most generic printing method that is intended to be used - /// by wrappers. - /// - /// The event being logged. - /// - /// - /// Logs the specified logging event through this logger. - /// - /// - void Log(LoggingEvent logEvent); - - /// - /// Checks if this logger is enabled for a given passed as parameter. - /// - /// The level to check. - /// - /// true if this logger is enabled for level, otherwise false. - /// - /// - /// - /// Test if this logger is going to log events of the specified . - /// - /// - bool IsEnabledFor(Level level); - - /// - /// Gets the where this - /// Logger instance is attached to. - /// - /// - /// The that this logger belongs to. - /// - /// - /// - /// Gets the where this - /// Logger instance is attached to. - /// - /// - ILoggerRepository Repository { get; } - } -} diff --git a/src/log4net/Core/ILoggerWrapper.cs b/src/log4net/Core/ILoggerWrapper.cs deleted file mode 100644 index 735e3686..00000000 --- a/src/log4net/Core/ILoggerWrapper.cs +++ /dev/null @@ -1,59 +0,0 @@ -#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; -using log4net.Core; -using log4net.Repository; - -namespace log4net.Core -{ - /// - /// Base interface for all wrappers - /// - /// - /// - /// Base interface for all wrappers. - /// - /// - /// All wrappers must implement this interface. - /// - /// - /// Nicko Cadell - public interface ILoggerWrapper - { - /// - /// Get the implementation behind this wrapper object. - /// - /// - /// The object that in implementing this object. - /// - /// - /// - /// The object that in implementing this - /// object. The Logger object may not - /// be the same object as this object because of logger decorators. - /// This gets the actual underlying objects that is used to process - /// the log events. - /// - /// - ILogger Logger { get; } - } -} diff --git a/src/log4net/Core/IOptionHandler.cs b/src/log4net/Core/IOptionHandler.cs deleted file mode 100644 index cdc46820..00000000 --- a/src/log4net/Core/IOptionHandler.cs +++ /dev/null @@ -1,58 +0,0 @@ -#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; - -namespace log4net.Core -{ - /// - /// Interface used to delay activate a configured object. - /// - /// - /// - /// This allows an object to defer activation of its options until all - /// options have been set. This is required for components which have - /// related options that remain ambiguous until all are set. - /// - /// - /// If a component implements this interface then the method - /// must be called by the container after its all the configured properties have been set - /// and before the component can be used. - /// - /// - /// Nicko Cadell - public interface IOptionHandler - { - /// - /// Activate the options that were previously set with calls to properties. - /// - /// - /// - /// This allows an object to defer activation of its options until all - /// options have been set. This is required for components which have - /// related options that remain ambiguous until all are set. - /// - /// - /// If a component implements this interface then this method must be called - /// after its properties have been set before the component can be used. - /// - /// - void ActivateOptions(); - } -} diff --git a/src/log4net/Core/IRepositorySelector.cs b/src/log4net/Core/IRepositorySelector.cs deleted file mode 100644 index 55e393a3..00000000 --- a/src/log4net/Core/IRepositorySelector.cs +++ /dev/null @@ -1,213 +0,0 @@ -#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 System.Reflection; - -using log4net.Repository; - -namespace log4net.Core -{ - #region LoggerRepositoryCreationEvent - - /// - /// Delegate used to handle logger repository creation event notifications - /// - /// The which created the repository. - /// The event args - /// that holds the instance that has been created. - /// - /// - /// Delegate used to handle logger repository creation event notifications. - /// - /// - public delegate void LoggerRepositoryCreationEventHandler(object sender, LoggerRepositoryCreationEventArgs e); - - /// - /// Provides data for the event. - /// - /// - /// - /// A - /// event is raised every time a is created. - /// - /// - public class LoggerRepositoryCreationEventArgs : EventArgs - { - /// - /// The created - /// - private ILoggerRepository m_repository; - - /// - /// Construct instance using specified - /// - /// the that has been created - /// - /// - /// Construct instance using specified - /// - /// - public LoggerRepositoryCreationEventArgs(ILoggerRepository repository) - { - m_repository = repository; - } - - /// - /// The that has been created - /// - /// - /// The that has been created - /// - /// - /// - /// The that has been created - /// - /// - public ILoggerRepository LoggerRepository - { - get { return m_repository; } - } - } - - #endregion - - /// - /// Interface used by the to select the . - /// - /// - /// - /// The uses a - /// to specify the policy for selecting the correct - /// to return to the caller. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IRepositorySelector - { - /// - /// Gets the for the specified assembly. - /// - /// The assembly to use to lookup to the - /// The for the assembly. - /// - /// - /// Gets the for the specified assembly. - /// - /// - /// How the association between and - /// is made is not defined. The implementation may choose any method for - /// this association. The results of this method must be repeatable, i.e. - /// when called again with the same arguments the result must be the - /// save value. - /// - /// - ILoggerRepository GetRepository(Assembly assembly); - - /// - /// Gets the named . - /// - /// The name to use to lookup to the . - /// The named - /// - /// Lookup a named . This is the repository created by - /// calling . - /// - ILoggerRepository GetRepository(string repositoryName); - - /// - /// Creates a new repository for the assembly specified. - /// - /// The assembly to use to create the domain to associate with the . - /// The type of repository to create, must implement . - /// The repository created. - /// - /// - /// The created will be associated with the domain - /// specified such that a call to with the - /// same assembly specified will return the same repository instance. - /// - /// - /// How the association between and - /// is made is not defined. The implementation may choose any method for - /// this association. - /// - /// - ILoggerRepository CreateRepository(Assembly assembly, Type repositoryType); - - /// - /// Creates a new repository with the name specified. - /// - /// The name to associate with the . - /// The type of repository to create, must implement . - /// The repository created. - /// - /// - /// The created will be associated with the name - /// specified such that a call to with the - /// same name will return the same repository instance. - /// - /// - ILoggerRepository CreateRepository(string repositoryName, Type repositoryType); - - /// - /// Test if a named repository exists - /// - /// the named repository to check - /// true if the repository exists - /// - /// - /// Test if a named repository exists. Use - /// to create a new repository and to retrieve - /// a repository. - /// - /// - bool ExistsRepository(string repositoryName); - - /// - /// Gets an array of all currently defined repositories. - /// - /// - /// An array of the instances created by - /// this . - /// - /// - /// Gets an array of all of the repositories created by this selector. - /// - /// - ILoggerRepository[] GetAllRepositories(); - - /// - /// Event to notify that a logger repository has been created. - /// - /// - /// Event to notify that a logger repository has been created. - /// - /// - /// - /// Event raised when a new repository is created. - /// The event source will be this selector. The event args will - /// be a which - /// holds the newly created . - /// - /// - event LoggerRepositoryCreationEventHandler LoggerRepositoryCreatedEvent; - } -} diff --git a/src/log4net/Core/ITriggeringEventEvaluator.cs b/src/log4net/Core/ITriggeringEventEvaluator.cs deleted file mode 100644 index baa7536a..00000000 --- a/src/log4net/Core/ITriggeringEventEvaluator.cs +++ /dev/null @@ -1,51 +0,0 @@ -#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; - -namespace log4net.Core -{ - /// - /// Test if an triggers an action - /// - /// - /// - /// Implementations of this interface allow certain appenders to decide - /// when to perform an appender specific action. - /// - /// - /// The action or behavior triggered is defined by the implementation. - /// - /// - /// Nicko Cadell - public interface ITriggeringEventEvaluator - { - /// - /// Test if this event triggers the action - /// - /// The event to check - /// true if this event triggers the action, otherwise false - /// - /// - /// Return true if this event triggers the action - /// - /// - bool IsTriggeringEvent(LoggingEvent loggingEvent); - } -} diff --git a/src/log4net/Core/Level.cs b/src/log4net/Core/Level.cs deleted file mode 100644 index 40a6ad22..00000000 --- a/src/log4net/Core/Level.cs +++ /dev/null @@ -1,611 +0,0 @@ -#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 System.Collections; - -namespace log4net.Core -{ - /// - /// Defines the default set of levels recognized by the system. - /// - /// - /// - /// Each has an associated . - /// - /// - /// Levels have a numeric that defines the relative - /// ordering between levels. Two Levels with the same - /// are deemed to be equivalent. - /// - /// - /// The levels that are recognized by log4net are set for each - /// and each repository can have different levels defined. The levels are stored - /// in the on the repository. Levels are - /// looked up by name from the . - /// - /// - /// When logging at level INFO the actual level used is not but - /// the value of LoggerRepository.LevelMap["INFO"]. The default value for this is - /// , but this can be changed by reconfiguring the level map. - /// - /// - /// Each level has a in addition to its . The - /// is the string that is written into the output log. By default - /// the display name is the same as the level name, but this can be used to alias levels - /// or to localize the log output. - /// - /// - /// Some of the predefined levels recognized by the system are: - /// - /// - /// - /// . - /// - /// - /// . - /// - /// - /// . - /// - /// - /// . - /// - /// - /// . - /// - /// - /// . - /// - /// - /// . - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen -#if !NETCF - [Serializable] -#endif - sealed public class Level : IComparable - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// Integer value for this level, higher values represent more severe levels. - /// The string name of this level. - /// The display name for this level. This may be localized or otherwise different from the name - /// - /// - /// Initializes a new instance of the class with - /// the specified level name and value. - /// - /// - public Level(int level, string levelName, string displayName) - { - if (levelName == null) - { - throw new ArgumentNullException("levelName"); - } - if (displayName == null) - { - throw new ArgumentNullException("displayName"); - } - - m_levelValue = level; - m_levelName = string.Intern(levelName); - m_levelDisplayName = displayName; - } - - /// - /// Constructor - /// - /// Integer value for this level, higher values represent more severe levels. - /// The string name of this level. - /// - /// - /// Initializes a new instance of the class with - /// the specified level name and value. - /// - /// - public Level(int level, string levelName) : this(level, levelName, levelName) - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the name of this level. - /// - /// - /// The name of this level. - /// - /// - /// - /// Gets the name of this level. - /// - /// - public string Name - { - get { return m_levelName; } - } - - /// - /// Gets the value of this level. - /// - /// - /// The value of this level. - /// - /// - /// - /// Gets the value of this level. - /// - /// - public int Value - { - get { return m_levelValue; } - } - - /// - /// Gets the display name of this level. - /// - /// - /// The display name of this level. - /// - /// - /// - /// Gets the display name of this level. - /// - /// - public string DisplayName - { - get { return m_levelDisplayName; } - } - - #endregion Public Instance Properties - - #region Override implementation of Object - - /// - /// Returns the representation of the current - /// . - /// - /// - /// A representation of the current . - /// - /// - /// - /// Returns the level . - /// - /// - override public string ToString() - { - return m_levelName; - } - - /// - /// Compares levels. - /// - /// The object to compare against. - /// true if the objects are equal. - /// - /// - /// Compares the levels of instances, and - /// defers to base class if the target object is not a - /// instance. - /// - /// - override public bool Equals(object o) - { - Level otherLevel = o as Level; - if (otherLevel != null) - { - return m_levelValue == otherLevel.m_levelValue; - } - else - { - return base.Equals(o); - } - } - - /// - /// Returns a hash code - /// - /// A hash code for the current . - /// - /// - /// Returns a hash code suitable for use in hashing algorithms and data - /// structures like a hash table. - /// - /// - /// Returns the hash code of the level . - /// - /// - override public int GetHashCode() - { - return m_levelValue; - } - - #endregion Override implementation of Object - - #region Implementation of IComparable - - /// - /// Compares this instance to a specified object and returns an - /// indication of their relative values. - /// - /// A instance or to compare with this instance. - /// - /// A 32-bit signed integer that indicates the relative order of the - /// values compared. The return value has these meanings: - /// - /// - /// Value - /// Meaning - /// - /// - /// Less than zero - /// This instance is less than . - /// - /// - /// Zero - /// This instance is equal to . - /// - /// - /// Greater than zero - /// - /// This instance is greater than . - /// -or- - /// is . - /// - /// - /// - /// - /// - /// - /// must be an instance of - /// or ; otherwise, an exception is thrown. - /// - /// - /// is not a . - public int CompareTo(object r) - { - Level target = r as Level; - if (target != null) - { - return Compare(this, target); - } - throw new ArgumentException("Parameter: r, Value: [" + r + "] is not an instance of Level"); - } - - #endregion Implementation of IComparable - - #region Operators - - /// - /// Returns a value indicating whether a specified - /// is greater than another specified . - /// - /// A - /// A - /// - /// true if is greater than - /// ; otherwise, false. - /// - /// - /// - /// Compares two levels. - /// - /// - public static bool operator > (Level l, Level r) - { - return l.m_levelValue > r.m_levelValue; - } - - /// - /// Returns a value indicating whether a specified - /// is less than another specified . - /// - /// A - /// A - /// - /// true if is less than - /// ; otherwise, false. - /// - /// - /// - /// Compares two levels. - /// - /// - public static bool operator < (Level l, Level r) - { - return l.m_levelValue < r.m_levelValue; - } - - /// - /// Returns a value indicating whether a specified - /// is greater than or equal to another specified . - /// - /// A - /// A - /// - /// true if is greater than or equal to - /// ; otherwise, false. - /// - /// - /// - /// Compares two levels. - /// - /// - public static bool operator >= (Level l, Level r) - { - return l.m_levelValue >= r.m_levelValue; - } - - /// - /// Returns a value indicating whether a specified - /// is less than or equal to another specified . - /// - /// A - /// A - /// - /// true if is less than or equal to - /// ; otherwise, false. - /// - /// - /// - /// Compares two levels. - /// - /// - public static bool operator <= (Level l, Level r) - { - return l.m_levelValue <= r.m_levelValue; - } - - /// - /// Returns a value indicating whether two specified - /// objects have the same value. - /// - /// A or . - /// A or . - /// - /// true if the value of is the same as the - /// value of ; otherwise, false. - /// - /// - /// - /// Compares two levels. - /// - /// - public static bool operator == (Level l, Level r) - { - if (((object)l) != null && ((object)r) != null) - { - return l.m_levelValue == r.m_levelValue; - } - else - { - return ((object) l) == ((object) r); - } - } - - /// - /// Returns a value indicating whether two specified - /// objects have different values. - /// - /// A or . - /// A or . - /// - /// true if the value of is different from - /// the value of ; otherwise, false. - /// - /// - /// - /// Compares two levels. - /// - /// - public static bool operator != (Level l, Level r) - { - return !(l==r); - } - - #endregion Operators - - #region Public Static Methods - - /// - /// Compares two specified instances. - /// - /// The first to compare. - /// The second to compare. - /// - /// A 32-bit signed integer that indicates the relative order of the - /// two values compared. The return value has these meanings: - /// - /// - /// Value - /// Meaning - /// - /// - /// Less than zero - /// is less than . - /// - /// - /// Zero - /// is equal to . - /// - /// - /// Greater than zero - /// is greater than . - /// - /// - /// - /// - /// - /// Compares two levels. - /// - /// - public static int Compare(Level l, Level r) - { - // Reference equals - if ((object)l == (object)r) - { - return 0; - } - - if (l == null && r == null) - { - return 0; - } - if (l == null) - { - return -1; - } - if (r == null) - { - return 1; - } - - return l.m_levelValue.CompareTo(r.m_levelValue); - } - - #endregion Public Static Methods - - #region Public Static Fields - - /// - /// The level designates a higher level than all the rest. - /// - public readonly static Level Off = new Level(int.MaxValue, "OFF"); - - /// - /// The level designates very severe error events. - /// System unusable, emergencies. - /// - public readonly static Level Log4Net_Debug = new Level(120000, "log4net:DEBUG"); - - /// - /// The level designates very severe error events. - /// System unusable, emergencies. - /// - public readonly static Level Emergency = new Level(120000, "EMERGENCY"); - - /// - /// The level designates very severe error events - /// that will presumably lead the application to abort. - /// - public readonly static Level Fatal = new Level(110000, "FATAL"); - - /// - /// The level designates very severe error events. - /// Take immediate action, alerts. - /// - public readonly static Level Alert = new Level(100000, "ALERT"); - - /// - /// The level designates very severe error events. - /// Critical condition, critical. - /// - public readonly static Level Critical = new Level(90000, "CRITICAL"); - - /// - /// The level designates very severe error events. - /// - public readonly static Level Severe = new Level(80000, "SEVERE"); - - /// - /// The level designates error events that might - /// still allow the application to continue running. - /// - public readonly static Level Error = new Level(70000, "ERROR"); - - /// - /// The level designates potentially harmful - /// situations. - /// - public readonly static Level Warn = new Level(60000, "WARN"); - - /// - /// The level designates informational messages - /// that highlight the progress of the application at the highest level. - /// - public readonly static Level Notice = new Level(50000, "NOTICE"); - - /// - /// The level designates informational messages that - /// highlight the progress of the application at coarse-grained level. - /// - public readonly static Level Info = new Level(40000, "INFO"); - - /// - /// The level designates fine-grained informational - /// events that are most useful to debug an application. - /// - public readonly static Level Debug = new Level(30000, "DEBUG"); - - /// - /// The level designates fine-grained informational - /// events that are most useful to debug an application. - /// - public readonly static Level Fine = new Level(30000, "FINE"); - - /// - /// The level designates fine-grained informational - /// events that are most useful to debug an application. - /// - public readonly static Level Trace = new Level(20000, "TRACE"); - - /// - /// The level designates fine-grained informational - /// events that are most useful to debug an application. - /// - public readonly static Level Finer = new Level(20000, "FINER"); - - /// - /// The level designates fine-grained informational - /// events that are most useful to debug an application. - /// - public readonly static Level Verbose = new Level(10000, "VERBOSE"); - - /// - /// The level designates fine-grained informational - /// events that are most useful to debug an application. - /// - public readonly static Level Finest = new Level(10000, "FINEST"); - - /// - /// The level designates the lowest level possible. - /// - public readonly static Level All = new Level(int.MinValue, "ALL"); - - #endregion Public Static Fields - - #region Private Instance Fields - - private readonly int m_levelValue; - private readonly string m_levelName; - private readonly string m_levelDisplayName; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Core/LevelCollection.cs b/src/log4net/Core/LevelCollection.cs deleted file mode 100644 index 1287ac01..00000000 --- a/src/log4net/Core/LevelCollection.cs +++ /dev/null @@ -1,857 +0,0 @@ -#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 System.Collections; - -namespace log4net.Core -{ - /// - /// A strongly-typed collection of objects. - /// - /// Nicko Cadell - public class LevelCollection : ICollection, IList, IEnumerable, ICloneable - { - #region Interfaces - - /// - /// Supports type-safe iteration over a . - /// - public interface ILevelCollectionEnumerator - { - /// - /// Gets the current element in the collection. - /// - Level Current { get; } - - /// - /// Advances the enumerator to the next element in the collection. - /// - /// - /// true if the enumerator was successfully advanced to the next element; - /// false if the enumerator has passed the end of the collection. - /// - /// - /// The collection was modified after the enumerator was created. - /// - bool MoveNext(); - - /// - /// Sets the enumerator to its initial position, before the first element in the collection. - /// - void Reset(); - } - - #endregion - - private const int DEFAULT_CAPACITY = 16; - - #region Implementation (data) - - private Level[] m_array; - private int m_count = 0; - private int m_version = 0; - - #endregion - - #region Static Wrappers - - /// - /// Creates a read-only wrapper for a LevelCollection instance. - /// - /// list to create a readonly wrapper arround - /// - /// A LevelCollection wrapper that is read-only. - /// - public static LevelCollection ReadOnly(LevelCollection list) - { - if(list==null) throw new ArgumentNullException("list"); - - return new ReadOnlyLevelCollection(list); - } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the LevelCollection class - /// that is empty and has the default initial capacity. - /// - public LevelCollection() - { - m_array = new Level[DEFAULT_CAPACITY]; - } - - /// - /// Initializes a new instance of the LevelCollection class - /// that has the specified initial capacity. - /// - /// - /// The number of elements that the new LevelCollection is initially capable of storing. - /// - public LevelCollection(int capacity) - { - m_array = new Level[capacity]; - } - - /// - /// Initializes a new instance of the LevelCollection class - /// that contains elements copied from the specified LevelCollection. - /// - /// The LevelCollection whose elements are copied to the new collection. - public LevelCollection(LevelCollection c) - { - m_array = new Level[c.Count]; - AddRange(c); - } - - /// - /// Initializes a new instance of the LevelCollection class - /// that contains elements copied from the specified array. - /// - /// The array whose elements are copied to the new list. - public LevelCollection(Level[] a) - { - m_array = new Level[a.Length]; - AddRange(a); - } - - /// - /// Initializes a new instance of the LevelCollection class - /// that contains elements copied from the specified collection. - /// - /// The collection whose elements are copied to the new list. - public LevelCollection(ICollection col) - { - m_array = new Level[col.Count]; - AddRange(col); - } - - /// - /// Type visible only to our subclasses - /// Used to access protected constructor - /// - protected internal enum Tag - { - /// - /// A value - /// - Default - } - - /// - /// Allow subclasses to avoid our default constructors - /// - /// - protected internal LevelCollection(Tag tag) - { - m_array = null; - } - #endregion - - #region Operations (type-safe ICollection) - - /// - /// Gets the number of elements actually contained in the LevelCollection. - /// - public virtual int Count - { - get { return m_count; } - } - - /// - /// Copies the entire LevelCollection to a one-dimensional - /// array. - /// - /// The one-dimensional array to copy to. - public virtual void CopyTo(Level[] array) - { - this.CopyTo(array, 0); - } - - /// - /// Copies the entire LevelCollection to a one-dimensional - /// array, starting at the specified index of the target array. - /// - /// The one-dimensional array to copy to. - /// The zero-based index in at which copying begins. - public virtual void CopyTo(Level[] array, int start) - { - if (m_count > array.GetUpperBound(0) + 1 - start) - { - throw new System.ArgumentException("Destination array was not long enough."); - } - - Array.Copy(m_array, 0, array, start, m_count); - } - - /// - /// Gets a value indicating whether access to the collection is synchronized (thread-safe). - /// - /// true if access to the ICollection is synchronized (thread-safe); otherwise, false. - public virtual bool IsSynchronized - { - get { return m_array.IsSynchronized; } - } - - /// - /// Gets an object that can be used to synchronize access to the collection. - /// - public virtual object SyncRoot - { - get { return m_array.SyncRoot; } - } - - #endregion - - #region Operations (type-safe IList) - - /// - /// Gets or sets the at the specified index. - /// - /// The zero-based index of the element to get or set. - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - public virtual Level this[int index] - { - get - { - ValidateIndex(index); // throws - return m_array[index]; - } - set - { - ValidateIndex(index); // throws - ++m_version; - m_array[index] = value; - } - } - - /// - /// Adds a to the end of the LevelCollection. - /// - /// The to be added to the end of the LevelCollection. - /// The index at which the value has been added. - public virtual int Add(Level item) - { - if (m_count == m_array.Length) - { - EnsureCapacity(m_count + 1); - } - - m_array[m_count] = item; - m_version++; - - return m_count++; - } - - /// - /// Removes all elements from the LevelCollection. - /// - public virtual void Clear() - { - ++m_version; - m_array = new Level[DEFAULT_CAPACITY]; - m_count = 0; - } - - /// - /// Creates a shallow copy of the . - /// - /// A new with a shallow copy of the collection data. - public virtual object Clone() - { - LevelCollection newCol = new LevelCollection(m_count); - Array.Copy(m_array, 0, newCol.m_array, 0, m_count); - newCol.m_count = m_count; - newCol.m_version = m_version; - - return newCol; - } - - /// - /// Determines whether a given is in the LevelCollection. - /// - /// The to check for. - /// true if is found in the LevelCollection; otherwise, false. - public virtual bool Contains(Level item) - { - for (int i=0; i != m_count; ++i) - { - if (m_array[i].Equals(item)) - { - return true; - } - } - return false; - } - - /// - /// Returns the zero-based index of the first occurrence of a - /// in the LevelCollection. - /// - /// The to locate in the LevelCollection. - /// - /// The zero-based index of the first occurrence of - /// in the entire LevelCollection, if found; otherwise, -1. - /// - public virtual int IndexOf(Level item) - { - for (int i=0; i != m_count; ++i) - { - if (m_array[i].Equals(item)) - { - return i; - } - } - return -1; - } - - /// - /// Inserts an element into the LevelCollection at the specified index. - /// - /// The zero-based index at which should be inserted. - /// The to insert. - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - public virtual void Insert(int index, Level item) - { - ValidateIndex(index, true); // throws - - if (m_count == m_array.Length) - { - EnsureCapacity(m_count + 1); - } - - if (index < m_count) - { - Array.Copy(m_array, index, m_array, index + 1, m_count - index); - } - - m_array[index] = item; - m_count++; - m_version++; - } - - /// - /// Removes the first occurrence of a specific from the LevelCollection. - /// - /// The to remove from the LevelCollection. - /// - /// The specified was not found in the LevelCollection. - /// - public virtual void Remove(Level item) - { - int i = IndexOf(item); - if (i < 0) - { - throw new System.ArgumentException("Cannot remove the specified item because it was not found in the specified Collection."); - } - - ++m_version; - RemoveAt(i); - } - - /// - /// Removes the element at the specified index of the LevelCollection. - /// - /// The zero-based index of the element to remove. - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - public virtual void RemoveAt(int index) - { - ValidateIndex(index); // throws - - m_count--; - - if (index < m_count) - { - Array.Copy(m_array, index + 1, m_array, index, m_count - index); - } - - // We can't set the deleted entry equal to null, because it might be a value type. - // Instead, we'll create an empty single-element array of the right type and copy it - // over the entry we want to erase. - Level[] temp = new Level[1]; - Array.Copy(temp, 0, m_array, m_count, 1); - m_version++; - } - - /// - /// Gets a value indicating whether the collection has a fixed size. - /// - /// true if the collection has a fixed size; otherwise, false. The default is false - public virtual bool IsFixedSize - { - get { return false; } - } - - /// - /// Gets a value indicating whether the IList is read-only. - /// - /// true if the collection is read-only; otherwise, false. The default is false - public virtual bool IsReadOnly - { - get { return false; } - } - - #endregion - - #region Operations (type-safe IEnumerable) - - /// - /// Returns an enumerator that can iterate through the LevelCollection. - /// - /// An for the entire LevelCollection. - public virtual ILevelCollectionEnumerator GetEnumerator() - { - return new Enumerator(this); - } - - #endregion - - #region Public helpers (just to mimic some nice features of ArrayList) - - /// - /// Gets or sets the number of elements the LevelCollection can contain. - /// - public virtual int Capacity - { - get - { - return m_array.Length; - } - set - { - if (value < m_count) - { - value = m_count; - } - - if (value != m_array.Length) - { - if (value > 0) - { - Level[] temp = new Level[value]; - Array.Copy(m_array, 0, temp, 0, m_count); - m_array = temp; - } - else - { - m_array = new Level[DEFAULT_CAPACITY]; - } - } - } - } - - /// - /// Adds the elements of another LevelCollection to the current LevelCollection. - /// - /// The LevelCollection whose elements should be added to the end of the current LevelCollection. - /// The new of the LevelCollection. - public virtual int AddRange(LevelCollection x) - { - if (m_count + x.Count >= m_array.Length) - { - EnsureCapacity(m_count + x.Count); - } - - Array.Copy(x.m_array, 0, m_array, m_count, x.Count); - m_count += x.Count; - m_version++; - - return m_count; - } - - /// - /// Adds the elements of a array to the current LevelCollection. - /// - /// The array whose elements should be added to the end of the LevelCollection. - /// The new of the LevelCollection. - public virtual int AddRange(Level[] x) - { - if (m_count + x.Length >= m_array.Length) - { - EnsureCapacity(m_count + x.Length); - } - - Array.Copy(x, 0, m_array, m_count, x.Length); - m_count += x.Length; - m_version++; - - return m_count; - } - - /// - /// Adds the elements of a collection to the current LevelCollection. - /// - /// The collection whose elements should be added to the end of the LevelCollection. - /// The new of the LevelCollection. - public virtual int AddRange(ICollection col) - { - if (m_count + col.Count >= m_array.Length) - { - EnsureCapacity(m_count + col.Count); - } - - foreach(object item in col) - { - Add((Level)item); - } - - return m_count; - } - - /// - /// Sets the capacity to the actual number of elements. - /// - public virtual void TrimToSize() - { - this.Capacity = m_count; - } - - #endregion - - #region Implementation (helpers) - - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - private void ValidateIndex(int i) - { - ValidateIndex(i, false); - } - - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - private void ValidateIndex(int i, bool allowEqualEnd) - { - int max = (allowEqualEnd) ? (m_count) : (m_count-1); - if (i < 0 || i > max) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("i", (object)i, "Index was out of range. Must be non-negative and less than the size of the collection. [" + (object)i + "] Specified argument was out of the range of valid values."); - } - } - - private void EnsureCapacity(int min) - { - int newCapacity = ((m_array.Length == 0) ? DEFAULT_CAPACITY : m_array.Length * 2); - if (newCapacity < min) - { - newCapacity = min; - } - - this.Capacity = newCapacity; - } - - #endregion - - #region Implementation (ICollection) - - void ICollection.CopyTo(Array array, int start) - { - Array.Copy(m_array, 0, array, start, m_count); - } - - #endregion - - #region Implementation (IList) - - object IList.this[int i] - { - get { return (object)this[i]; } - set { this[i] = (Level)value; } - } - - int IList.Add(object x) - { - return this.Add((Level)x); - } - - bool IList.Contains(object x) - { - return this.Contains((Level)x); - } - - int IList.IndexOf(object x) - { - return this.IndexOf((Level)x); - } - - void IList.Insert(int pos, object x) - { - this.Insert(pos, (Level)x); - } - - void IList.Remove(object x) - { - this.Remove((Level)x); - } - - void IList.RemoveAt(int pos) - { - this.RemoveAt(pos); - } - - #endregion - - #region Implementation (IEnumerable) - - IEnumerator IEnumerable.GetEnumerator() - { - return (IEnumerator)(this.GetEnumerator()); - } - - #endregion - - #region Nested enumerator class - - /// - /// Supports simple iteration over a . - /// - private sealed class Enumerator : IEnumerator, ILevelCollectionEnumerator - { - #region Implementation (data) - - private readonly LevelCollection m_collection; - private int m_index; - private int m_version; - - #endregion - - #region Construction - - /// - /// Initializes a new instance of the Enumerator class. - /// - /// - internal Enumerator(LevelCollection tc) - { - m_collection = tc; - m_index = -1; - m_version = tc.m_version; - } - - #endregion - - #region Operations (type-safe IEnumerator) - - /// - /// Gets the current element in the collection. - /// - public Level Current - { - get { return m_collection[m_index]; } - } - - /// - /// Advances the enumerator to the next element in the collection. - /// - /// - /// true if the enumerator was successfully advanced to the next element; - /// false if the enumerator has passed the end of the collection. - /// - /// - /// The collection was modified after the enumerator was created. - /// - public bool MoveNext() - { - if (m_version != m_collection.m_version) - { - throw new System.InvalidOperationException("Collection was modified; enumeration operation may not execute."); - } - - ++m_index; - return (m_index < m_collection.Count); - } - - /// - /// Sets the enumerator to its initial position, before the first element in the collection. - /// - public void Reset() - { - m_index = -1; - } - - #endregion - - #region Implementation (IEnumerator) - - object IEnumerator.Current - { - get { return this.Current; } - } - - #endregion - } - - #endregion - - #region Nested Read Only Wrapper class - - private sealed class ReadOnlyLevelCollection : LevelCollection - { - #region Implementation (data) - - private readonly LevelCollection m_collection; - - #endregion - - #region Construction - - internal ReadOnlyLevelCollection(LevelCollection list) : base(Tag.Default) - { - m_collection = list; - } - - #endregion - - #region Type-safe ICollection - - public override void CopyTo(Level[] array) - { - m_collection.CopyTo(array); - } - - public override void CopyTo(Level[] array, int start) - { - m_collection.CopyTo(array,start); - } - public override int Count - { - get { return m_collection.Count; } - } - - public override bool IsSynchronized - { - get { return m_collection.IsSynchronized; } - } - - public override object SyncRoot - { - get { return this.m_collection.SyncRoot; } - } - - #endregion - - #region Type-safe IList - - public override Level this[int i] - { - get { return m_collection[i]; } - set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); } - } - - public override int Add(Level x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override void Clear() - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override bool Contains(Level x) - { - return m_collection.Contains(x); - } - - public override int IndexOf(Level x) - { - return m_collection.IndexOf(x); - } - - public override void Insert(int pos, Level x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override void Remove(Level x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override void RemoveAt(int pos) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override bool IsFixedSize - { - get { return true; } - } - - public override bool IsReadOnly - { - get { return true; } - } - - #endregion - - #region Type-safe IEnumerable - - public override ILevelCollectionEnumerator GetEnumerator() - { - return m_collection.GetEnumerator(); - } - - #endregion - - #region Public Helpers - - // (just to mimic some nice features of ArrayList) - public override int Capacity - { - get { return m_collection.Capacity; } - set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); } - } - - public override int AddRange(LevelCollection x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override int AddRange(Level[] x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - #endregion - } - - #endregion - } - -} diff --git a/src/log4net/Core/LevelEvaluator.cs b/src/log4net/Core/LevelEvaluator.cs deleted file mode 100644 index 35706df8..00000000 --- a/src/log4net/Core/LevelEvaluator.cs +++ /dev/null @@ -1,133 +0,0 @@ -#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; - -namespace log4net.Core -{ - /// - /// An evaluator that triggers at a threshold level - /// - /// - /// - /// This evaluator will trigger if the level of the event - /// passed to - /// is equal to or greater than the - /// level. - /// - /// - /// Nicko Cadell - public class LevelEvaluator : ITriggeringEventEvaluator - { - /// - /// The threshold for triggering - /// - private Level m_threshold; - - /// - /// Create a new evaluator using the threshold. - /// - /// - /// - /// Create a new evaluator using the threshold. - /// - /// - /// This evaluator will trigger if the level of the event - /// passed to - /// is equal to or greater than the - /// level. - /// - /// - public LevelEvaluator() : this(Level.Off) - { - } - - /// - /// Create a new evaluator using the specified threshold. - /// - /// the threshold to trigger at - /// - /// - /// Create a new evaluator using the specified threshold. - /// - /// - /// This evaluator will trigger if the level of the event - /// passed to - /// is equal to or greater than the - /// level. - /// - /// - public LevelEvaluator(Level threshold) - { - if (threshold == null) - { - throw new ArgumentNullException("threshold"); - } - - m_threshold = threshold; - } - - /// - /// the threshold to trigger at - /// - /// - /// The that will cause this evaluator to trigger - /// - /// - /// - /// This evaluator will trigger if the level of the event - /// passed to - /// is equal to or greater than the - /// level. - /// - /// - public Level Threshold - { - get { return m_threshold; } - set { m_threshold = value; } - } - - /// - /// Is this the triggering event? - /// - /// The event to check - /// This method returns true, if the event level - /// is equal or higher than the . - /// Otherwise it returns false - /// - /// - /// This evaluator will trigger if the level of the event - /// passed to - /// is equal to or greater than the - /// level. - /// - /// - public bool IsTriggeringEvent(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - return (loggingEvent.Level >= m_threshold); - } - } -} diff --git a/src/log4net/Core/LevelMap.cs b/src/log4net/Core/LevelMap.cs deleted file mode 100644 index d458533a..00000000 --- a/src/log4net/Core/LevelMap.cs +++ /dev/null @@ -1,229 +0,0 @@ -#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 System.Collections; -using System.Collections.Specialized; - -using log4net.Util; - -namespace log4net.Core -{ - /// - /// Mapping between string name and Level object - /// - /// - /// - /// Mapping between string name and object. - /// This mapping is held separately for each . - /// The level name is case insensitive. - /// - /// - /// Nicko Cadell - public sealed class LevelMap - { - #region Member Variables - - /// - /// Mapping from level name to Level object. The - /// level name is case insensitive - /// - private Hashtable m_mapName2Level = SystemInfo.CreateCaseInsensitiveHashtable(); - - #endregion - - /// - /// Construct the level map - /// - /// - /// - /// Construct the level map. - /// - /// - public LevelMap() - { - } - - /// - /// Clear the internal maps of all levels - /// - /// - /// - /// Clear the internal maps of all levels - /// - /// - public void Clear() - { - // Clear all current levels - m_mapName2Level.Clear(); - } - - /// - /// Lookup a by name - /// - /// The name of the Level to lookup - /// a Level from the map with the name specified - /// - /// - /// Returns the from the - /// map with the name specified. If the no level is - /// found then null is returned. - /// - /// - public Level this[string name] - { - get - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - lock(this) - { - return (Level)m_mapName2Level[name]; - } - } - } - - /// - /// Create a new Level and add it to the map - /// - /// the string to display for the Level - /// the level value to give to the Level - /// - /// - /// Create a new Level and add it to the map - /// - /// - /// - public void Add(string name, int value) - { - Add(name, value, null); - } - - /// - /// Create a new Level and add it to the map - /// - /// the string to display for the Level - /// the level value to give to the Level - /// the display name to give to the Level - /// - /// - /// Create a new Level and add it to the map - /// - /// - public void Add(string name, int value, string displayName) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - if (name.Length == 0) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("name", name, "Parameter: name, Value: ["+name+"] out of range. Level name must not be empty"); - } - - if (displayName == null || displayName.Length == 0) - { - displayName = name; - } - - Add(new Level(value, name, displayName)); - } - - /// - /// Add a Level to the map - /// - /// the Level to add - /// - /// - /// Add a Level to the map - /// - /// - public void Add(Level level) - { - if (level == null) - { - throw new ArgumentNullException("level"); - } - lock(this) - { - m_mapName2Level[level.Name] = level; - } - } - - /// - /// Return all possible levels as a list of Level objects. - /// - /// all possible levels as a list of Level objects - /// - /// - /// Return all possible levels as a list of Level objects. - /// - /// - public LevelCollection AllLevels - { - get - { - lock(this) - { - return new LevelCollection(m_mapName2Level.Values); - } - } - } - - /// - /// Lookup a named level from the map - /// - /// the name of the level to lookup is taken from this level. - /// If the level is not set on the map then this level is added - /// the level in the map with the name specified - /// - /// - /// Lookup a named level from the map. The name of the level to lookup is taken - /// from the property of the - /// argument. - /// - /// - /// If no level with the specified name is found then the - /// argument is added to the level map - /// and returned. - /// - /// - public Level LookupWithDefault(Level defaultLevel) - { - if (defaultLevel == null) - { - throw new ArgumentNullException("defaultLevel"); - } - - lock(this) - { - Level level = (Level)m_mapName2Level[defaultLevel.Name]; - if (level == null) - { - m_mapName2Level[defaultLevel.Name] = defaultLevel; - return defaultLevel; - } - return level; - } - } - } -} diff --git a/src/log4net/Core/LocationInfo.cs b/src/log4net/Core/LocationInfo.cs deleted file mode 100644 index 8f96c4e8..00000000 --- a/src/log4net/Core/LocationInfo.cs +++ /dev/null @@ -1,319 +0,0 @@ -#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 System.Collections; -using System.Diagnostics; - -using log4net.Util; - -namespace log4net.Core -{ - /// - /// The internal representation of caller location information. - /// - /// - /// - /// This class uses the System.Diagnostics.StackTrace class to generate - /// a call stack. The caller's information is then extracted from this stack. - /// - /// - /// The System.Diagnostics.StackTrace class is not supported on the - /// .NET Compact Framework 1.0 therefore caller location information is not - /// available on that framework. - /// - /// - /// The System.Diagnostics.StackTrace class has this to say about Release builds: - /// - /// - /// "StackTrace information will be most informative with Debug build configurations. - /// By default, Debug builds include debug symbols, while Release builds do not. The - /// debug symbols contain most of the file, method name, line number, and column - /// information used in constructing StackFrame and StackTrace objects. StackTrace - /// might not report as many method calls as expected, due to code transformations - /// that occur during optimization." - /// - /// - /// This means that in a Release build the caller information may be incomplete or may - /// not exist at all! Therefore caller location information cannot be relied upon in a Release build. - /// - /// - /// Nicko Cadell - /// Gert Driesen -#if !NETCF - [Serializable] -#endif - public class LocationInfo - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// The declaring type of the method that is - /// the stack boundary into the logging system for this call. - /// - /// - /// Initializes a new instance of the - /// class based on the current thread. - /// - /// - public LocationInfo(Type callerStackBoundaryDeclaringType) - { - // Initialize all fields - m_className = NA; - m_fileName = NA; - m_lineNumber = NA; - m_methodName = NA; - m_fullInfo = NA; - -#if !NETCF - if (callerStackBoundaryDeclaringType != null) - { - try - { - StackTrace st = new StackTrace(true); - int frameIndex = 0; - - // skip frames not from fqnOfCallingClass - while (frameIndex < st.FrameCount) - { - StackFrame frame = st.GetFrame(frameIndex); - if (frame != null && frame.GetMethod().DeclaringType == callerStackBoundaryDeclaringType) - { - break; - } - frameIndex++; - } - - // skip frames from fqnOfCallingClass - while (frameIndex < st.FrameCount) - { - StackFrame frame = st.GetFrame(frameIndex); - if (frame != null && frame.GetMethod().DeclaringType != callerStackBoundaryDeclaringType) - { - break; - } - frameIndex++; - } - - if (frameIndex < st.FrameCount) - { - // take into account the frames we skip above - int adjustedFrameCount = st.FrameCount - frameIndex; - ArrayList stackFramesList = new ArrayList(adjustedFrameCount); - m_stackFrames = new StackFrameItem[adjustedFrameCount]; - for (int i=frameIndex; i < st.FrameCount; i++) - { - stackFramesList.Add(new StackFrameItem(st.GetFrame(i))); - } - - stackFramesList.CopyTo(m_stackFrames, 0); - - // now frameIndex is the first 'user' caller frame - StackFrame locationFrame = st.GetFrame(frameIndex); - - if (locationFrame != null) - { - System.Reflection.MethodBase method = locationFrame.GetMethod(); - - if (method != null) - { - m_methodName = method.Name; - if (method.DeclaringType != null) - { - m_className = method.DeclaringType.FullName; - } - } - m_fileName = locationFrame.GetFileName(); - m_lineNumber = locationFrame.GetFileLineNumber().ToString(System.Globalization.NumberFormatInfo.InvariantInfo); - - // Combine all location info - m_fullInfo = m_className + '.' + m_methodName + '(' + m_fileName + ':' + m_lineNumber + ')'; - } - } - } - catch(System.Security.SecurityException) - { - // This security exception will occur if the caller does not have - // some undefined set of SecurityPermission flags. - LogLog.Debug(declaringType, "Security exception while trying to get caller stack frame. Error Ignored. Location Information Not Available."); - } - } -#endif - } - - /// - /// Constructor - /// - /// The fully qualified class name. - /// The method name. - /// The file name. - /// The line number of the method within the file. - /// - /// - /// Initializes a new instance of the - /// class with the specified data. - /// - /// - public LocationInfo(string className, string methodName, string fileName, string lineNumber) - { - m_className = className; - m_fileName = fileName; - m_lineNumber = lineNumber; - m_methodName = methodName; - m_fullInfo = m_className + '.' + m_methodName + '(' + m_fileName + - ':' + m_lineNumber + ')'; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the fully qualified class name of the caller making the logging - /// request. - /// - /// - /// The fully qualified class name of the caller making the logging - /// request. - /// - /// - /// - /// Gets the fully qualified class name of the caller making the logging - /// request. - /// - /// - public string ClassName - { - get { return m_className; } - } - - /// - /// Gets the file name of the caller. - /// - /// - /// The file name of the caller. - /// - /// - /// - /// Gets the file name of the caller. - /// - /// - public string FileName - { - get { return m_fileName; } - } - - /// - /// Gets the line number of the caller. - /// - /// - /// The line number of the caller. - /// - /// - /// - /// Gets the line number of the caller. - /// - /// - public string LineNumber - { - get { return m_lineNumber; } - } - - /// - /// Gets the method name of the caller. - /// - /// - /// The method name of the caller. - /// - /// - /// - /// Gets the method name of the caller. - /// - /// - public string MethodName - { - get { return m_methodName; } - } - - /// - /// Gets all available caller information - /// - /// - /// All available caller information, in the format - /// fully.qualified.classname.of.caller.methodName(Filename:line) - /// - /// - /// - /// Gets all available caller information, in the format - /// fully.qualified.classname.of.caller.methodName(Filename:line) - /// - /// - public string FullInfo - { - get { return m_fullInfo; } - } - -#if !NETCF - /// - /// Gets the stack frames from the stack trace of the caller making the log request - /// - public StackFrameItem[] StackFrames - { - get { return m_stackFrames; } - } -#endif - - #endregion Public Instance Properties - - #region Private Instance Fields - - private readonly string m_className; - private readonly string m_fileName; - private readonly string m_lineNumber; - private readonly string m_methodName; - private readonly string m_fullInfo; -#if !NETCF - private readonly StackFrameItem[] m_stackFrames; -#endif - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the LocationInfo class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(LocationInfo); - - /// - /// When location information is not available the constant - /// NA is returned. Current value of this string - /// constant is ?. - /// - private const string NA = "?"; - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Core/LogException.cs b/src/log4net/Core/LogException.cs deleted file mode 100644 index 499979c1..00000000 --- a/src/log4net/Core/LogException.cs +++ /dev/null @@ -1,110 +0,0 @@ -#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; -#if !NETCF -using System.Runtime.Serialization; -#endif - -namespace log4net.Core -{ - /// - /// Exception base type for log4net. - /// - /// - /// - /// This type extends . It - /// does not add any new functionality but does differentiate the - /// type of exception being thrown. - /// - /// - /// Nicko Cadell - /// Gert Driesen -#if !NETCF - [Serializable] -#endif - public class LogException : ApplicationException - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public LogException() - { - } - - /// - /// Constructor - /// - /// A message to include with the exception. - /// - /// - /// Initializes a new instance of the class with - /// the specified message. - /// - /// - public LogException(String message) : base(message) - { - } - - /// - /// Constructor - /// - /// A message to include with the exception. - /// A nested exception to include. - /// - /// - /// Initializes a new instance of the class - /// with the specified message and inner exception. - /// - /// - public LogException(String message, Exception innerException) : base(message, innerException) - { - } - - #endregion Public Instance Constructors - - #region Protected Instance Constructors - -#if !NETCF - /// - /// Serialization constructor - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// - /// - /// Initializes a new instance of the class - /// with serialized data. - /// - /// - protected LogException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } -#endif - - #endregion Protected Instance Constructors - } -} diff --git a/src/log4net/Core/LogImpl.cs b/src/log4net/Core/LogImpl.cs deleted file mode 100644 index df1715b6..00000000 --- a/src/log4net/Core/LogImpl.cs +++ /dev/null @@ -1,1525 +0,0 @@ -#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 System.Globalization; - -using log4net.Repository; -using log4net.Util; - -namespace log4net.Core -{ - /// - /// Implementation of wrapper interface. - /// - /// - /// - /// This implementation of the interface - /// forwards to the held by the base class. - /// - /// - /// This logger has methods to allow the caller to log at the following - /// levels: - /// - /// - /// - /// TRACE - /// - /// The and methods log messages - /// at the TRACE level. That is the level with that name defined in the - /// repositories . The default value - /// for this level is . The - /// property tests if this level is enabled for logging. - /// - /// - /// - /// DEBUG - /// - /// The and methods log messages - /// at the DEBUG level. That is the level with that name defined in the - /// repositories . The default value - /// for this level is . The - /// property tests if this level is enabled for logging. - /// - /// - /// - /// INFO - /// - /// The and methods log messages - /// at the INFO level. That is the level with that name defined in the - /// repositories . The default value - /// for this level is . The - /// property tests if this level is enabled for logging. - /// - /// - /// - /// WARN - /// - /// The and methods log messages - /// at the WARN level. That is the level with that name defined in the - /// repositories . The default value - /// for this level is . The - /// property tests if this level is enabled for logging. - /// - /// - /// - /// ERROR - /// - /// The and methods log messages - /// at the ERROR level. That is the level with that name defined in the - /// repositories . The default value - /// for this level is . The - /// property tests if this level is enabled for logging. - /// - /// - /// - /// FATAL - /// - /// The and methods log messages - /// at the FATAL level. That is the level with that name defined in the - /// repositories . The default value - /// for this level is . The - /// property tests if this level is enabled for logging. - /// - /// - /// - /// - /// The values for these levels and their semantic meanings can be changed by - /// configuring the for the repository. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class LogImpl : LoggerWrapperImpl, ILog - { - #region Public Instance Constructors - - /// - /// Construct a new wrapper for the specified logger. - /// - /// The logger to wrap. - /// - /// - /// Construct a new wrapper for the specified logger. - /// - /// - public LogImpl(ILogger logger) : base(logger) - { - // Listen for changes to the repository - logger.Repository.ConfigurationChanged += new LoggerRepositoryConfigurationChangedEventHandler(LoggerRepositoryConfigurationChanged); - - // load the current levels - ReloadLevels(logger.Repository); - } - - #endregion Public Instance Constructors - - /// - /// Virtual method called when the configuration of the repository changes - /// - /// the repository holding the levels - /// - /// - /// Virtual method called when the configuration of the repository changes - /// - /// - protected virtual void ReloadLevels(ILoggerRepository repository) - { - LevelMap levelMap = repository.LevelMap; - - m_levelTrace = levelMap.LookupWithDefault(Level.Trace); - m_levelDebug = levelMap.LookupWithDefault(Level.Debug); - m_levelInfo = levelMap.LookupWithDefault(Level.Info); - m_levelWarn = levelMap.LookupWithDefault(Level.Warn); - m_levelError = levelMap.LookupWithDefault(Level.Error); - m_levelFatal = levelMap.LookupWithDefault(Level.Fatal); - } - - #region Implementation of ILog - - /// - /// Logs a message object with the TRACE level. - /// - /// The message object to log. - /// - /// - /// This method first checks if this logger is TRACE - /// enabled by comparing the level of this logger with the - /// TRACE level. If this logger is - /// TRACE enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger and - /// also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// - /// WARNING Note that passing an to this - /// method will print the name of the but no - /// stack trace. To print a stack trace use the - /// form instead. - /// - /// - virtual public void Trace(object message) - { - Logger.Log(ThisDeclaringType, m_levelTrace, message, null); - } - - /// - /// Logs a message object with the TRACE level - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// Logs a message object with the TRACE level including - /// the stack trace of the - /// passed as a parameter. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - virtual public void Trace(object message, Exception exception) - { - Logger.Log(ThisDeclaringType, m_levelTrace, message, exception); - } - - /// - /// Logs a formatted message string with the TRACE level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void TraceFormat(string format, params object[] args) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - /// - /// Logs a formatted message string with the TRACE level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void TraceFormat(string format, object arg0) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - /// - /// Logs a formatted message string with the TRACE level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void TraceFormat(string format, object arg0, object arg1) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - /// - /// Logs a formatted message string with the TRACE level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void TraceFormat(string format, object arg0, object arg1, object arg2) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - /// - /// Logs a formatted message string with the TRACE level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void TraceFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsTraceEnabled) - { - Logger.Log(ThisDeclaringType, m_levelTrace, new SystemStringFormat(provider, format, args), null); - } - } - - /// - /// Logs a message object with the DEBUG level. - /// - /// The message object to log. - /// - /// - /// This method first checks if this logger is DEBUG - /// enabled by comparing the level of this logger with the - /// DEBUG level. If this logger is - /// DEBUG enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - virtual public void Debug(object message) - { - Logger.Log(ThisDeclaringType, m_levelDebug, message, null); - } - - /// - /// Logs a message object with the DEBUG level - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// Logs a message object with the DEBUG level including - /// the stack trace of the passed - /// as a parameter. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - virtual public void Debug(object message, Exception exception) - { - Logger.Log(ThisDeclaringType, m_levelDebug, message, exception); - } - - /// - /// Logs a formatted message string with the DEBUG level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void DebugFormat(string format, params object[] args) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - /// - /// Logs a formatted message string with the DEBUG level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void DebugFormat(string format, object arg0) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - /// - /// Logs a formatted message string with the DEBUG level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void DebugFormat(string format, object arg0, object arg1) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - /// - /// Logs a formatted message string with the DEBUG level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void DebugFormat(string format, object arg0, object arg1, object arg2) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - /// - /// Logs a formatted message string with the DEBUG level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void DebugFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsDebugEnabled) - { - Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(provider, format, args), null); - } - } - - /// - /// Logs a message object with the INFO level. - /// - /// The message object to log. - /// - /// - /// This method first checks if this logger is INFO - /// enabled by comparing the level of this logger with the - /// INFO level. If this logger is - /// INFO enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - virtual public void Info(object message) - { - Logger.Log(ThisDeclaringType, m_levelInfo, message, null); - } - - /// - /// Logs a message object with the INFO level. - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// Logs a message object with the INFO level including - /// the stack trace of the - /// passed as a parameter. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - virtual public void Info(object message, Exception exception) - { - Logger.Log(ThisDeclaringType, m_levelInfo, message, exception); - } - - /// - /// Logs a formatted message string with the INFO level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void InfoFormat(string format, params object[] args) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - /// - /// Logs a formatted message string with the INFO level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void InfoFormat(string format, object arg0) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - /// - /// Logs a formatted message string with the INFO level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void InfoFormat(string format, object arg0, object arg1) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - /// - /// Logs a formatted message string with the INFO level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void InfoFormat(string format, object arg0, object arg1, object arg2) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - /// - /// Logs a formatted message string with the INFO level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void InfoFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsInfoEnabled) - { - Logger.Log(ThisDeclaringType, m_levelInfo, new SystemStringFormat(provider, format, args), null); - } - } - - /// - /// Logs a message object with the WARN level. - /// - /// the message object to log - /// - /// - /// This method first checks if this logger is WARN - /// enabled by comparing the level of this logger with the - /// WARN level. If this logger is - /// WARN enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger and - /// also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// - /// WARNING Note that passing an to this - /// method will print the name of the but no - /// stack trace. To print a stack trace use the - /// form instead. - /// - /// - virtual public void Warn(object message) - { - Logger.Log(ThisDeclaringType, m_levelWarn, message, null); - } - - /// - /// Logs a message object with the WARN level - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// Logs a message object with the WARN level including - /// the stack trace of the - /// passed as a parameter. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - virtual public void Warn(object message, Exception exception) - { - Logger.Log(ThisDeclaringType, m_levelWarn, message, exception); - } - - /// - /// Logs a formatted message string with the WARN level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void WarnFormat(string format, params object[] args) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - /// - /// Logs a formatted message string with the WARN level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void WarnFormat(string format, object arg0) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - /// - /// Logs a formatted message string with the WARN level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void WarnFormat(string format, object arg0, object arg1) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - /// - /// Logs a formatted message string with the WARN level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void WarnFormat(string format, object arg0, object arg1, object arg2) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - /// - /// Logs a formatted message string with the WARN level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void WarnFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsWarnEnabled) - { - Logger.Log(ThisDeclaringType, m_levelWarn, new SystemStringFormat(provider, format, args), null); - } - } - - /// - /// Logs a message object with the ERROR level. - /// - /// The message object to log. - /// - /// - /// This method first checks if this logger is ERROR - /// enabled by comparing the level of this logger with the - /// ERROR level. If this logger is - /// ERROR enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger and - /// also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// - /// WARNING Note that passing an to this - /// method will print the name of the but no - /// stack trace. To print a stack trace use the - /// form instead. - /// - /// - virtual public void Error(object message) - { - Logger.Log(ThisDeclaringType, m_levelError, message, null); - } - - /// - /// Logs a message object with the ERROR level - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// Logs a message object with the ERROR level including - /// the stack trace of the - /// passed as a parameter. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - virtual public void Error(object message, Exception exception) - { - Logger.Log(ThisDeclaringType, m_levelError, message, exception); - } - - /// - /// Logs a formatted message string with the ERROR level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void ErrorFormat(string format, params object[] args) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - /// - /// Logs a formatted message string with the ERROR level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void ErrorFormat(string format, object arg0) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - /// - /// Logs a formatted message string with the ERROR level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void ErrorFormat(string format, object arg0, object arg1) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - /// - /// Logs a formatted message string with the ERROR level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void ErrorFormat(string format, object arg0, object arg1, object arg2) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - /// - /// Logs a formatted message string with the ERROR level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void ErrorFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsErrorEnabled) - { - Logger.Log(ThisDeclaringType, m_levelError, new SystemStringFormat(provider, format, args), null); - } - } - - /// - /// Logs a message object with the FATAL level. - /// - /// The message object to log. - /// - /// - /// This method first checks if this logger is FATAL - /// enabled by comparing the level of this logger with the - /// FATAL level. If this logger is - /// FATAL enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger and - /// also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// - /// WARNING Note that passing an to this - /// method will print the name of the but no - /// stack trace. To print a stack trace use the - /// form instead. - /// - /// - virtual public void Fatal(object message) - { - Logger.Log(ThisDeclaringType, m_levelFatal, message, null); - } - - /// - /// Logs a message object with the FATAL level - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// Logs a message object with the FATAL level including - /// the stack trace of the - /// passed as a parameter. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - virtual public void Fatal(object message, Exception exception) - { - Logger.Log(ThisDeclaringType, m_levelFatal, message, exception); - } - - /// - /// Logs a formatted message string with the FATAL level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void FatalFormat(string format, params object[] args) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); - } - } - - /// - /// Logs a formatted message string with the FATAL level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void FatalFormat(string format, object arg0) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0 }), null); - } - } - - /// - /// Logs a formatted message string with the FATAL level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void FatalFormat(string format, object arg0, object arg1) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1 }), null); - } - } - - /// - /// Logs a formatted message string with the FATAL level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// The string is formatted using the - /// format provider. To specify a localized provider use the - /// method. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void FatalFormat(string format, object arg0, object arg1, object arg2) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, new object[] { arg0, arg1, arg2 }), null); - } - } - - /// - /// Logs a formatted message string with the FATAL level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the method. See - /// String.Format for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - virtual public void FatalFormat(IFormatProvider provider, string format, params object[] args) - { - if (IsFatalEnabled) - { - Logger.Log(ThisDeclaringType, m_levelFatal, new SystemStringFormat(provider, format, args), null); - } - } - - /// - /// Checks if this logger is enabled for the TRACE level. - /// - /// - /// true if this logger is enabled for TRACE events, - /// false otherwise. - /// - /// - /// - /// See for more tracermation and examples - /// of using this method. - /// - /// - /// - virtual public bool IsTraceEnabled - { - get { return Logger.IsEnabledFor(m_levelTrace); } - } - - /// - /// Checks if this logger is enabled for the DEBUG - /// level. - /// - /// - /// true if this logger is enabled for DEBUG events, - /// false otherwise. - /// - /// - /// - /// This function is intended to lessen the computational cost of - /// disabled log debug statements. - /// - /// - /// For some log Logger object, when you write: - /// - /// - /// log.Debug("This is entry number: " + i ); - /// - /// - /// You incur the cost constructing the message, concatenation in - /// this case, regardless of whether the message is logged or not. - /// - /// - /// If you are worried about speed, then you should write: - /// - /// - /// if (log.IsDebugEnabled()) - /// { - /// log.Debug("This is entry number: " + i ); - /// } - /// - /// - /// This way you will not incur the cost of parameter - /// construction if debugging is disabled for log. On - /// the other hand, if the log is debug enabled, you - /// will incur the cost of evaluating whether the logger is debug - /// enabled twice. Once in IsDebugEnabled and once in - /// the Debug. This is an insignificant overhead - /// since evaluating a logger takes about 1% of the time it - /// takes to actually log. - /// - /// - virtual public bool IsDebugEnabled - { - get { return Logger.IsEnabledFor(m_levelDebug); } - } - - /// - /// Checks if this logger is enabled for the INFO level. - /// - /// - /// true if this logger is enabled for INFO events, - /// false otherwise. - /// - /// - /// - /// See for more information and examples - /// of using this method. - /// - /// - /// - virtual public bool IsInfoEnabled - { - get { return Logger.IsEnabledFor(m_levelInfo); } - } - - /// - /// Checks if this logger is enabled for the WARN level. - /// - /// - /// true if this logger is enabled for WARN events, - /// false otherwise. - /// - /// - /// - /// See for more information and examples - /// of using this method. - /// - /// - /// - virtual public bool IsWarnEnabled - { - get { return Logger.IsEnabledFor(m_levelWarn); } - } - - /// - /// Checks if this logger is enabled for the ERROR level. - /// - /// - /// true if this logger is enabled for ERROR events, - /// false otherwise. - /// - /// - /// - /// See for more information and examples of using this method. - /// - /// - /// - virtual public bool IsErrorEnabled - { - get { return Logger.IsEnabledFor(m_levelError); } - } - - /// - /// Checks if this logger is enabled for the FATAL level. - /// - /// - /// true if this logger is enabled for FATAL events, - /// false otherwise. - /// - /// - /// - /// See for more information and examples of using this method. - /// - /// - /// - virtual public bool IsFatalEnabled - { - get { return Logger.IsEnabledFor(m_levelFatal); } - } - - #endregion Implementation of ILog - - #region Private Methods - - /// - /// Event handler for the event - /// - /// the repository - /// Empty - private void LoggerRepositoryConfigurationChanged(object sender, EventArgs e) - { - ILoggerRepository repository = sender as ILoggerRepository; - if (repository != null) - { - ReloadLevels(repository); - } - } - - #endregion - - #region Private Static Instance Fields - - /// - /// The fully qualified name of this declaring type not the type of any subclass. - /// - private readonly static Type ThisDeclaringType = typeof(LogImpl); - - #endregion Private Static Instance Fields - - #region Private Fields - - private Level m_levelTrace; - private Level m_levelDebug; - private Level m_levelInfo; - private Level m_levelWarn; - private Level m_levelError; - private Level m_levelFatal; - - #endregion - } -} diff --git a/src/log4net/Core/LoggerManager.cs b/src/log4net/Core/LoggerManager.cs deleted file mode 100644 index 02cbb31b..00000000 --- a/src/log4net/Core/LoggerManager.cs +++ /dev/null @@ -1,770 +0,0 @@ -#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 System.Configuration; -using System.Reflection; - -using log4net.Util; -using log4net.Repository; - -namespace log4net.Core -{ - /// - /// Static manager that controls the creation of repositories - /// - /// - /// - /// Static manager that controls the creation of repositories - /// - /// - /// This class is used by the wrapper managers (e.g. ) - /// to provide access to the objects. - /// - /// - /// This manager also holds the that is used to - /// lookup and create repositories. The selector can be set either programmatically using - /// the property, or by setting the log4net.RepositorySelector - /// AppSetting in the applications config file to the fully qualified type name of the - /// selector to use. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class LoggerManager - { - #region Private Instance Constructors - - /// - /// Private constructor to prevent instances. Only static methods should be used. - /// - /// - /// - /// Private constructor to prevent instances. Only static methods should be used. - /// - /// - private LoggerManager() - { - } - - #endregion Private Instance Constructors - - #region Static Constructor - - /// - /// Hook the shutdown event - /// - /// - /// - /// On the full .NET runtime, the static constructor hooks up the - /// AppDomain.ProcessExit and AppDomain.DomainUnload> events. - /// These are used to shutdown the log4net system as the application exits. - /// - /// - static LoggerManager() - { - try - { - // Register the AppDomain events, note we have to do this with a - // method call rather than directly here because the AppDomain - // makes a LinkDemand which throws the exception during the JIT phase. - RegisterAppDomainEvents(); - } - catch(System.Security.SecurityException) - { - LogLog.Debug(declaringType, "Security Exception (ControlAppDomain LinkDemand) while trying "+ - "to register Shutdown handler with the AppDomain. LoggerManager.Shutdown() "+ - "will not be called automatically when the AppDomain exits. It must be called "+ - "programmatically."); - } - - // Dump out our assembly version into the log if debug is enabled - LogLog.Debug(declaringType, GetVersionInfo()); - - // Set the default repository selector -#if NETCF - s_repositorySelector = new CompactRepositorySelector(typeof(log4net.Repository.Hierarchy.Hierarchy)); -#else - - // Look for the RepositorySelector type specified in the AppSettings 'log4net.RepositorySelector' - string appRepositorySelectorTypeName = SystemInfo.GetAppSetting("log4net.RepositorySelector"); - if (appRepositorySelectorTypeName != null && appRepositorySelectorTypeName.Length > 0) - { - // Resolve the config string into a Type - Type appRepositorySelectorType = null; - try - { - appRepositorySelectorType = SystemInfo.GetTypeFromString(appRepositorySelectorTypeName, false, true); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Exception while resolving RepositorySelector Type ["+appRepositorySelectorTypeName+"]", ex); - } - - if (appRepositorySelectorType != null) - { - // Create an instance of the RepositorySelectorType - object appRepositorySelectorObj = null; - try - { - appRepositorySelectorObj = Activator.CreateInstance(appRepositorySelectorType); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Exception while creating RepositorySelector ["+appRepositorySelectorType.FullName+"]", ex); - } - - if (appRepositorySelectorObj != null && appRepositorySelectorObj is IRepositorySelector) - { - s_repositorySelector = (IRepositorySelector)appRepositorySelectorObj; - } - else - { - LogLog.Error(declaringType, "RepositorySelector Type ["+appRepositorySelectorType.FullName+"] is not an IRepositorySelector"); - } - } - } - - // Create the DefaultRepositorySelector if not configured above - if (s_repositorySelector == null) - { - s_repositorySelector = new DefaultRepositorySelector(typeof(log4net.Repository.Hierarchy.Hierarchy)); - } -#endif - } - - /// - /// Register for ProcessExit and DomainUnload events on the AppDomain - /// - /// - /// - /// This needs to be in a separate method because the events make - /// a LinkDemand for the ControlAppDomain SecurityPermission. Because - /// this is a LinkDemand it is demanded at JIT time. Therefore we cannot - /// catch the exception in the method itself, we have to catch it in the - /// caller. - /// - /// - private static void RegisterAppDomainEvents() - { -#if !NETCF - // ProcessExit seems to be fired if we are part of the default domain - AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit); - - // Otherwise DomainUnload is fired - AppDomain.CurrentDomain.DomainUnload += new EventHandler(OnDomainUnload); -#endif - } - - #endregion Static Constructor - - #region Public Static Methods - - /// - /// Return the default instance. - /// - /// the repository to lookup in - /// Return the default instance - /// - /// - /// Gets the for the repository specified - /// by the argument. - /// - /// - public static ILoggerRepository GetRepository(string repository) - { - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - return RepositorySelector.GetRepository(repository); - } - - /// - /// Returns the default instance. - /// - /// The assembly to use to lookup the repository. - /// The default instance. - /// - /// - /// Returns the default instance. - /// - /// - public static ILoggerRepository GetRepository(Assembly repositoryAssembly) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - return RepositorySelector.GetRepository(repositoryAssembly); - } - - /// - /// Returns the named logger if it exists. - /// - /// The repository to lookup in. - /// The fully qualified logger name to look for. - /// - /// The logger found, or null if the named logger does not exist in the - /// specified repository. - /// - /// - /// - /// If the named logger exists (in the specified repository) then it - /// returns a reference to the logger, otherwise it returns - /// null. - /// - /// - public static ILogger Exists(string repository, string name) - { - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - if (name == null) - { - throw new ArgumentNullException("name"); - } - return RepositorySelector.GetRepository(repository).Exists(name); - } - - /// - /// Returns the named logger if it exists. - /// - /// The assembly to use to lookup the repository. - /// The fully qualified logger name to look for. - /// - /// The logger found, or null if the named logger does not exist in the - /// specified assembly's repository. - /// - /// - /// - /// If the named logger exists (in the specified assembly's repository) then it - /// returns a reference to the logger, otherwise it returns - /// null. - /// - /// - public static ILogger Exists(Assembly repositoryAssembly, string name) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - if (name == null) - { - throw new ArgumentNullException("name"); - } - return RepositorySelector.GetRepository(repositoryAssembly).Exists(name); - } - - /// - /// Returns all the currently defined loggers in the specified repository. - /// - /// The repository to lookup in. - /// All the defined loggers. - /// - /// - /// The root logger is not included in the returned array. - /// - /// - public static ILogger[] GetCurrentLoggers(string repository) - { - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - return RepositorySelector.GetRepository(repository).GetCurrentLoggers(); - } - - /// - /// Returns all the currently defined loggers in the specified assembly's repository. - /// - /// The assembly to use to lookup the repository. - /// All the defined loggers. - /// - /// - /// The root logger is not included in the returned array. - /// - /// - public static ILogger[] GetCurrentLoggers(Assembly repositoryAssembly) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - return RepositorySelector.GetRepository(repositoryAssembly).GetCurrentLoggers(); - } - - /// - /// Retrieves or creates a named logger. - /// - /// The repository to lookup in. - /// The name of the logger to retrieve. - /// The logger with the name specified. - /// - /// - /// Retrieves a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// - public static ILogger GetLogger(string repository, string name) - { - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - if (name == null) - { - throw new ArgumentNullException("name"); - } - return RepositorySelector.GetRepository(repository).GetLogger(name); - } - - /// - /// Retrieves or creates a named logger. - /// - /// The assembly to use to lookup the repository. - /// The name of the logger to retrieve. - /// The logger with the name specified. - /// - /// - /// Retrieves a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// - public static ILogger GetLogger(Assembly repositoryAssembly, string name) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - if (name == null) - { - throw new ArgumentNullException("name"); - } - return RepositorySelector.GetRepository(repositoryAssembly).GetLogger(name); - } - - /// - /// Shorthand for . - /// - /// The repository to lookup in. - /// The of which the fullname will be used as the name of the logger to retrieve. - /// The logger with the name specified. - /// - /// - /// Gets the logger for the fully qualified name of the type specified. - /// - /// - public static ILogger GetLogger(string repository, Type type) - { - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - if (type == null) - { - throw new ArgumentNullException("type"); - } - return RepositorySelector.GetRepository(repository).GetLogger(type.FullName); - } - - /// - /// Shorthand for . - /// - /// the assembly to use to lookup the repository - /// The of which the fullname will be used as the name of the logger to retrieve. - /// The logger with the name specified. - /// - /// - /// Gets the logger for the fully qualified name of the type specified. - /// - /// - public static ILogger GetLogger(Assembly repositoryAssembly, Type type) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - if (type == null) - { - throw new ArgumentNullException("type"); - } - return RepositorySelector.GetRepository(repositoryAssembly).GetLogger(type.FullName); - } - - /// - /// Shuts down the log4net system. - /// - /// - /// - /// Calling this method will safely close and remove all - /// appenders in all the loggers including root contained in all the - /// default repositories. - /// - /// - /// Some appenders need to be closed before the application exists. - /// Otherwise, pending logging events might be lost. - /// - /// - /// The shutdown method is careful to close nested - /// appenders before closing regular appenders. This is allows - /// configurations where a regular appender is attached to a logger - /// and again to a nested appender. - /// - /// - public static void Shutdown() - { - foreach(ILoggerRepository repository in GetAllRepositories()) - { - repository.Shutdown(); - } - } - - /// - /// Shuts down the repository for the repository specified. - /// - /// The repository to shutdown. - /// - /// - /// Calling this method will safely close and remove all - /// appenders in all the loggers including root contained in the - /// repository for the specified. - /// - /// - /// Some appenders need to be closed before the application exists. - /// Otherwise, pending logging events might be lost. - /// - /// - /// The shutdown method is careful to close nested - /// appenders before closing regular appenders. This is allows - /// configurations where a regular appender is attached to a logger - /// and again to a nested appender. - /// - /// - public static void ShutdownRepository(string repository) - { - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - RepositorySelector.GetRepository(repository).Shutdown(); - } - - /// - /// Shuts down the repository for the repository specified. - /// - /// The assembly to use to lookup the repository. - /// - /// - /// Calling this method will safely close and remove all - /// appenders in all the loggers including root contained in the - /// repository for the repository. The repository is looked up using - /// the specified. - /// - /// - /// Some appenders need to be closed before the application exists. - /// Otherwise, pending logging events might be lost. - /// - /// - /// The shutdown method is careful to close nested - /// appenders before closing regular appenders. This is allows - /// configurations where a regular appender is attached to a logger - /// and again to a nested appender. - /// - /// - public static void ShutdownRepository(Assembly repositoryAssembly) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - RepositorySelector.GetRepository(repositoryAssembly).Shutdown(); - } - - /// - /// Resets all values contained in this repository instance to their defaults. - /// - /// The repository to reset. - /// - /// - /// Resets all values contained in the repository instance to their - /// defaults. This removes all appenders from all loggers, sets - /// the level of all non-root loggers to null, - /// sets their additivity flag to true and sets the level - /// of the root logger to . Moreover, - /// message disabling is set its default "off" value. - /// - /// - public static void ResetConfiguration(string repository) - { - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - RepositorySelector.GetRepository(repository).ResetConfiguration(); - } - - /// - /// Resets all values contained in this repository instance to their defaults. - /// - /// The assembly to use to lookup the repository to reset. - /// - /// - /// Resets all values contained in the repository instance to their - /// defaults. This removes all appenders from all loggers, sets - /// the level of all non-root loggers to null, - /// sets their additivity flag to true and sets the level - /// of the root logger to . Moreover, - /// message disabling is set its default "off" value. - /// - /// - public static void ResetConfiguration(Assembly repositoryAssembly) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - RepositorySelector.GetRepository(repositoryAssembly).ResetConfiguration(); - } - - /// - /// Creates a repository with the specified name. - /// - /// The name of the repository, this must be unique amongst repositories. - /// The created for the repository. - /// - /// - /// Creates the default type of which is a - /// object. - /// - /// - /// The name must be unique. Repositories cannot be redefined. - /// An will be thrown if the repository already exists. - /// - /// - /// The specified repository already exists. - public static ILoggerRepository CreateRepository(string repository) - { - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - return RepositorySelector.CreateRepository(repository, null); - } - - /// - /// Creates a repository with the specified name and repository type. - /// - /// The name of the repository, this must be unique to the repository. - /// A that implements - /// and has a no arg constructor. An instance of this type will be created to act - /// as the for the repository specified. - /// The created for the repository. - /// - /// - /// The name must be unique. Repositories cannot be redefined. - /// An Exception will be thrown if the repository already exists. - /// - /// - /// The specified repository already exists. - public static ILoggerRepository CreateRepository(string repository, Type repositoryType) - { - if (repository == null) - { - throw new ArgumentNullException("repository"); - } - if (repositoryType == null) - { - throw new ArgumentNullException("repositoryType"); - } - return RepositorySelector.CreateRepository(repository, repositoryType); - } - - /// - /// Creates a repository for the specified assembly and repository type. - /// - /// The assembly to use to get the name of the repository. - /// A that implements - /// and has a no arg constructor. An instance of this type will be created to act - /// as the for the repository specified. - /// The created for the repository. - /// - /// - /// The created will be associated with the repository - /// specified such that a call to with the - /// same assembly specified will return the same repository instance. - /// - /// - public static ILoggerRepository CreateRepository(Assembly repositoryAssembly, Type repositoryType) - { - if (repositoryAssembly == null) - { - throw new ArgumentNullException("repositoryAssembly"); - } - if (repositoryType == null) - { - throw new ArgumentNullException("repositoryType"); - } - return RepositorySelector.CreateRepository(repositoryAssembly, repositoryType); - } - - /// - /// Gets an array of all currently defined repositories. - /// - /// An array of all the known objects. - /// - /// - /// Gets an array of all currently defined repositories. - /// - /// - public static ILoggerRepository[] GetAllRepositories() - { - return RepositorySelector.GetAllRepositories(); - } - - /// - /// Gets or sets the repository selector used by the . - /// - /// - /// The repository selector used by the . - /// - /// - /// - /// The repository selector () is used by - /// the to create and select repositories - /// (). - /// - /// - /// The caller to supplies either a string name - /// or an assembly (if not supplied the assembly is inferred using - /// ). - /// - /// - /// This context is used by the selector to lookup a specific repository. - /// - /// - /// For the full .NET Framework, the default repository is DefaultRepositorySelector; - /// for the .NET Compact Framework CompactRepositorySelector is the default - /// repository. - /// - /// - public static IRepositorySelector RepositorySelector - { - get { return s_repositorySelector; } - set { s_repositorySelector = value; } - } - - #endregion Public Static Methods - - #region Private Static Methods - - /// - /// Internal method to get pertinent version info. - /// - /// A string of version info. - private static string GetVersionInfo() - { - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - - // Grab the currently executing assembly - Assembly myAssembly = Assembly.GetExecutingAssembly(); - - // Build Up message - sb.Append("log4net assembly [").Append(myAssembly.FullName).Append("]. "); - sb.Append("Loaded from [").Append(SystemInfo.AssemblyLocationInfo(myAssembly)).Append("]. "); - sb.Append("(.NET Runtime [").Append(Environment.Version.ToString()).Append("]"); - sb.Append(" on ").Append(Environment.OSVersion.ToString()); - sb.Append(")"); - return sb.ToString(); - } - -#if (!NETCF) - /// - /// Called when the event fires - /// - /// the that is exiting - /// null - /// - /// - /// Called when the event fires. - /// - /// - /// When the event is triggered the log4net system is . - /// - /// - private static void OnDomainUnload(object sender, EventArgs e) - { - Shutdown(); - } - - /// - /// Called when the event fires - /// - /// the that is exiting - /// null - /// - /// - /// Called when the event fires. - /// - /// - /// When the event is triggered the log4net system is . - /// - /// - private static void OnProcessExit(object sender, EventArgs e) - { - Shutdown(); - } -#endif - - #endregion Private Static Methods - - #region Private Static Fields - - /// - /// The fully qualified type of the LoggerManager class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(LoggerManager); - - /// - /// Initialize the default repository selector - /// - private static IRepositorySelector s_repositorySelector; - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Core/LoggerWrapperImpl.cs b/src/log4net/Core/LoggerWrapperImpl.cs deleted file mode 100644 index fff496d0..00000000 --- a/src/log4net/Core/LoggerWrapperImpl.cs +++ /dev/null @@ -1,86 +0,0 @@ -#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 - -namespace log4net.Core -{ - /// - /// Implementation of the interface. - /// - /// - /// - /// This class should be used as the base for all wrapper implementations. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public abstract class LoggerWrapperImpl : ILoggerWrapper - { - #region Protected Instance Constructors - - /// - /// Constructs a new wrapper for the specified logger. - /// - /// The logger to wrap. - /// - /// - /// Constructs a new wrapper for the specified logger. - /// - /// - protected LoggerWrapperImpl(ILogger logger) - { - m_logger = logger; - } - - #endregion Public Instance Constructors - - #region Implementation of ILoggerWrapper - - /// - /// Gets the implementation behind this wrapper object. - /// - /// - /// The object that this object is implementing. - /// - /// - /// - /// The Logger object may not be the same object as this object - /// because of logger decorators. - /// - /// - /// This gets the actual underlying objects that is used to process - /// the log events. - /// - /// - virtual public ILogger Logger - { - get { return m_logger; } - } - - #endregion - - #region Private Instance Fields - - /// - /// The logger that this object is wrapping - /// - private readonly ILogger m_logger; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Core/LoggingEvent.cs b/src/log4net/Core/LoggingEvent.cs deleted file mode 100644 index 6b270661..00000000 --- a/src/log4net/Core/LoggingEvent.cs +++ /dev/null @@ -1,1453 +0,0 @@ -#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 System.Collections; -using System.IO; -#if (!NETCF) -using System.Runtime.Serialization; -using System.Security.Principal; -#endif - -using log4net.Util; -using log4net.Repository; - -namespace log4net.Core -{ - /// - /// Portable data structure used by - /// - /// - /// - /// Portable data structure used by - /// - /// - /// Nicko Cadell - public struct LoggingEventData - { - #region Public Instance Fields - - /// - /// The logger name. - /// - /// - /// - /// The logger name. - /// - /// - public string LoggerName; - - /// - /// Level of logging event. - /// - /// - /// - /// Level of logging event. Level cannot be Serializable - /// because it is a flyweight. Due to its special serialization it - /// cannot be declared final either. - /// - /// - public Level Level; - - /// - /// The application supplied message. - /// - /// - /// - /// The application supplied message of logging event. - /// - /// - public string Message; - - /// - /// The name of thread - /// - /// - /// - /// The name of thread in which this logging event was generated - /// - /// - public string ThreadName; - - /// - /// The time the event was logged - /// - /// - /// - /// The TimeStamp is stored in the local time zone for this computer. - /// - /// - public DateTime TimeStamp; - - /// - /// Location information for the caller. - /// - /// - /// - /// Location information for the caller. - /// - /// - public LocationInfo LocationInfo; - - /// - /// String representation of the user - /// - /// - /// - /// String representation of the user's windows name, - /// like DOMAIN\username - /// - /// - public string UserName; - - /// - /// String representation of the identity. - /// - /// - /// - /// String representation of the current thread's principal identity. - /// - /// - public string Identity; - - /// - /// The string representation of the exception - /// - /// - /// - /// The string representation of the exception - /// - /// - public string ExceptionString; - - /// - /// String representation of the AppDomain. - /// - /// - /// - /// String representation of the AppDomain. - /// - /// - public string Domain; - - /// - /// Additional event specific properties - /// - /// - /// - /// A logger or an appender may attach additional - /// properties to specific events. These properties - /// have a string key and an object value. - /// - /// - public PropertiesDictionary Properties; - - #endregion Public Instance Fields - } - - /// - /// Flags passed to the property - /// - /// - /// - /// Flags passed to the property - /// - /// - /// Nicko Cadell - [Flags] public enum FixFlags - { - /// - /// Fix the NDC - /// - Ndc = 0x02, - - /// - /// Fix the rendered message - /// - Message = 0x04, - - /// - /// Fix the thread name - /// - ThreadName = 0x08, - - /// - /// Fix the callers location information - /// - /// - /// CAUTION: Very slow to generate - /// - LocationInfo = 0x10, - - /// - /// Fix the callers windows user name - /// - /// - /// CAUTION: Slow to generate - /// - UserName = 0x20, - - /// - /// Fix the domain friendly name - /// - Domain = 0x40, - - /// - /// Fix the callers principal name - /// - /// - /// CAUTION: May be slow to generate - /// - Identity = 0x80, - - /// - /// Fix the exception text - /// - Exception = 0x100, - - /// - /// Fix the event properties. Active properties must implement in order to be eligible for fixing. - /// - Properties = 0x200, - - /// - /// No fields fixed - /// - None = 0x0, - - /// - /// All fields fixed - /// - All = 0xFFFFFFF, - - /// - /// Partial fields fixed - /// - /// - /// - /// This set of partial fields gives good performance. The following fields are fixed: - /// - /// - /// - /// - /// - /// - /// - /// - /// - Partial = Message | ThreadName | Exception | Domain | Properties, - } - - /// - /// The internal representation of logging events. - /// - /// - /// - /// When an affirmative decision is made to log then a - /// instance is created. This instance - /// is passed around to the different log4net components. - /// - /// - /// This class is of concern to those wishing to extend log4net. - /// - /// - /// Some of the values in instances of - /// are considered volatile, that is the values are correct at the - /// time the event is delivered to appenders, but will not be consistent - /// at any time afterwards. If an event is to be stored and then processed - /// at a later time these volatile values must be fixed by calling - /// . There is a performance penalty - /// for incurred by calling but it - /// is essential to maintaining data consistency. - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Douglas de la Torre - /// Daniel Cazzulino -#if !NETCF - [Serializable] -#endif - public class LoggingEvent -#if !NETCF - : ISerializable -#endif - { - private readonly static Type declaringType = typeof(LoggingEvent); - - #region Public Instance Constructors - - /// - /// Initializes a new instance of the class - /// from the supplied parameters. - /// - /// The declaring type of the method that is - /// the stack boundary into the logging system for this call. - /// The repository this event is logged in. - /// The name of the logger of this event. - /// The level of this event. - /// The message of this event. - /// The exception for this event. - /// - /// - /// Except , and , - /// all fields of LoggingEvent are filled when actually needed. Call - /// to cache all data locally - /// to prevent inconsistencies. - /// - /// This method is called by the log4net framework - /// to create a logging event. - /// - /// - public LoggingEvent(Type callerStackBoundaryDeclaringType, log4net.Repository.ILoggerRepository repository, string loggerName, Level level, object message, Exception exception) - { - m_callerStackBoundaryDeclaringType = callerStackBoundaryDeclaringType; - m_message = message; - m_repository = repository; - m_thrownException = exception; - - m_data.LoggerName = loggerName; - m_data.Level = level; - - // Store the event creation time - m_data.TimeStamp = DateTime.Now; - } - - /// - /// Initializes a new instance of the class - /// using specific data. - /// - /// The declaring type of the method that is - /// the stack boundary into the logging system for this call. - /// The repository this event is logged in. - /// Data used to initialize the logging event. - /// The fields in the struct that have already been fixed. - /// - /// - /// This constructor is provided to allow a - /// to be created independently of the log4net framework. This can - /// be useful if you require a custom serialization scheme. - /// - /// - /// Use the method to obtain an - /// instance of the class. - /// - /// - /// The parameter should be used to specify which fields in the - /// struct have been preset. Fields not specified in the - /// will be captured from the environment if requested or fixed. - /// - /// - public LoggingEvent(Type callerStackBoundaryDeclaringType, log4net.Repository.ILoggerRepository repository, LoggingEventData data, FixFlags fixedData) - { - m_callerStackBoundaryDeclaringType = callerStackBoundaryDeclaringType; - m_repository = repository; - - m_data = data; - m_fixFlags = fixedData; - } - - /// - /// Initializes a new instance of the class - /// using specific data. - /// - /// The declaring type of the method that is - /// the stack boundary into the logging system for this call. - /// The repository this event is logged in. - /// Data used to initialize the logging event. - /// - /// - /// This constructor is provided to allow a - /// to be created independently of the log4net framework. This can - /// be useful if you require a custom serialization scheme. - /// - /// - /// Use the method to obtain an - /// instance of the class. - /// - /// - /// This constructor sets this objects flags to , - /// this assumes that all the data relating to this event is passed in via the - /// parameter and no other data should be captured from the environment. - /// - /// - public LoggingEvent(Type callerStackBoundaryDeclaringType, log4net.Repository.ILoggerRepository repository, LoggingEventData data) : this(callerStackBoundaryDeclaringType, repository, data, FixFlags.All) - { - } - - /// - /// Initializes a new instance of the class - /// using specific data. - /// - /// Data used to initialize the logging event. - /// - /// - /// This constructor is provided to allow a - /// to be created independently of the log4net framework. This can - /// be useful if you require a custom serialization scheme. - /// - /// - /// Use the method to obtain an - /// instance of the class. - /// - /// - /// This constructor sets this objects flags to , - /// this assumes that all the data relating to this event is passed in via the - /// parameter and no other data should be captured from the environment. - /// - /// - public LoggingEvent(LoggingEventData data) : this(null, null, data) - { - } - - #endregion Public Instance Constructors - - #region Protected Instance Constructors - -#if !NETCF - - /// - /// Serialization constructor - /// - /// The that holds the serialized object data. - /// The that contains contextual information about the source or destination. - /// - /// - /// Initializes a new instance of the class - /// with serialized data. - /// - /// - protected LoggingEvent(SerializationInfo info, StreamingContext context) - { - m_data.LoggerName = info.GetString("LoggerName"); - - // Note we are deserializing the whole level object. That is the - // name and the value. This value is correct for the source - // hierarchy but may not be for the target hierarchy that this - // event may be re-logged into. If it is to be re-logged it may - // be necessary to re-lookup the level based only on the name. - m_data.Level = (Level)info.GetValue("Level", typeof(Level)); - - m_data.Message = info.GetString("Message"); - m_data.ThreadName = info.GetString("ThreadName"); - m_data.TimeStamp = info.GetDateTime("TimeStamp"); - m_data.LocationInfo = (LocationInfo) info.GetValue("LocationInfo", typeof(LocationInfo)); - m_data.UserName = info.GetString("UserName"); - m_data.ExceptionString = info.GetString("ExceptionString"); - m_data.Properties = (PropertiesDictionary) info.GetValue("Properties", typeof(PropertiesDictionary)); - m_data.Domain = info.GetString("Domain"); - m_data.Identity = info.GetString("Identity"); - - // We have restored all the values of this instance, i.e. all the values are fixed - // Set the fix flags otherwise the data values may be overwritten from the current environment. - m_fixFlags = FixFlags.All; - } - -#endif - - #endregion Protected Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the time when the current process started. - /// - /// - /// This is the time when this process started. - /// - /// - /// - /// The TimeStamp is stored in the local time zone for this computer. - /// - /// - /// Tries to get the start time for the current process. - /// Failing that it returns the time of the first call to - /// this property. - /// - /// - /// Note that AppDomains may be loaded and unloaded within the - /// same process without the process terminating and therefore - /// without the process start time being reset. - /// - /// - public static DateTime StartTime - { - get { return SystemInfo.ProcessStartTime; } - } - - /// - /// Gets the of the logging event. - /// - /// - /// The of the logging event. - /// - /// - /// - /// Gets the of the logging event. - /// - /// - public Level Level - { - get { return m_data.Level; } - } - - /// - /// Gets the time of the logging event. - /// - /// - /// The time of the logging event. - /// - /// - /// - /// The TimeStamp is stored in the local time zone for this computer. - /// - /// - public DateTime TimeStamp - { - get { return m_data.TimeStamp; } - } - - /// - /// Gets the name of the logger that logged the event. - /// - /// - /// The name of the logger that logged the event. - /// - /// - /// - /// Gets the name of the logger that logged the event. - /// - /// - public string LoggerName - { - get { return m_data.LoggerName; } - } - - /// - /// Gets the location information for this logging event. - /// - /// - /// The location information for this logging event. - /// - /// - /// - /// The collected information is cached for future use. - /// - /// - /// See the class for more information on - /// supported frameworks and the different behavior in Debug and - /// Release builds. - /// - /// - public LocationInfo LocationInformation - { - get - { - if (m_data.LocationInfo == null && this.m_cacheUpdatable) - { - m_data.LocationInfo = new LocationInfo(m_callerStackBoundaryDeclaringType); - } - return m_data.LocationInfo; - } - } - - /// - /// Gets the message object used to initialize this event. - /// - /// - /// The message object used to initialize this event. - /// - /// - /// - /// Gets the message object used to initialize this event. - /// Note that this event may not have a valid message object. - /// If the event is serialized the message object will not - /// be transferred. To get the text of the message the - /// property must be used - /// not this property. - /// - /// - /// If there is no defined message object for this event then - /// null will be returned. - /// - /// - public object MessageObject - { - get { return m_message; } - } - - /// - /// Gets the exception object used to initialize this event. - /// - /// - /// The exception object used to initialize this event. - /// - /// - /// - /// Gets the exception object used to initialize this event. - /// Note that this event may not have a valid exception object. - /// If the event is serialized the exception object will not - /// be transferred. To get the text of the exception the - /// method must be used - /// not this property. - /// - /// - /// If there is no defined exception object for this event then - /// null will be returned. - /// - /// - public Exception ExceptionObject - { - get { return m_thrownException; } - } - - /// - /// The that this event was created in. - /// - /// - /// - /// The that this event was created in. - /// - /// - public ILoggerRepository Repository - { - get { return m_repository; } - } - - /// - /// Ensure that the repository is set. - /// - /// the value for the repository - internal void EnsureRepository(ILoggerRepository repository) - { - if (repository != null) - { - m_repository = repository; - } - } - - /// - /// Gets the message, rendered through the . - /// - /// - /// The message rendered through the . - /// - /// - /// - /// The collected information is cached for future use. - /// - /// - public string RenderedMessage - { - get - { - if (m_data.Message == null && this.m_cacheUpdatable) - { - if (m_message == null) - { - m_data.Message = ""; - } - else if (m_message is string) - { - m_data.Message = (m_message as string); - } - else if (m_repository != null) - { - m_data.Message = m_repository.RendererMap.FindAndRender(m_message); - } - else - { - // Very last resort - m_data.Message = m_message.ToString(); - } - } - return m_data.Message; - } - } - - /// - /// Write the rendered message to a TextWriter - /// - /// the writer to write the message to - /// - /// - /// Unlike the property this method - /// does store the message data in the internal cache. Therefore - /// if called only once this method should be faster than the - /// property, however if the message is - /// to be accessed multiple times then the property will be more efficient. - /// - /// - public void WriteRenderedMessage(TextWriter writer) - { - if (m_data.Message != null) - { - writer.Write(m_data.Message); - } - else - { - if (m_message != null) - { - if (m_message is string) - { - writer.Write(m_message as string); - } - else if (m_repository != null) - { - m_repository.RendererMap.FindAndRender(m_message, writer); - } - else - { - // Very last resort - writer.Write(m_message.ToString()); - } - } - } - } - - /// - /// Gets the name of the current thread. - /// - /// - /// The name of the current thread, or the thread ID when - /// the name is not available. - /// - /// - /// - /// The collected information is cached for future use. - /// - /// - public string ThreadName - { - get - { - if (m_data.ThreadName == null && this.m_cacheUpdatable) - { -#if NETCF - // Get thread ID only - m_data.ThreadName = SystemInfo.CurrentThreadId.ToString(System.Globalization.NumberFormatInfo.InvariantInfo); -#else - m_data.ThreadName = System.Threading.Thread.CurrentThread.Name; - if (m_data.ThreadName == null || m_data.ThreadName.Length == 0) - { - // The thread name is not available. Therefore we - // go the the AppDomain to get the ID of the - // current thread. (Why don't Threads know their own ID?) - try - { - m_data.ThreadName = SystemInfo.CurrentThreadId.ToString(System.Globalization.NumberFormatInfo.InvariantInfo); - } - catch(System.Security.SecurityException) - { - // This security exception will occur if the caller does not have - // some undefined set of SecurityPermission flags. - LogLog.Debug(declaringType, "Security exception while trying to get current thread ID. Error Ignored. Empty thread name."); - - // As a last resort use the hash code of the Thread object - m_data.ThreadName = System.Threading.Thread.CurrentThread.GetHashCode().ToString(System.Globalization.CultureInfo.InvariantCulture); - } - } -#endif - } - return m_data.ThreadName; - } - } - - /// - /// Gets the name of the current user. - /// - /// - /// The name of the current user, or NOT AVAILABLE when the - /// underlying runtime has no support for retrieving the name of the - /// current user. - /// - /// - /// - /// Calls WindowsIdentity.GetCurrent().Name to get the name of - /// the current windows user. - /// - /// - /// To improve performance, we could cache the string representation of - /// the name, and reuse that as long as the identity stayed constant. - /// Once the identity changed, we would need to re-assign and re-render - /// the string. - /// - /// - /// However, the WindowsIdentity.GetCurrent() call seems to - /// return different objects every time, so the current implementation - /// doesn't do this type of caching. - /// - /// - /// Timing for these operations: - /// - /// - /// - /// Method - /// Results - /// - /// - /// WindowsIdentity.GetCurrent() - /// 10000 loops, 00:00:00.2031250 seconds - /// - /// - /// WindowsIdentity.GetCurrent().Name - /// 10000 loops, 00:00:08.0468750 seconds - /// - /// - /// - /// This means we could speed things up almost 40 times by caching the - /// value of the WindowsIdentity.GetCurrent().Name property, since - /// this takes (8.04-0.20) = 7.84375 seconds. - /// - /// - public string UserName - { - get - { - if (m_data.UserName == null && this.m_cacheUpdatable) - { -#if NETCF - // On compact framework there's no notion of current Windows user - m_data.UserName = SystemInfo.NotAvailableText; -#else - try - { - WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent(); - if (windowsIdentity != null && windowsIdentity.Name != null) - { - m_data.UserName = windowsIdentity.Name; - } - else - { - m_data.UserName = ""; - } - } - catch(System.Security.SecurityException) - { - // This security exception will occur if the caller does not have - // some undefined set of SecurityPermission flags. - LogLog.Debug(declaringType, "Security exception while trying to get current windows identity. Error Ignored. Empty user name."); - - m_data.UserName = ""; - } -#endif - } - return m_data.UserName; - } - } - - /// - /// Gets the identity of the current thread principal. - /// - /// - /// The string name of the identity of the current thread principal. - /// - /// - /// - /// Calls System.Threading.Thread.CurrentPrincipal.Identity.Name to get - /// the name of the current thread principal. - /// - /// - public string Identity - { - get - { - if (m_data.Identity == null && this.m_cacheUpdatable) - { -#if NETCF - // On compact framework there's no notion of current thread principals - m_data.Identity = SystemInfo.NotAvailableText; -#else - try - { - if (System.Threading.Thread.CurrentPrincipal != null && - System.Threading.Thread.CurrentPrincipal.Identity != null && - System.Threading.Thread.CurrentPrincipal.Identity.Name != null) - { - m_data.Identity = System.Threading.Thread.CurrentPrincipal.Identity.Name; - } - else - { - m_data.Identity = ""; - } - } - catch (ObjectDisposedException) - { - // This exception will occur if System.Threading.Thread.CurrentPrincipal.Identity is not null but - // the getter of the property Name tries to access disposed objects. - // Seen to happen on IIS 7 or greater with windows authentication. - LogLog.Debug(declaringType, "Object disposed exception while trying to get current thread principal. Error Ignored. Empty identity name."); - - m_data.Identity = ""; - } - catch (System.Security.SecurityException) - { - // This security exception will occur if the caller does not have - // some undefined set of SecurityPermission flags. - LogLog.Debug(declaringType, "Security exception while trying to get current thread principal. Error Ignored. Empty identity name."); - - m_data.Identity = ""; - } -#endif - } - return m_data.Identity; - } - } - - /// - /// Gets the AppDomain friendly name. - /// - /// - /// The AppDomain friendly name. - /// - /// - /// - /// Gets the AppDomain friendly name. - /// - /// - public string Domain - { - get - { - if (m_data.Domain == null && this.m_cacheUpdatable) - { - m_data.Domain = SystemInfo.ApplicationFriendlyName; - } - return m_data.Domain; - } - } - - /// - /// Additional event specific properties. - /// - /// - /// Additional event specific properties. - /// - /// - /// - /// A logger or an appender may attach additional - /// properties to specific events. These properties - /// have a string key and an object value. - /// - /// - /// This property is for events that have been added directly to - /// this event. The aggregate properties (which include these - /// event properties) can be retrieved using - /// and . - /// - /// - /// Once the properties have been fixed this property - /// returns the combined cached properties. This ensures that updates to - /// this property are always reflected in the underlying storage. When - /// returning the combined properties there may be more keys in the - /// Dictionary than expected. - /// - /// - public PropertiesDictionary Properties - { - get - { - // If we have cached properties then return that otherwise changes will be lost - if (m_data.Properties != null) - { - return m_data.Properties; - } - - if (m_eventProperties == null) - { - m_eventProperties = new PropertiesDictionary(); - } - return m_eventProperties; - } - } - - /// - /// The fixed fields in this event - /// - /// - /// The set of fields that are fixed in this event - /// - /// - /// - /// Fields will not be fixed if they have previously been fixed. - /// It is not possible to 'unfix' a field. - /// - /// - public FixFlags Fix - { - get { return m_fixFlags; } - set { this.FixVolatileData(value); } - } - - #endregion Public Instance Properties - - #region Implementation of ISerializable - -#if !NETCF - - /// - /// Serializes this object into the provided. - /// - /// The to populate with data. - /// The destination for this serialization. - /// - /// - /// The data in this event must be fixed before it can be serialized. - /// - /// - /// The method must be called during the - /// method call if this event - /// is to be used outside that method. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecurityCritical] -#else - [System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.Demand, SerializationFormatter=true)] -#endif - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - // The caller must call FixVolatileData before this object - // can be serialized. - - info.AddValue("LoggerName", m_data.LoggerName); - info.AddValue("Level", m_data.Level); - info.AddValue("Message", m_data.Message); - info.AddValue("ThreadName", m_data.ThreadName); - info.AddValue("TimeStamp", m_data.TimeStamp); - info.AddValue("LocationInfo", m_data.LocationInfo); - info.AddValue("UserName", m_data.UserName); - info.AddValue("ExceptionString", m_data.ExceptionString); - info.AddValue("Properties", m_data.Properties); - info.AddValue("Domain", m_data.Domain); - info.AddValue("Identity", m_data.Identity); - } - -#endif - - #endregion Implementation of ISerializable - - #region Public Instance Methods - - /// - /// Gets the portable data for this . - /// - /// The for this event. - /// - /// - /// A new can be constructed using a - /// instance. - /// - /// - /// Does a fix of the data - /// in the logging event before returning the event data. - /// - /// - public LoggingEventData GetLoggingEventData() - { - return GetLoggingEventData(FixFlags.Partial); - } - - /// - /// Gets the portable data for this . - /// - /// The set of data to ensure is fixed in the LoggingEventData - /// The for this event. - /// - /// - /// A new can be constructed using a - /// instance. - /// - /// - public LoggingEventData GetLoggingEventData(FixFlags fixFlags) - { - Fix = fixFlags; - return m_data; - } - - /// - /// Returns this event's exception's rendered using the - /// . - /// - /// - /// This event's exception's rendered using the . - /// - /// - /// - /// Returns this event's exception's rendered using the - /// . - /// - /// - public string GetExceptionString() - { - if (m_data.ExceptionString == null && this.m_cacheUpdatable) - { - if (m_thrownException != null) - { - if (m_repository != null) - { - // Render exception using the repositories renderer map - m_data.ExceptionString = m_repository.RendererMap.FindAndRender(m_thrownException); - } - else - { - // Very last resort - m_data.ExceptionString = m_thrownException.ToString(); - } - } - else - { - m_data.ExceptionString = ""; - } - } - return m_data.ExceptionString; - } - - /// - /// Fix the fields specified by the parameter - /// - /// the fields to fix - /// - /// - /// Only fields specified in the will be fixed. - /// Fields will not be fixed if they have previously been fixed. - /// It is not possible to 'unfix' a field. - /// - /// - protected void FixVolatileData(FixFlags flags) - { - object forceCreation = null; - - //Unlock the cache so that new values can be stored - //This may not be ideal if we are no longer in the correct context - //and someone calls fix. - m_cacheUpdatable=true; - - // determine the flags that we are actually fixing - FixFlags updateFlags = (FixFlags)((flags ^ m_fixFlags) & flags); - - if (updateFlags > 0) - { - if ((updateFlags & FixFlags.Message) != 0) - { - // Force the message to be rendered - forceCreation = this.RenderedMessage; - - m_fixFlags |= FixFlags.Message; - } - if ((updateFlags & FixFlags.ThreadName) != 0) - { - // Grab the thread name - forceCreation = this.ThreadName; - - m_fixFlags |= FixFlags.ThreadName; - } - - if ((updateFlags & FixFlags.LocationInfo) != 0) - { - // Force the location information to be loaded - forceCreation = this.LocationInformation; - - m_fixFlags |= FixFlags.LocationInfo; - } - if ((updateFlags & FixFlags.UserName) != 0) - { - // Grab the user name - forceCreation = this.UserName; - - m_fixFlags |= FixFlags.UserName; - } - if ((updateFlags & FixFlags.Domain) != 0) - { - // Grab the domain name - forceCreation = this.Domain; - - m_fixFlags |= FixFlags.Domain; - } - if ((updateFlags & FixFlags.Identity) != 0) - { - // Grab the identity - forceCreation = this.Identity; - - m_fixFlags |= FixFlags.Identity; - } - - if ((updateFlags & FixFlags.Exception) != 0) - { - // Force the exception text to be loaded - forceCreation = GetExceptionString(); - - m_fixFlags |= FixFlags.Exception; - } - - if ((updateFlags & FixFlags.Properties) != 0) - { - CacheProperties(); - - m_fixFlags |= FixFlags.Properties; - } - } - - // avoid warning CS0219 - if (forceCreation != null) - { - } - - //Finaly lock everything we've cached. - m_cacheUpdatable=false; - } - - #endregion Public Instance Methods - - #region Protected Instance Methods - - private void CreateCompositeProperties() - { - m_compositeProperties = new CompositeProperties(); - - if (m_eventProperties != null) - { - m_compositeProperties.Add(m_eventProperties); - } -#if !NETCF - PropertiesDictionary logicalThreadProperties = LogicalThreadContext.Properties.GetProperties(false); - if (logicalThreadProperties != null) - { - m_compositeProperties.Add(logicalThreadProperties); - } -#endif - PropertiesDictionary threadProperties = ThreadContext.Properties.GetProperties(false); - if (threadProperties != null) - { - m_compositeProperties.Add(threadProperties); - } - - // TODO: Add Repository Properties - - // event properties - PropertiesDictionary eventProperties = new PropertiesDictionary(); - eventProperties[UserNameProperty] = UserName; - eventProperties[IdentityProperty] = Identity; - m_compositeProperties.Add(eventProperties); - - m_compositeProperties.Add(GlobalContext.Properties.GetReadOnlyProperties()); - } - - private void CacheProperties() - { - if (m_data.Properties == null && this.m_cacheUpdatable) - { - if (m_compositeProperties == null) - { - CreateCompositeProperties(); - } - - PropertiesDictionary flattenedProperties = m_compositeProperties.Flatten(); - - PropertiesDictionary fixedProperties = new PropertiesDictionary(); - - // Validate properties - foreach(DictionaryEntry entry in flattenedProperties) - { - string key = entry.Key as string; - - if (key != null) - { - object val = entry.Value; - - // Fix any IFixingRequired objects - IFixingRequired fixingRequired = val as IFixingRequired; - if (fixingRequired != null) - { - val = fixingRequired.GetFixedObject(); - } - - // Strip keys with null values - if (val != null) - { - fixedProperties[key] = val; - } - } - } - - m_data.Properties = fixedProperties; - } - } - - /// - /// Lookup a composite property in this event - /// - /// the key for the property to lookup - /// the value for the property - /// - /// - /// This event has composite properties that combine together properties from - /// several different contexts in the following order: - /// - /// - /// this events properties - /// - /// This event has that can be set. These - /// properties are specific to this event only. - /// - /// - /// - /// the thread properties - /// - /// The that are set on the current - /// thread. These properties are shared by all events logged on this thread. - /// - /// - /// - /// the global properties - /// - /// The that are set globally. These - /// properties are shared by all the threads in the AppDomain. - /// - /// - /// - /// - /// - public object LookupProperty(string key) - { - if (m_data.Properties != null) - { - return m_data.Properties[key]; - } - if (m_compositeProperties == null) - { - CreateCompositeProperties(); - } - return m_compositeProperties[key]; - } - - /// - /// Get all the composite properties in this event - /// - /// the containing all the properties - /// - /// - /// See for details of the composite properties - /// stored by the event. - /// - /// - /// This method returns a single containing all the - /// properties defined for this event. - /// - /// - public PropertiesDictionary GetProperties() - { - if (m_data.Properties != null) - { - return m_data.Properties; - } - if (m_compositeProperties == null) - { - CreateCompositeProperties(); - } - return m_compositeProperties.Flatten(); - } - - #endregion Public Instance Methods - - #region Private Instance Fields - - /// - /// The internal logging event data. - /// - private LoggingEventData m_data; - - /// - /// The internal logging event data. - /// - private CompositeProperties m_compositeProperties; - - /// - /// The internal logging event data. - /// - private PropertiesDictionary m_eventProperties; - - /// - /// The fully qualified Type of the calling - /// logger class in the stack frame (i.e. the declaring type of the method). - /// - private readonly Type m_callerStackBoundaryDeclaringType; - - /// - /// The application supplied message of logging event. - /// - private readonly object m_message; - - /// - /// The exception that was thrown. - /// - /// - /// This is not serialized. The string representation - /// is serialized instead. - /// - private readonly Exception m_thrownException; - - /// - /// The repository that generated the logging event - /// - /// - /// This is not serialized. - /// - private ILoggerRepository m_repository = null; - - /// - /// The fix state for this event - /// - /// - /// These flags indicate which fields have been fixed. - /// Not serialized. - /// - private FixFlags m_fixFlags = FixFlags.None; - - /// - /// Indicated that the internal cache is updateable (ie not fixed) - /// - /// - /// This is a seperate flag to m_fixFlags as it allows incrementel fixing and simpler - /// changes in the caching strategy. - /// - private bool m_cacheUpdatable = true; - - #endregion Private Instance Fields - - #region Constants - - /// - /// The key into the Properties map for the host name value. - /// - public const string HostNameProperty = "log4net:HostName"; - - /// - /// The key into the Properties map for the thread identity value. - /// - public const string IdentityProperty = "log4net:Identity"; - - /// - /// The key into the Properties map for the user name value. - /// - public const string UserNameProperty = "log4net:UserName"; - - #endregion - } -} \ No newline at end of file diff --git a/src/log4net/Core/MethodItem.cs b/src/log4net/Core/MethodItem.cs deleted file mode 100644 index a8b90c65..00000000 --- a/src/log4net/Core/MethodItem.cs +++ /dev/null @@ -1,171 +0,0 @@ -#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 System.Text; -using System.Collections; - -using log4net.Util; - -namespace log4net.Core -{ - /// - /// provides method information without actually referencing a System.Reflection.MethodBase - /// as that would require that the containing assembly is loaded. - /// - /// -#if !NETCF - [Serializable] -#endif - public class MethodItem - { - #region Public Instance Constructors - - /// - /// constructs a method item for an unknown method. - /// - public MethodItem() - { - m_name = NA; - m_parameters = new string[0]; - } - - /// - /// constructs a method item from the name of the method. - /// - /// - public MethodItem(string name) - : this() - { - m_name = name; - } - - /// - /// constructs a method item from the name of the method and its parameters. - /// - /// - /// - public MethodItem(string name, string[] parameters) - : this(name) - { - m_parameters = parameters; - } - - /// - /// constructs a method item from a method base by determining the method name and its parameters. - /// - /// - public MethodItem(System.Reflection.MethodBase methodBase) - : this(methodBase.Name, GetMethodParameterNames(methodBase)) - { - } - - #endregion - - private static string[] GetMethodParameterNames(System.Reflection.MethodBase methodBase) - { - ArrayList methodParameterNames = new ArrayList(); - try - { - System.Reflection.ParameterInfo[] methodBaseGetParameters = methodBase.GetParameters(); - - int methodBaseGetParametersCount = methodBaseGetParameters.GetUpperBound(0); - - for (int i = 0; i <= methodBaseGetParametersCount; i++) - { - methodParameterNames.Add(methodBaseGetParameters[i].ParameterType + " " + methodBaseGetParameters[i].Name); - } - } - catch (Exception ex) - { - LogLog.Error(declaringType, "An exception ocurred while retreiving method parameters.", ex); - } - - return (string[])methodParameterNames.ToArray(typeof(string)); - } - - #region Public Instance Properties - - /// - /// Gets the method name of the caller making the logging - /// request. - /// - /// - /// The method name of the caller making the logging - /// request. - /// - /// - /// - /// Gets the method name of the caller making the logging - /// request. - /// - /// - public string Name - { - get { return m_name; } - } - - /// - /// Gets the method parameters of the caller making - /// the logging request. - /// - /// - /// The method parameters of the caller making - /// the logging request - /// - /// - /// - /// Gets the method parameters of the caller making - /// the logging request. - /// - /// - public string[] Parameters - { - get { return m_parameters; } - } - - #endregion - - #region Private Instance Fields - - private readonly string m_name; - private readonly string[] m_parameters; - - #endregion - - #region Private Static Fields - - /// - /// The fully qualified type of the StackFrameItem class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(MethodItem); - - /// - /// When location information is not available the constant - /// NA is returned. Current value of this string - /// constant is ?. - /// - private const string NA = "?"; - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Core/SecurityContext.cs b/src/log4net/Core/SecurityContext.cs deleted file mode 100644 index fecad2b2..00000000 --- a/src/log4net/Core/SecurityContext.cs +++ /dev/null @@ -1,55 +0,0 @@ -#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; - -namespace log4net.Core -{ - /// - /// A SecurityContext used by log4net when interacting with protected resources - /// - /// - /// - /// A SecurityContext used by log4net when interacting with protected resources - /// for example with operating system services. This can be used to impersonate - /// a principal that has been granted privileges on the system resources. - /// - /// - /// Nicko Cadell - public abstract class SecurityContext - { - /// - /// Impersonate this SecurityContext - /// - /// State supplied by the caller - /// An instance that will - /// revoke the impersonation of this SecurityContext, or null - /// - /// - /// Impersonate this security context. Further calls on the current - /// thread should now be made in the security context provided - /// by this object. When the result - /// method is called the security - /// context of the thread should be reverted to the state it was in - /// before was called. - /// - /// - public abstract IDisposable Impersonate(object state); - } -} diff --git a/src/log4net/Core/SecurityContextProvider.cs b/src/log4net/Core/SecurityContextProvider.cs deleted file mode 100644 index f6e99e6e..00000000 --- a/src/log4net/Core/SecurityContextProvider.cs +++ /dev/null @@ -1,124 +0,0 @@ -#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.Util; - -namespace log4net.Core -{ - /// - /// The providers default instances. - /// - /// - /// - /// A configured component that interacts with potentially protected system - /// resources uses a to provide the elevated - /// privileges required. If the object has - /// been not been explicitly provided to the component then the component - /// will request one from this . - /// - /// - /// By default the is - /// an instance of which returns only - /// objects. This is a reasonable default - /// where the privileges required are not know by the system. - /// - /// - /// This default behavior can be overridden by subclassing the - /// and overriding the method to return - /// the desired objects. The default provider - /// can be replaced by programmatically setting the value of the - /// property. - /// - /// - /// An alternative is to use the log4net.Config.SecurityContextProviderAttribute - /// This attribute can be applied to an assembly in the same way as the - /// log4net.Config.XmlConfiguratorAttribute". The attribute takes - /// the type to use as the as an argument. - /// - /// - /// Nicko Cadell - public class SecurityContextProvider - { - /// - /// The default provider - /// - private static SecurityContextProvider s_defaultProvider = new SecurityContextProvider(); - - /// - /// Gets or sets the default SecurityContextProvider - /// - /// - /// The default SecurityContextProvider - /// - /// - /// - /// The default provider is used by configured components that - /// require a and have not had one - /// given to them. - /// - /// - /// By default this is an instance of - /// that returns objects. - /// - /// - /// The default provider can be set programmatically by setting - /// the value of this property to a sub class of - /// that has the desired behavior. - /// - /// - public static SecurityContextProvider DefaultProvider - { - get { return s_defaultProvider; } - set { s_defaultProvider = value; } - } - - /// - /// Protected default constructor to allow subclassing - /// - /// - /// - /// Protected default constructor to allow subclassing - /// - /// - protected SecurityContextProvider() - { - } - - /// - /// Create a SecurityContext for a consumer - /// - /// The consumer requesting the SecurityContext - /// An impersonation context - /// - /// - /// The default implementation is to return a . - /// - /// - /// Subclasses should override this method to provide their own - /// behavior. - /// - /// - public virtual SecurityContext CreateSecurityContext(object consumer) - { - return NullSecurityContext.Instance; - } - } -} diff --git a/src/log4net/Core/StackFrameItem.cs b/src/log4net/Core/StackFrameItem.cs deleted file mode 100644 index 0a3e1d08..00000000 --- a/src/log4net/Core/StackFrameItem.cs +++ /dev/null @@ -1,196 +0,0 @@ -#if !NETCF -#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 System.Text; -using System.Diagnostics; -using System.Reflection; -using log4net.Util; - -namespace log4net.Core -{ - /// - /// provides stack frame information without actually referencing a System.Diagnostics.StackFrame - /// as that would require that the containing assembly is loaded. - /// - /// - [Serializable] - public class StackFrameItem - { - #region Public Instance Constructors - - /// - /// returns a stack frame item from a stack frame. This - /// - /// - /// - public StackFrameItem(StackFrame frame) - { - // set default values - m_lineNumber = NA; - m_fileName = NA; - m_method = new MethodItem(); - m_className = NA; - - try - { - // get frame values - m_lineNumber = frame.GetFileLineNumber().ToString(System.Globalization.NumberFormatInfo.InvariantInfo); - m_fileName = frame.GetFileName(); - // get method values - MethodBase method = frame.GetMethod(); - if (method != null) - { - if(method.DeclaringType != null) - m_className = method.DeclaringType.FullName; - m_method = new MethodItem(method); - } - } - catch (Exception ex) - { - LogLog.Error(declaringType, "An exception ocurred while retreiving stack frame information.", ex); - } - - // set full info - m_fullInfo = m_className + '.' + m_method.Name + '(' + m_fileName + ':' + m_lineNumber + ')'; - } - - #endregion - - #region Public Instance Properties - - /// - /// Gets the fully qualified class name of the caller making the logging - /// request. - /// - /// - /// The fully qualified class name of the caller making the logging - /// request. - /// - /// - /// - /// Gets the fully qualified class name of the caller making the logging - /// request. - /// - /// - public string ClassName - { - get { return m_className; } - } - - /// - /// Gets the file name of the caller. - /// - /// - /// The file name of the caller. - /// - /// - /// - /// Gets the file name of the caller. - /// - /// - public string FileName - { - get { return m_fileName; } - } - - /// - /// Gets the line number of the caller. - /// - /// - /// The line number of the caller. - /// - /// - /// - /// Gets the line number of the caller. - /// - /// - public string LineNumber - { - get { return m_lineNumber; } - } - - /// - /// Gets the method name of the caller. - /// - /// - /// The method name of the caller. - /// - /// - /// - /// Gets the method name of the caller. - /// - /// - public MethodItem Method - { - get { return m_method; } - } - - /// - /// Gets all available caller information - /// - /// - /// All available caller information, in the format - /// fully.qualified.classname.of.caller.methodName(Filename:line) - /// - /// - /// - /// Gets all available caller information, in the format - /// fully.qualified.classname.of.caller.methodName(Filename:line) - /// - /// - public string FullInfo - { - get { return m_fullInfo; } - } - - #endregion Public Instance Properties - - #region Private Instance Fields - - private readonly string m_lineNumber; - private readonly string m_fileName; - private readonly string m_className; - private readonly string m_fullInfo; - private readonly MethodItem m_method; - - #endregion - - #region Private Static Fields - - /// - /// The fully qualified type of the StackFrameItem class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(StackFrameItem); - - /// - /// When location information is not available the constant - /// NA is returned. Current value of this string - /// constant is ?. - /// - private const string NA = "?"; - - #endregion Private Static Fields - } -} -#endif diff --git a/src/log4net/Core/TimeEvaluator.cs b/src/log4net/Core/TimeEvaluator.cs deleted file mode 100644 index 66ec8f68..00000000 --- a/src/log4net/Core/TimeEvaluator.cs +++ /dev/null @@ -1,148 +0,0 @@ -#region Copyright & 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; - -namespace log4net.Core -{ - /// - /// An evaluator that triggers after specified number of seconds. - /// - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - /// Robert Sevcik - public class TimeEvaluator : ITriggeringEventEvaluator - { - /// - /// The time threshold for triggering in seconds. Zero means it won't trigger at all. - /// - private int m_interval; - - /// - /// The time of last check. This gets updated when the object is created and when the evaluator triggers. - /// - private DateTime m_lasttime; - - /// - /// The default time threshold for triggering in seconds. Zero means it won't trigger at all. - /// - const int DEFAULT_INTERVAL = 0; - - /// - /// Create a new evaluator using the time threshold in seconds. - /// - /// - /// - /// Create a new evaluator using the time threshold in seconds. - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - public TimeEvaluator() - : this(DEFAULT_INTERVAL) - { - } - - /// - /// Create a new evaluator using the specified time threshold in seconds. - /// - /// - /// The time threshold in seconds to trigger after. - /// Zero means it won't trigger at all. - /// - /// - /// - /// Create a new evaluator using the specified time threshold in seconds. - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - public TimeEvaluator(int interval) - { - m_interval = interval; - m_lasttime = DateTime.Now; - } - - /// - /// The time threshold in seconds to trigger after - /// - /// - /// The time threshold in seconds to trigger after. - /// Zero means it won't trigger at all. - /// - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - public int Interval - { - get { return m_interval; } - set { m_interval = value; } - } - - /// - /// Is this the triggering event? - /// - /// The event to check - /// This method returns true, if the specified time period - /// has passed since last check.. - /// Otherwise it returns false - /// - /// - /// This evaluator will trigger if the specified time period - /// has passed since last check. - /// - /// - public bool IsTriggeringEvent(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - // disable the evaluator if threshold is zero - if (m_interval == 0) return false; - - lock (this) // avoid triggering multiple times - { - TimeSpan passed = DateTime.Now.Subtract(m_lasttime); - - if (passed.TotalSeconds > m_interval) - { - m_lasttime = DateTime.Now; - return true; - } - else - { - return false; - } - } - } - } -} diff --git a/src/log4net/Core/WrapperMap.cs b/src/log4net/Core/WrapperMap.cs deleted file mode 100644 index a43a8b8d..00000000 --- a/src/log4net/Core/WrapperMap.cs +++ /dev/null @@ -1,259 +0,0 @@ -#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 System.Collections; - -using log4net.Repository; - -namespace log4net.Core -{ - #region WrapperCreationHandler - - /// - /// Delegate used to handle creation of new wrappers. - /// - /// The logger to wrap in a wrapper. - /// - /// - /// Delegate used to handle creation of new wrappers. This delegate - /// is called from the - /// method to construct the wrapper for the specified logger. - /// - /// - /// The delegate to use is supplied to the - /// constructor. - /// - /// - public delegate ILoggerWrapper WrapperCreationHandler(ILogger logger); - - #endregion WrapperCreationHandler - - /// - /// Maps between logger objects and wrapper objects. - /// - /// - /// - /// This class maintains a mapping between objects and - /// objects. Use the method to - /// lookup the for the specified . - /// - /// - /// New wrapper instances are created by the - /// method. The default behavior is for this method to delegate construction - /// of the wrapper to the delegate supplied - /// to the constructor. This allows specialization of the behavior without - /// requiring subclassing of this type. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class WrapperMap - { - #region Public Instance Constructors - - /// - /// Initializes a new instance of the - /// - /// The handler to use to create the wrapper objects. - /// - /// - /// Initializes a new instance of the class with - /// the specified handler to create the wrapper objects. - /// - /// - public WrapperMap(WrapperCreationHandler createWrapperHandler) - { - m_createWrapperHandler = createWrapperHandler; - - // Create the delegates for the event callbacks - m_shutdownHandler = new LoggerRepositoryShutdownEventHandler(ILoggerRepository_Shutdown); - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the wrapper object for the specified logger. - /// - /// The wrapper object for the specified logger - /// - /// - /// If the logger is null then the corresponding wrapper is null. - /// - /// - /// Looks up the wrapper it it has previously been requested and - /// returns it. If the wrapper has never been requested before then - /// the virtual method is - /// called. - /// - /// - virtual public ILoggerWrapper GetWrapper(ILogger logger) - { - // If the logger is null then the corresponding wrapper is null - if (logger == null) - { - return null; - } - - lock(this) - { - // Lookup hierarchy in map. - Hashtable wrappersMap = (Hashtable)m_repositories[logger.Repository]; - - if (wrappersMap == null) - { - // Hierarchy does not exist in map. - // Must register with hierarchy - - wrappersMap = new Hashtable(); - m_repositories[logger.Repository] = wrappersMap; - - // Register for config reset & shutdown on repository - logger.Repository.ShutdownEvent += m_shutdownHandler; - } - - // Look for the wrapper object in the map - ILoggerWrapper wrapperObject = wrappersMap[logger] as ILoggerWrapper; - - if (wrapperObject == null) - { - // No wrapper object exists for the specified logger - - // Create a new wrapper wrapping the logger - wrapperObject = CreateNewWrapperObject(logger); - - // Store wrapper logger in map - wrappersMap[logger] = wrapperObject; - } - - return wrapperObject; - } - } - - #endregion Public Instance Properties - - #region Protected Instance Properties - - /// - /// Gets the map of logger repositories. - /// - /// - /// Map of logger repositories. - /// - /// - /// - /// Gets the hashtable that is keyed on . The - /// values are hashtables keyed on with the - /// value being the corresponding . - /// - /// - protected Hashtable Repositories - { - get { return this.m_repositories; } - } - - #endregion Protected Instance Properties - - #region Protected Instance Methods - - /// - /// Creates the wrapper object for the specified logger. - /// - /// The logger to wrap in a wrapper. - /// The wrapper object for the logger. - /// - /// - /// This implementation uses the - /// passed to the constructor to create the wrapper. This method - /// can be overridden in a subclass. - /// - /// - virtual protected ILoggerWrapper CreateNewWrapperObject(ILogger logger) - { - if (m_createWrapperHandler != null) - { - return m_createWrapperHandler(logger); - } - return null; - } - - /// - /// Called when a monitored repository shutdown event is received. - /// - /// The that is shutting down - /// - /// - /// This method is called when a that this - /// is holding loggers for has signaled its shutdown - /// event . The default - /// behavior of this method is to release the references to the loggers - /// and their wrappers generated for this repository. - /// - /// - virtual protected void RepositoryShutdown(ILoggerRepository repository) - { - lock(this) - { - // Remove the repository from map - m_repositories.Remove(repository); - - // Unhook events from the repository - repository.ShutdownEvent -= m_shutdownHandler; - } - } - - /// - /// Event handler for repository shutdown event. - /// - /// The sender of the event. - /// The event args. - private void ILoggerRepository_Shutdown(object sender, EventArgs e) - { - ILoggerRepository repository = sender as ILoggerRepository; - if (repository != null) - { - // Remove all repository from map - RepositoryShutdown(repository); - } - } - - #endregion Protected Instance Methods - - #region Private Instance Variables - - /// - /// Map of logger repositories to hashtables of ILogger to ILoggerWrapper mappings - /// - private readonly Hashtable m_repositories = new Hashtable(); - - /// - /// The handler to use to create the extension wrapper objects. - /// - private readonly WrapperCreationHandler m_createWrapperHandler; - - /// - /// Internal reference to the delegate used to register for repository shutdown events. - /// - private readonly LoggerRepositoryShutdownEventHandler m_shutdownHandler; - - #endregion Private Instance Variables - } -} diff --git a/src/log4net/DateFormatter/AbsoluteTimeDateFormatter.cs b/src/log4net/DateFormatter/AbsoluteTimeDateFormatter.cs deleted file mode 100644 index 72e11c9e..00000000 --- a/src/log4net/DateFormatter/AbsoluteTimeDateFormatter.cs +++ /dev/null @@ -1,199 +0,0 @@ -#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 System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading; - -namespace log4net.DateFormatter -{ - /// - /// Formats a as "HH:mm:ss,fff". - /// - /// - /// - /// Formats a in the format "HH:mm:ss,fff" for example, "15:49:37,459". - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class AbsoluteTimeDateFormatter : IDateFormatter - { - #region Protected Instance Methods - - /// - /// Renders the date into a string. Format is "HH:mm:ss". - /// - /// The date to render into a string. - /// The string builder to write to. - /// - /// - /// Subclasses should override this method to render the date - /// into a string using a precision up to the second. This method - /// will be called at most once per second and the result will be - /// reused if it is needed again during the same second. - /// - /// - virtual protected void FormatDateWithoutMillis(DateTime dateToFormat, StringBuilder buffer) - { - int hour = dateToFormat.Hour; - if (hour < 10) - { - buffer.Append('0'); - } - buffer.Append(hour); - buffer.Append(':'); - - int mins = dateToFormat.Minute; - if (mins < 10) - { - buffer.Append('0'); - } - buffer.Append(mins); - buffer.Append(':'); - - int secs = dateToFormat.Second; - if (secs < 10) - { - buffer.Append('0'); - } - buffer.Append(secs); - } - - #endregion Protected Instance Methods - - #region Implementation of IDateFormatter - - /// - /// Renders the date into a string. Format is "HH:mm:ss,fff". - /// - /// The date to render into a string. - /// The writer to write to. - /// - /// - /// Uses the method to generate the - /// time string up to the seconds and then appends the current - /// milliseconds. The results from are - /// cached and is called at most once - /// per second. - /// - /// - /// Sub classes should override - /// rather than . - /// - /// - virtual public void FormatDate(DateTime dateToFormat, TextWriter writer) - { - string timeString = null; - // Calculate the current time precise only to the second - long currentTimeToTheSecond = (dateToFormat.Ticks - (dateToFormat.Ticks % TimeSpan.TicksPerSecond)); - - // Compare this time with the stored last time - // If we are in the same second then append - // the previously calculated time string - if (s_lastTimeToTheSecond != currentTimeToTheSecond) - { - LastTimeStrings.Clear(); - } - else - { - LastTimeStrings.TryGetValue(GetType(), out timeString); - } - - if (timeString == null) - { - StringBuilder sb = new StringBuilder(); - // Calculate the new string for this second - FormatDateWithoutMillis(dateToFormat, sb); - - // Render the string buffer to a string - timeString = sb.ToString(); - - // Store the time as a string (we only have to do this once per second) - LastTimeStrings[GetType()] = timeString; - s_lastTimeToTheSecond = currentTimeToTheSecond; - } - writer.Write(timeString); - - // Append the current millisecond info - writer.Write(','); - int millis = dateToFormat.Millisecond; - if (millis < 100) - { - writer.Write('0'); - } - if (millis < 10) - { - writer.Write('0'); - } - writer.Write(millis); - } - - #endregion Implementation of IDateFormatter - - #region Public Static Fields - - /// - /// String constant used to specify AbsoluteTimeDateFormat in layouts. Current value is ABSOLUTE. - /// - public const string AbsoluteTimeDateFormat = "ABSOLUTE"; - - /// - /// String constant used to specify DateTimeDateFormat in layouts. Current value is DATE. - /// - public const string DateAndTimeDateFormat = "DATE"; - - /// - /// String constant used to specify ISO8601DateFormat in layouts. Current value is ISO8601. - /// - public const string Iso8601TimeDateFormat = "ISO8601"; - - #endregion Public Static Fields - - #region Private Static Fields - - /// - /// Last stored time with precision up to the second. - /// - [ThreadStatic] - private static long s_lastTimeToTheSecond; - - /// - /// Last stored time with precision up to the second, formatted - /// as a string. - /// - [ThreadStatic] - private static IDictionary s_lastTimeStrings; - - private IDictionary LastTimeStrings { - get - { - if (s_lastTimeStrings == null) - { - s_lastTimeStrings = new Dictionary(); - } - return s_lastTimeStrings; - } - } - - #endregion Private Static Fields - } -} diff --git a/src/log4net/DateFormatter/DateTimeDateFormatter.cs b/src/log4net/DateFormatter/DateTimeDateFormatter.cs deleted file mode 100644 index 03dcca95..00000000 --- a/src/log4net/DateFormatter/DateTimeDateFormatter.cs +++ /dev/null @@ -1,106 +0,0 @@ -#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 System.Text; -using System.Globalization; - -namespace log4net.DateFormatter -{ - /// - /// Formats a as "dd MMM yyyy HH:mm:ss,fff" - /// - /// - /// - /// Formats a in the format - /// "dd MMM yyyy HH:mm:ss,fff" for example, - /// "06 Nov 1994 15:49:37,459". - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Angelika Schnagl - public class DateTimeDateFormatter : AbsoluteTimeDateFormatter - { - #region Public Instance Constructors - - /// - /// Default constructor. - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public DateTimeDateFormatter() - { - m_dateTimeFormatInfo = DateTimeFormatInfo.InvariantInfo; - } - - #endregion Public Instance Constructors - - #region Override implementation of AbsoluteTimeDateFormatter - - /// - /// Formats the date without the milliseconds part - /// - /// The date to format. - /// The string builder to write to. - /// - /// - /// Formats a DateTime in the format "dd MMM yyyy HH:mm:ss" - /// for example, "06 Nov 1994 15:49:37". - /// - /// - /// The base class will append the ",fff" milliseconds section. - /// This method will only be called at most once per second. - /// - /// - override protected void FormatDateWithoutMillis(DateTime dateToFormat, StringBuilder buffer) - { - int day = dateToFormat.Day; - if (day < 10) - { - buffer.Append('0'); - } - buffer.Append(day); - buffer.Append(' '); - - buffer.Append(m_dateTimeFormatInfo.GetAbbreviatedMonthName(dateToFormat.Month)); - buffer.Append(' '); - - buffer.Append(dateToFormat.Year); - buffer.Append(' '); - - // Append the 'HH:mm:ss' - base.FormatDateWithoutMillis(dateToFormat, buffer); - } - - #endregion Override implementation of AbsoluteTimeDateFormatter - - #region Private Instance Fields - - /// - /// The format info for the invariant culture. - /// - private readonly DateTimeFormatInfo m_dateTimeFormatInfo; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/DateFormatter/IDateFormatter.cs b/src/log4net/DateFormatter/IDateFormatter.cs deleted file mode 100644 index f5074ee4..00000000 --- a/src/log4net/DateFormatter/IDateFormatter.cs +++ /dev/null @@ -1,55 +0,0 @@ -#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 System.IO; - -namespace log4net.DateFormatter -{ - /// - /// Render a as a string. - /// - /// - /// - /// Interface to abstract the rendering of a - /// instance into a string. - /// - /// - /// The method is used to render the - /// date to a text writer. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IDateFormatter - { - /// - /// Formats the specified date as a string. - /// - /// The date to format. - /// The writer to write to. - /// - /// - /// Format the as a string and write it - /// to the provided. - /// - /// - void FormatDate(DateTime dateToFormat, TextWriter writer); - } -} diff --git a/src/log4net/DateFormatter/Iso8601DateFormatter.cs b/src/log4net/DateFormatter/Iso8601DateFormatter.cs deleted file mode 100644 index a7e88d55..00000000 --- a/src/log4net/DateFormatter/Iso8601DateFormatter.cs +++ /dev/null @@ -1,96 +0,0 @@ -#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 System.Text; - -namespace log4net.DateFormatter -{ - /// - /// Formats the as "yyyy-MM-dd HH:mm:ss,fff". - /// - /// - /// - /// Formats the specified as a string: "yyyy-MM-dd HH:mm:ss,fff". - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class Iso8601DateFormatter : AbsoluteTimeDateFormatter - { - #region Public Instance Constructors - - /// - /// Default constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public Iso8601DateFormatter() - { - } - - #endregion Public Instance Constructors - - #region Override implementation of AbsoluteTimeDateFormatter - - /// - /// Formats the date without the milliseconds part - /// - /// The date to format. - /// The string builder to write to. - /// - /// - /// Formats the date specified as a string: "yyyy-MM-dd HH:mm:ss". - /// - /// - /// The base class will append the ",fff" milliseconds section. - /// This method will only be called at most once per second. - /// - /// - override protected void FormatDateWithoutMillis(DateTime dateToFormat, StringBuilder buffer) - { - buffer.Append(dateToFormat.Year); - - buffer.Append('-'); - int month = dateToFormat.Month; - if (month < 10) - { - buffer.Append('0'); - } - buffer.Append(month); - buffer.Append('-'); - - int day = dateToFormat.Day; - if (day < 10) - { - buffer.Append('0'); - } - buffer.Append(day); - buffer.Append(' '); - - // Append the 'HH:mm:ss' - base.FormatDateWithoutMillis(dateToFormat, buffer); - } - - #endregion Override implementation of AbsoluteTimeDateFormatter - } -} diff --git a/src/log4net/DateFormatter/SimpleDateFormatter.cs b/src/log4net/DateFormatter/SimpleDateFormatter.cs deleted file mode 100644 index c112ca1a..00000000 --- a/src/log4net/DateFormatter/SimpleDateFormatter.cs +++ /dev/null @@ -1,95 +0,0 @@ -#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 System.IO; - -namespace log4net.DateFormatter -{ - /// - /// Formats the using the method. - /// - /// - /// - /// Formats the using the method. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class SimpleDateFormatter : IDateFormatter - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// The format string. - /// - /// - /// Initializes a new instance of the class - /// with the specified format string. - /// - /// - /// The format string must be compatible with the options - /// that can be supplied to . - /// - /// - public SimpleDateFormatter(string format) - { - m_formatString = format; - } - - #endregion Public Instance Constructors - - #region Implementation of IDateFormatter - - /// - /// Formats the date using . - /// - /// The date to convert to a string. - /// The writer to write to. - /// - /// - /// Uses the date format string supplied to the constructor to call - /// the method to format the date. - /// - /// - virtual public void FormatDate(DateTime dateToFormat, TextWriter writer) - { - writer.Write(dateToFormat.ToString(m_formatString, System.Globalization.DateTimeFormatInfo.InvariantInfo)); - } - - #endregion - - #region Private Instance Fields - - /// - /// The format string used to format the . - /// - /// - /// - /// The format string must be compatible with the options - /// that can be supplied to . - /// - /// - private readonly string m_formatString; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Filter/DenyAllFilter.cs b/src/log4net/Filter/DenyAllFilter.cs deleted file mode 100644 index e17a16ff..00000000 --- a/src/log4net/Filter/DenyAllFilter.cs +++ /dev/null @@ -1,75 +0,0 @@ -#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; - -namespace log4net.Filter -{ - /// - /// This filter drops all . - /// - /// - /// - /// You can add this filter to the end of a filter chain to - /// switch from the default "accept all unless instructed otherwise" - /// filtering behavior to a "deny all unless instructed otherwise" - /// behavior. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class DenyAllFilter : FilterSkeleton - { - #region Constructors - - /// - /// Default constructor - /// - public DenyAllFilter() - { - } - - #endregion - - #region Override implementation of FilterSkeleton - - /// - /// Always returns the integer constant - /// - /// the LoggingEvent to filter - /// Always returns - /// - /// - /// Ignores the event being logged and just returns - /// . This can be used to change the default filter - /// chain behavior from to . This filter - /// should only be used as the last filter in the chain - /// as any further filters will be ignored! - /// - /// - override public FilterDecision Decide(LoggingEvent loggingEvent) - { - return FilterDecision.Deny; - } - - #endregion - } -} diff --git a/src/log4net/Filter/FilterDecision.cs b/src/log4net/Filter/FilterDecision.cs deleted file mode 100644 index 1b5967b4..00000000 --- a/src/log4net/Filter/FilterDecision.cs +++ /dev/null @@ -1,54 +0,0 @@ -#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; - -namespace log4net.Filter -{ - /// - /// The return result from - /// - /// - /// - /// The return result from - /// - /// - public enum FilterDecision : int - { - /// - /// The log event must be dropped immediately without - /// consulting with the remaining filters, if any, in the chain. - /// - Deny = -1, - - /// - /// This filter is neutral with respect to the log event. - /// The remaining filters, if any, should be consulted for a final decision. - /// - Neutral = 0, - - /// - /// The log event must be logged immediately without - /// consulting with the remaining filters, if any, in the chain. - /// - Accept = 1, - } -} diff --git a/src/log4net/Filter/FilterSkeleton.cs b/src/log4net/Filter/FilterSkeleton.cs deleted file mode 100644 index 9cc24d80..00000000 --- a/src/log4net/Filter/FilterSkeleton.cs +++ /dev/null @@ -1,155 +0,0 @@ -#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; - -namespace log4net.Filter -{ - /// - /// Subclass this type to implement customized logging event filtering - /// - /// - /// - /// Users should extend this class to implement customized logging - /// event filtering. Note that and - /// , the parent class of all standard - /// appenders, have built-in filtering rules. It is suggested that you - /// first use and understand the built-in rules before rushing to write - /// your own custom filters. - /// - /// - /// This abstract class assumes and also imposes that filters be - /// organized in a linear chain. The - /// method of each filter is called sequentially, in the order of their - /// addition to the chain. - /// - /// - /// The method must return one - /// of the integer constants , - /// or . - /// - /// - /// If the value is returned, then the log event is dropped - /// immediately without consulting with the remaining filters. - /// - /// - /// If the value is returned, then the next filter - /// in the chain is consulted. If there are no more filters in the - /// chain, then the log event is logged. Thus, in the presence of no - /// filters, the default behavior is to log all logging events. - /// - /// - /// If the value is returned, then the log - /// event is logged without consulting the remaining filters. - /// - /// - /// The philosophy of log4net filters is largely inspired from the - /// Linux ipchains. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public abstract class FilterSkeleton : IFilter - { - #region Member Variables - - /// - /// Points to the next filter in the filter chain. - /// - /// - /// - /// See for more information. - /// - /// - private IFilter m_next; - - #endregion - - #region Implementation of IOptionHandler - - /// - /// Initialize the filter with the options set - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// Typically filter's options become active immediately on set, - /// however this method must still be called. - /// - /// - virtual public void ActivateOptions() - { - } - - #endregion - - #region Implementation of IFilter - - /// - /// Decide if the should be logged through an appender. - /// - /// The to decide upon - /// The decision of the filter - /// - /// - /// If the decision is , then the event will be - /// dropped. If the decision is , then the next - /// filter, if any, will be invoked. If the decision is then - /// the event will be logged without consulting with other filters in - /// the chain. - /// - /// - /// This method is marked abstract and must be implemented - /// in a subclass. - /// - /// - abstract public FilterDecision Decide(LoggingEvent loggingEvent); - - /// - /// Property to get and set the next filter - /// - /// - /// The next filter in the chain - /// - /// - /// - /// Filters are typically composed into chains. This property allows the next filter in - /// the chain to be accessed. - /// - /// - public IFilter Next - { - get { return m_next; } - set { m_next = value; } - } - - #endregion - } -} diff --git a/src/log4net/Filter/IFilter.cs b/src/log4net/Filter/IFilter.cs deleted file mode 100644 index 8c597a7c..00000000 --- a/src/log4net/Filter/IFilter.cs +++ /dev/null @@ -1,102 +0,0 @@ -#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; - -namespace log4net.Filter -{ - /// - /// Implement this interface to provide customized logging event filtering - /// - /// - /// - /// Users should implement this interface to implement customized logging - /// event filtering. Note that and - /// , the parent class of all standard - /// appenders, have built-in filtering rules. It is suggested that you - /// first use and understand the built-in rules before rushing to write - /// your own custom filters. - /// - /// - /// This abstract class assumes and also imposes that filters be - /// organized in a linear chain. The - /// method of each filter is called sequentially, in the order of their - /// addition to the chain. - /// - /// - /// The method must return one - /// of the integer constants , - /// or . - /// - /// - /// If the value is returned, then the log event is dropped - /// immediately without consulting with the remaining filters. - /// - /// - /// If the value is returned, then the next filter - /// in the chain is consulted. If there are no more filters in the - /// chain, then the log event is logged. Thus, in the presence of no - /// filters, the default behavior is to log all logging events. - /// - /// - /// If the value is returned, then the log - /// event is logged without consulting the remaining filters. - /// - /// - /// The philosophy of log4net filters is largely inspired from the - /// Linux ipchains. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IFilter : IOptionHandler - { - /// - /// Decide if the logging event should be logged through an appender. - /// - /// The LoggingEvent to decide upon - /// The decision of the filter - /// - /// - /// If the decision is , then the event will be - /// dropped. If the decision is , then the next - /// filter, if any, will be invoked. If the decision is then - /// the event will be logged without consulting with other filters in - /// the chain. - /// - /// - FilterDecision Decide(LoggingEvent loggingEvent); - - /// - /// Property to get and set the next filter - /// - /// - /// The next filter in the chain - /// - /// - /// - /// Filters are typically composed into chains. This property allows the next filter in - /// the chain to be accessed. - /// - /// - IFilter Next { get; set; } - } -} diff --git a/src/log4net/Filter/LevelMatchFilter.cs b/src/log4net/Filter/LevelMatchFilter.cs deleted file mode 100644 index 2d3465a2..00000000 --- a/src/log4net/Filter/LevelMatchFilter.cs +++ /dev/null @@ -1,142 +0,0 @@ -#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; -using log4net.Core; -using log4net.Util; - -namespace log4net.Filter -{ - /// - /// This is a very simple filter based on matching. - /// - /// - /// - /// The filter admits two options and - /// . If there is an exact match between the value - /// of the option and the of the - /// , then the method returns in - /// case the option value is set - /// to true, if it is false then - /// is returned. If the does not match then - /// the result will be . - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class LevelMatchFilter : FilterSkeleton - { - #region Member Variables - - /// - /// flag to indicate if the filter should on a match - /// - private bool m_acceptOnMatch = true; - - /// - /// the to match against - /// - private Level m_levelToMatch; - - #endregion - - #region Constructors - - /// - /// Default constructor - /// - public LevelMatchFilter() - { - } - - #endregion - - /// - /// when matching - /// - /// - /// - /// The property is a flag that determines - /// the behavior when a matching is found. If the - /// flag is set to true then the filter will the - /// logging event, otherwise it will the event. - /// - /// - /// The default is true i.e. to the event. - /// - /// - public bool AcceptOnMatch - { - get { return m_acceptOnMatch; } - set { m_acceptOnMatch = value; } - } - - /// - /// The that the filter will match - /// - /// - /// - /// The level that this filter will attempt to match against the - /// level. If a match is found then - /// the result depends on the value of . - /// - /// - public Level LevelToMatch - { - get { return m_levelToMatch; } - set { m_levelToMatch = value; } - } - - #region Override implementation of FilterSkeleton - - /// - /// Tests if the of the logging event matches that of the filter - /// - /// the event to filter - /// see remarks - /// - /// - /// If the of the event matches the level of the - /// filter then the result of the function depends on the - /// value of . If it is true then - /// the function will return , it it is false then it - /// will return . If the does not match then - /// the result will be . - /// - /// - override public FilterDecision Decide(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - if (m_levelToMatch != null && m_levelToMatch == loggingEvent.Level) - { - // Found match - return m_acceptOnMatch ? FilterDecision.Accept : FilterDecision.Deny; - } - return FilterDecision.Neutral; - } - - #endregion - } -} diff --git a/src/log4net/Filter/LevelRangeFilter.cs b/src/log4net/Filter/LevelRangeFilter.cs deleted file mode 100644 index 9afc03a1..00000000 --- a/src/log4net/Filter/LevelRangeFilter.cs +++ /dev/null @@ -1,185 +0,0 @@ -#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; -using log4net.Core; -using log4net.Util; - -namespace log4net.Filter -{ - /// - /// This is a simple filter based on matching. - /// - /// - /// - /// The filter admits three options and - /// that determine the range of priorities that are matched, and - /// . If there is a match between the range - /// of priorities and the of the , then the - /// method returns in case the - /// option value is set to true, if it is false - /// then is returned. If there is no match, is returned. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class LevelRangeFilter : FilterSkeleton - { - #region Member Variables - - /// - /// Flag to indicate the behavior when matching a - /// - private bool m_acceptOnMatch = true; - - /// - /// the minimum value to match - /// - private Level m_levelMin; - - /// - /// the maximum value to match - /// - private Level m_levelMax; - - #endregion - - #region Constructors - - /// - /// Default constructor - /// - public LevelRangeFilter() - { - } - - #endregion - - /// - /// when matching and - /// - /// - /// - /// The property is a flag that determines - /// the behavior when a matching is found. If the - /// flag is set to true then the filter will the - /// logging event, otherwise it will the event. - /// - /// - /// The default is true i.e. to the event. - /// - /// - public bool AcceptOnMatch - { - get { return m_acceptOnMatch; } - set { m_acceptOnMatch = value; } - } - - /// - /// Set the minimum matched - /// - /// - /// - /// The minimum level that this filter will attempt to match against the - /// level. If a match is found then - /// the result depends on the value of . - /// - /// - public Level LevelMin - { - get { return m_levelMin; } - set { m_levelMin = value; } - } - - /// - /// Sets the maximum matched - /// - /// - /// - /// The maximum level that this filter will attempt to match against the - /// level. If a match is found then - /// the result depends on the value of . - /// - /// - public Level LevelMax - { - get { return m_levelMax; } - set { m_levelMax = value; } - } - - #region Override implementation of FilterSkeleton - - /// - /// Check if the event should be logged. - /// - /// the logging event to check - /// see remarks - /// - /// - /// If the of the logging event is outside the range - /// matched by this filter then - /// is returned. If the is matched then the value of - /// is checked. If it is true then - /// is returned, otherwise - /// is returned. - /// - /// - override public FilterDecision Decide(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - if (m_levelMin != null) - { - if (loggingEvent.Level < m_levelMin) - { - // level of event is less than minimum - return FilterDecision.Deny; - } - } - - if (m_levelMax != null) - { - if (loggingEvent.Level > m_levelMax) - { - // level of event is greater than maximum - return FilterDecision.Deny; - } - } - - if (m_acceptOnMatch) - { - // this filter set up to bypass later filters and always return - // accept if level in range - return FilterDecision.Accept; - } - else - { - // event is ok for this filter; allow later filters to have a look.. - return FilterDecision.Neutral; - } - } - - #endregion - } -} diff --git a/src/log4net/Filter/LoggerMatchFilter.cs b/src/log4net/Filter/LoggerMatchFilter.cs deleted file mode 100644 index 828a304e..00000000 --- a/src/log4net/Filter/LoggerMatchFilter.cs +++ /dev/null @@ -1,160 +0,0 @@ -#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; -using log4net.Core; -using log4net.Util; - -namespace log4net.Filter -{ - /// - /// Simple filter to match a string in the event's logger name. - /// - /// - /// - /// The works very similar to the . It admits two - /// options and . If the - /// of the starts - /// with the value of the option, then the - /// method returns in - /// case the option value is set to true, - /// if it is false then is returned. - /// - /// - /// Daniel Cazzulino - public class LoggerMatchFilter : FilterSkeleton - { - #region Member Variables - - /// - /// Flag to indicate the behavior when we have a match - /// - private bool m_acceptOnMatch = true; - - /// - /// The logger name string to substring match against the event - /// - private string m_loggerToMatch; - - #endregion - - #region Constructors - - /// - /// Default constructor - /// - public LoggerMatchFilter() - { - } - - #endregion - - #region Properties - - /// - /// when matching - /// - /// - /// - /// The property is a flag that determines - /// the behavior when a matching is found. If the - /// flag is set to true then the filter will the - /// logging event, otherwise it will the event. - /// - /// - /// The default is true i.e. to the event. - /// - /// - public bool AcceptOnMatch - { - get { return m_acceptOnMatch; } - set { m_acceptOnMatch = value; } - } - - /// - /// The that the filter will match - /// - /// - /// - /// This filter will attempt to match this value against logger name in - /// the following way. The match will be done against the beginning of the - /// logger name (using ). The match is - /// case sensitive. If a match is found then - /// the result depends on the value of . - /// - /// - public string LoggerToMatch - { - get { return m_loggerToMatch; } - set { m_loggerToMatch = value; } - } - - #endregion - - #region Override implementation of FilterSkeleton - - /// - /// Check if this filter should allow the event to be logged - /// - /// the event being logged - /// see remarks - /// - /// - /// The rendered message is matched against the . - /// If the equals the beginning of - /// the incoming () - /// then a match will have occurred. If no match occurs - /// this function will return - /// allowing other filters to check the event. If a match occurs then - /// the value of is checked. If it is - /// true then is returned otherwise - /// is returned. - /// - /// - override public FilterDecision Decide(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - // Check if we have been setup to filter - if ((m_loggerToMatch != null && m_loggerToMatch.Length != 0) && - loggingEvent.LoggerName.StartsWith(m_loggerToMatch)) - { - // we've got a match - if (m_acceptOnMatch) - { - return FilterDecision.Accept; - } - return FilterDecision.Deny; - } - else - { - // We cannot filter so allow the filter chain - // to continue processing - return FilterDecision.Neutral; - } - } - - #endregion - } -} diff --git a/src/log4net/Filter/MdcFilter.cs b/src/log4net/Filter/MdcFilter.cs deleted file mode 100644 index 6bf835ee..00000000 --- a/src/log4net/Filter/MdcFilter.cs +++ /dev/null @@ -1,46 +0,0 @@ -#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 System.Text.RegularExpressions; - -using log4net; -using log4net.Core; -using log4net.Util; - -namespace log4net.Filter -{ - /// - /// Simple filter to match a keyed string in the - /// - /// - /// - /// Simple filter to match a keyed string in the - /// - /// - /// As the MDC has been replaced with layered properties the - /// should be used instead. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class MdcFilter : PropertyFilter - { - } -} diff --git a/src/log4net/Filter/NdcFilter.cs b/src/log4net/Filter/NdcFilter.cs deleted file mode 100644 index d7b3478f..00000000 --- a/src/log4net/Filter/NdcFilter.cs +++ /dev/null @@ -1,59 +0,0 @@ -#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 System.Text.RegularExpressions; - -using log4net; -using log4net.Core; -using log4net.Util; - -namespace log4net.Filter -{ - /// - /// Simple filter to match a string in the - /// - /// - /// - /// Simple filter to match a string in the - /// - /// - /// As the MDC has been replaced with named stacks stored in the - /// properties collections the should - /// be used instead. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class NdcFilter : PropertyFilter - { - /// - /// Default constructor - /// - /// - /// - /// Sets the to "NDC". - /// - /// - public NdcFilter() - { - base.Key = "NDC"; - } - } -} diff --git a/src/log4net/Filter/PropertyFilter.cs b/src/log4net/Filter/PropertyFilter.cs deleted file mode 100644 index 8c35c7fe..00000000 --- a/src/log4net/Filter/PropertyFilter.cs +++ /dev/null @@ -1,165 +0,0 @@ -#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 System.Text.RegularExpressions; - -using log4net; -using log4net.Core; -using log4net.Util; - -namespace log4net.Filter -{ - /// - /// Simple filter to match a string an event property - /// - /// - /// - /// Simple filter to match a string in the value for a - /// specific event property - /// - /// - /// Nicko Cadell - public class PropertyFilter : StringMatchFilter - { - #region Member Variables - - /// - /// The key to use to lookup the string from the event properties - /// - private string m_key; - - #endregion - - #region Constructors - - /// - /// Default constructor - /// - public PropertyFilter() - { - } - - #endregion - - /// - /// The key to lookup in the event properties and then match against. - /// - /// - /// - /// The key name to use to lookup in the properties map of the - /// . The match will be performed against - /// the value of this property if it exists. - /// - /// - public string Key - { - get { return m_key; } - set { m_key = value; } - } - - #region Override implementation of FilterSkeleton - - /// - /// Check if this filter should allow the event to be logged - /// - /// the event being logged - /// see remarks - /// - /// - /// The event property for the is matched against - /// the . - /// If the occurs as a substring within - /// the property value then a match will have occurred. If no match occurs - /// this function will return - /// allowing other filters to check the event. If a match occurs then - /// the value of is checked. If it is - /// true then is returned otherwise - /// is returned. - /// - /// - override public FilterDecision Decide(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - // Check if we have a key to lookup the event property value with - if (m_key == null) - { - // We cannot filter so allow the filter chain - // to continue processing - return FilterDecision.Neutral; - } - - // Lookup the string to match in from the properties using - // the key specified. - object msgObj = loggingEvent.LookupProperty(m_key); - - // Use an ObjectRenderer to convert the property value to a string - string msg = loggingEvent.Repository.RendererMap.FindAndRender(msgObj); - - // Check if we have been setup to filter - if (msg == null || (m_stringToMatch == null && m_regexToMatch == null)) - { - // We cannot filter so allow the filter chain - // to continue processing - return FilterDecision.Neutral; - } - - // Firstly check if we are matching using a regex - if (m_regexToMatch != null) - { - // Check the regex - if (m_regexToMatch.Match(msg).Success == false) - { - // No match, continue processing - return FilterDecision.Neutral; - } - - // we've got a match - if (m_acceptOnMatch) - { - return FilterDecision.Accept; - } - return FilterDecision.Deny; - } - else if (m_stringToMatch != null) - { - // Check substring match - if (msg.IndexOf(m_stringToMatch) == -1) - { - // No match, continue processing - return FilterDecision.Neutral; - } - - // we've got a match - if (m_acceptOnMatch) - { - return FilterDecision.Accept; - } - return FilterDecision.Deny; - } - return FilterDecision.Neutral; - } - - #endregion - } -} diff --git a/src/log4net/Filter/StringMatchFilter.cs b/src/log4net/Filter/StringMatchFilter.cs deleted file mode 100644 index 00a3626c..00000000 --- a/src/log4net/Filter/StringMatchFilter.cs +++ /dev/null @@ -1,241 +0,0 @@ -#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 System.Text.RegularExpressions; - -using log4net; -using log4net.Core; -using log4net.Util; - -namespace log4net.Filter -{ - /// - /// Simple filter to match a string in the rendered message - /// - /// - /// - /// Simple filter to match a string in the rendered message - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class StringMatchFilter : FilterSkeleton - { - #region Member Variables - - /// - /// Flag to indicate the behavior when we have a match - /// - protected bool m_acceptOnMatch = true; - - /// - /// The string to substring match against the message - /// - protected string m_stringToMatch; - - /// - /// A string regex to match - /// - protected string m_stringRegexToMatch; - - /// - /// A regex object to match (generated from m_stringRegexToMatch) - /// - protected Regex m_regexToMatch; - - #endregion - - #region Constructors - - /// - /// Default constructor - /// - public StringMatchFilter() - { - } - - #endregion - - #region Implementation of IOptionHandler - - /// - /// Initialize and precompile the Regex if required - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - override public void ActivateOptions() - { - if (m_stringRegexToMatch != null) - { - m_regexToMatch = new Regex(m_stringRegexToMatch, RegexOptions.Compiled); - } - } - - #endregion - - /// - /// when matching or - /// - /// - /// - /// The property is a flag that determines - /// the behavior when a matching is found. If the - /// flag is set to true then the filter will the - /// logging event, otherwise it will the event. - /// - /// - /// The default is true i.e. to the event. - /// - /// - public bool AcceptOnMatch - { - get { return m_acceptOnMatch; } - set { m_acceptOnMatch = value; } - } - - /// - /// Sets the static string to match - /// - /// - /// - /// The string that will be substring matched against - /// the rendered message. If the message contains this - /// string then the filter will match. If a match is found then - /// the result depends on the value of . - /// - /// - /// One of or - /// must be specified. - /// - /// - public string StringToMatch - { - get { return m_stringToMatch; } - set { m_stringToMatch = value; } - } - - /// - /// Sets the regular expression to match - /// - /// - /// - /// The regular expression pattern that will be matched against - /// the rendered message. If the message matches this - /// pattern then the filter will match. If a match is found then - /// the result depends on the value of . - /// - /// - /// One of or - /// must be specified. - /// - /// - public string RegexToMatch - { - get { return m_stringRegexToMatch; } - set { m_stringRegexToMatch = value; } - } - - #region Override implementation of FilterSkeleton - - /// - /// Check if this filter should allow the event to be logged - /// - /// the event being logged - /// see remarks - /// - /// - /// The rendered message is matched against the . - /// If the occurs as a substring within - /// the message then a match will have occurred. If no match occurs - /// this function will return - /// allowing other filters to check the event. If a match occurs then - /// the value of is checked. If it is - /// true then is returned otherwise - /// is returned. - /// - /// - override public FilterDecision Decide(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - string msg = loggingEvent.RenderedMessage; - - // Check if we have been setup to filter - if (msg == null || (m_stringToMatch == null && m_regexToMatch == null)) - { - // We cannot filter so allow the filter chain - // to continue processing - return FilterDecision.Neutral; - } - - // Firstly check if we are matching using a regex - if (m_regexToMatch != null) - { - // Check the regex - if (m_regexToMatch.Match(msg).Success == false) - { - // No match, continue processing - return FilterDecision.Neutral; - } - - // we've got a match - if (m_acceptOnMatch) - { - return FilterDecision.Accept; - } - return FilterDecision.Deny; - } - else if (m_stringToMatch != null) - { - // Check substring match - if (msg.IndexOf(m_stringToMatch) == -1) - { - // No match, continue processing - return FilterDecision.Neutral; - } - - // we've got a match - if (m_acceptOnMatch) - { - return FilterDecision.Accept; - } - return FilterDecision.Deny; - } - return FilterDecision.Neutral; - - } - - #endregion - } -} diff --git a/src/log4net/GlobalContext.cs b/src/log4net/GlobalContext.cs deleted file mode 100644 index dd02a90c..00000000 --- a/src/log4net/GlobalContext.cs +++ /dev/null @@ -1,102 +0,0 @@ -#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 System.Collections; - -using log4net.Util; - -namespace log4net -{ - /// - /// The log4net Global Context. - /// - /// - /// - /// The GlobalContext provides a location for global debugging - /// information to be stored. - /// - /// - /// The global context has a properties map and these properties can - /// be included in the output of log messages. The - /// supports selecting and outputing these properties. - /// - /// - /// By default the log4net:HostName property is set to the name of - /// the current machine. - /// - /// - /// - /// - /// GlobalContext.Properties["hostname"] = Environment.MachineName; - /// - /// - /// - /// Nicko Cadell - public sealed class GlobalContext - { - #region Private Instance Constructors - - /// - /// Private Constructor. - /// - /// - /// Uses a private access modifier to prevent instantiation of this class. - /// - private GlobalContext() - { - } - - #endregion Private Instance Constructors - - static GlobalContext() - { - Properties[log4net.Core.LoggingEvent.HostNameProperty] = SystemInfo.HostName; - } - - #region Public Static Properties - - /// - /// The global properties map. - /// - /// - /// The global properties map. - /// - /// - /// - /// The global properties map. - /// - /// - public static GlobalContextProperties Properties - { - get { return s_properties; } - } - - #endregion Public Static Properties - - #region Private Static Fields - - /// - /// The global context properties instance - /// - private readonly static GlobalContextProperties s_properties = new GlobalContextProperties(); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/ILog.cs b/src/log4net/ILog.cs deleted file mode 100644 index 8f400174..00000000 --- a/src/log4net/ILog.cs +++ /dev/null @@ -1,1128 +0,0 @@ -#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 System.Reflection; - -using log4net.Core; - -namespace log4net -{ - /// - /// The ILog interface is use by application to log messages into - /// the log4net framework. - /// - /// - /// - /// Use the to obtain logger instances - /// that implement this interface. The - /// static method is used to get logger instances. - /// - /// - /// This class contains methods for logging at different levels and also - /// has properties for determining if those logging levels are - /// enabled in the current configuration. - /// - /// - /// This interface can be implemented in different ways. This documentation - /// specifies reasonable behavior that a caller can expect from the actual - /// implementation, however different implementations reserve the right to - /// do things differently. - /// - /// - /// Simple example of logging messages - /// - /// ILog log = LogManager.GetLogger("application-log"); - /// - /// log.Info("Application Start"); - /// log.Debug("This is a debug message"); - /// - /// if (log.IsDebugEnabled) - /// { - /// log.Debug("This is another debug message"); - /// } - /// - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface ILog : ILoggerWrapper - { - /// Log a message object with the level. - /// - /// Log a message object with the level. - /// - /// - /// - /// This method first checks if this logger is TRACE - /// enabled by comparing the level of this logger with the - /// level. If this logger is - /// TRACE enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// The message object to log. - /// - /// - void Trace(object message); - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - void Trace(object message, Exception exception); - - /// Log a formatted message string with the level. - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void TraceFormat(string format, params object[] args); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void TraceFormat(string format, object arg0); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void TraceFormat(string format, object arg0, object arg1); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void TraceFormat(string format, object arg0, object arg1, object arg2); - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void TraceFormat(IFormatProvider provider, string format, params object[] args); - - /// Log a message object with the level. - /// - /// Log a message object with the level. - /// - /// The message object to log. - /// - /// - /// This method first checks if this logger is DEBUG - /// enabled by comparing the level of this logger with the - /// level. If this logger is - /// DEBUG enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - void Debug(object message); - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - void Debug(object message, Exception exception); - - /// Log a formatted string with the level. - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void DebugFormat(string format, params object[] args); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void DebugFormat(string format, object arg0); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void DebugFormat(string format, object arg0, object arg1); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void DebugFormat(string format, object arg0, object arg1, object arg2); - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void DebugFormat(IFormatProvider provider, string format, params object[] args); - - /// Log a message object with the level. - /// - /// Logs a message object with the level. - /// - /// - /// - /// This method first checks if this logger is INFO - /// enabled by comparing the level of this logger with the - /// level. If this logger is - /// INFO enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// The message object to log. - /// - /// - void Info(object message); - - /// - /// Logs a message object with the INFO level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - void Info(object message, Exception exception); - - /// Log a formatted message string with the level. - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void InfoFormat(string format, params object[] args); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void InfoFormat(string format, object arg0); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void InfoFormat(string format, object arg0, object arg1); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void InfoFormat(string format, object arg0, object arg1, object arg2); - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void InfoFormat(IFormatProvider provider, string format, params object[] args); - - /// Log a message object with the level. - /// - /// Log a message object with the level. - /// - /// - /// - /// This method first checks if this logger is WARN - /// enabled by comparing the level of this logger with the - /// level. If this logger is - /// WARN enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// The message object to log. - /// - /// - void Warn(object message); - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - void Warn(object message, Exception exception); - - /// Log a formatted message string with the level. - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void WarnFormat(string format, params object[] args); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void WarnFormat(string format, object arg0); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void WarnFormat(string format, object arg0, object arg1); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void WarnFormat(string format, object arg0, object arg1, object arg2); - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void WarnFormat(IFormatProvider provider, string format, params object[] args); - - /// Log a message object with the level. - /// - /// Logs a message object with the level. - /// - /// The message object to log. - /// - /// - /// This method first checks if this logger is ERROR - /// enabled by comparing the level of this logger with the - /// level. If this logger is - /// ERROR enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - void Error(object message); - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - void Error(object message, Exception exception); - - /// Log a formatted message string with the level. - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void ErrorFormat(string format, params object[] args); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void ErrorFormat(string format, object arg0); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void ErrorFormat(string format, object arg0, object arg1); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void ErrorFormat(string format, object arg0, object arg1, object arg2); - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void ErrorFormat(IFormatProvider provider, string format, params object[] args); - - /// Log a message object with the level. - /// - /// Log a message object with the level. - /// - /// - /// - /// This method first checks if this logger is FATAL - /// enabled by comparing the level of this logger with the - /// level. If this logger is - /// FATAL enabled, then it converts the message object - /// (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of the - /// additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// The message object to log. - /// - /// - void Fatal(object message); - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - void Fatal(object message, Exception exception); - - /// Log a formatted message string with the level. - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void FatalFormat(string format, params object[] args); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void FatalFormat(string format, object arg0); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void FatalFormat(string format, object arg0, object arg1); - - /// - /// Logs a formatted message string with the level. - /// - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void FatalFormat(string format, object arg0, object arg1, object arg2); - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - void FatalFormat(IFormatProvider provider, string format, params object[] args); - - /// - /// Checks if this logger is enabled for the level. - /// - /// - /// true if this logger is enabled for events, false otherwise. - /// - /// - /// - /// This function is intended to lessen the computational cost of - /// disabled log debug statements. - /// - /// For some ILog interface log, when you write: - /// - /// log.Debug("This is entry number: " + i ); - /// - /// - /// You incur the cost constructing the message, string construction and concatenation in - /// this case, regardless of whether the message is logged or not. - /// - /// - /// If you are worried about speed (who isn't), then you should write: - /// - /// - /// if (log.IsDebugEnabled) - /// { - /// log.Debug("This is entry number: " + i ); - /// } - /// - /// - /// This way you will not incur the cost of parameter - /// construction if debugging is disabled for log. On - /// the other hand, if the log is debug enabled, you - /// will incur the cost of evaluating whether the logger is debug - /// enabled twice. Once in and once in - /// the . This is an insignificant overhead - /// since evaluating a logger takes about 1% of the time it - /// takes to actually log. This is the preferred style of logging. - /// - /// Alternatively if your logger is available statically then the is debug - /// enabled state can be stored in a static variable like this: - /// - /// - /// private static readonly bool isDebugEnabled = log.IsDebugEnabled; - /// - /// - /// Then when you come to log you can write: - /// - /// - /// if (isDebugEnabled) - /// { - /// log.Debug("This is entry number: " + i ); - /// } - /// - /// - /// This way the debug enabled state is only queried once - /// when the class is loaded. Using a private static readonly - /// variable is the most efficient because it is a run time constant - /// and can be heavily optimized by the JIT compiler. - /// - /// - /// Of course if you use a static readonly variable to - /// hold the enabled state of the logger then you cannot - /// change the enabled state at runtime to vary the logging - /// that is produced. You have to decide if you need absolute - /// speed or runtime flexibility. - /// - /// - /// - /// - bool IsDebugEnabled { get; } - - /// - /// Checks if this logger is enabled for the level. - /// - /// - /// true if this logger is enabled for events, false otherwise. - /// - /// - /// For more information see . - /// - /// - /// - /// - bool IsTraceEnabled { get; } - - /// - /// Checks if this logger is enabled for the level. - /// - /// - /// true if this logger is enabled for events, false otherwise. - /// - /// - /// For more information see . - /// - /// - /// - /// - bool IsInfoEnabled { get; } - - /// - /// Checks if this logger is enabled for the level. - /// - /// - /// true if this logger is enabled for events, false otherwise. - /// - /// - /// For more information see . - /// - /// - /// - /// - bool IsWarnEnabled { get; } - - /// - /// Checks if this logger is enabled for the level. - /// - /// - /// true if this logger is enabled for events, false otherwise. - /// - /// - /// For more information see . - /// - /// - /// - /// - bool IsErrorEnabled { get; } - - /// - /// Checks if this logger is enabled for the level. - /// - /// - /// true if this logger is enabled for events, false otherwise. - /// - /// - /// For more information see . - /// - /// - /// - /// - bool IsFatalEnabled { get; } - - } -} diff --git a/src/log4net/Layout/DynamicPatternLayout.cs b/src/log4net/Layout/DynamicPatternLayout.cs deleted file mode 100644 index 28174be1..00000000 --- a/src/log4net/Layout/DynamicPatternLayout.cs +++ /dev/null @@ -1,143 +0,0 @@ -#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 System.Collections; -using System.IO; - -using log4net.Core; -using log4net.Layout.Pattern; -using log4net.Util; - -namespace log4net.Layout -{ - /// - /// A flexible layout configurable with pattern string that re-evaluates on each call. - /// - /// - /// This class is built on and provides all the - /// features and capabilities of PatternLayout. PatternLayout is a 'static' class - /// in that its layout is done once at configuration time. This class will recreate - /// the layout on each reference. - /// One important difference between PatternLayout and DynamicPatternLayout is the - /// treatment of the Header and Footer parameters in the configuration. The Header and Footer - /// parameters for DynamicPatternLayout must be syntactically in the form of a PatternString, - /// but should not be marked as type log4net.Util.PatternString. Doing so causes the - /// pattern to be statically converted at configuration time and causes DynamicPatternLayout - /// to perform the same as PatternLayout. - /// Please see for complete documentation. - /// - /// <layout type="log4net.Layout.DynamicPatternLayout"> - /// <param name="Header" value="%newline**** Trace Opened Local: %date{yyyy-MM-dd HH:mm:ss.fff} UTC: %utcdate{yyyy-MM-dd HH:mm:ss.fff} ****%newline" /> - /// <param name="Footer" value="**** Trace Closed %date{yyyy-MM-dd HH:mm:ss.fff} ****%newline" /> - /// </layout> - /// - /// - public class DynamicPatternLayout: PatternLayout - { - #region Member Variables - /// - /// The header PatternString - /// - private PatternString m_headerPatternString = new PatternString(""); - - /// - /// The footer PatternString - /// - private PatternString m_footerPatternString = new PatternString(""); - #endregion - - #region Constructors - /// - /// Constructs a DynamicPatternLayout using the DefaultConversionPattern - /// - /// - /// - /// The default pattern just produces the application supplied message. - /// - /// - public DynamicPatternLayout() - : base() - { - } - - /// - /// Constructs a DynamicPatternLayout using the supplied conversion pattern - /// - /// the pattern to use - /// - /// - public DynamicPatternLayout (string pattern) - : base(pattern) - { - } - #endregion - - #region Override implementation of LayoutSkeleton - /// - /// The header for the layout format. - /// - /// the layout header - /// - /// - /// The Header text will be appended before any logging events - /// are formatted and appended. - /// - /// The pattern will be formatted on each get operation. - /// - public override string Header - { - get - { - return m_headerPatternString.Format(); - } - set - { - base.Header = value; - m_headerPatternString = new PatternString(value); - } - } /* property DynamicPatternLayout Header */ - - /// - /// The footer for the layout format. - /// - /// the layout footer - /// - /// - /// The Footer text will be appended after all the logging events - /// have been formatted and appended. - /// - /// The pattern will be formatted on each get operation. - /// - public override string Footer - { - get - { - return m_footerPatternString.Format(); - } - set - { - base.Footer = value; - m_footerPatternString = new PatternString(value); - } - } /* property DynamicPatternLayout Footer */ - #endregion - } /* class DynamicPatternLayout */ -} /* namespace log4net.Layout */ diff --git a/src/log4net/Layout/ExceptionLayout.cs b/src/log4net/Layout/ExceptionLayout.cs deleted file mode 100644 index 06c4509b..00000000 --- a/src/log4net/Layout/ExceptionLayout.cs +++ /dev/null @@ -1,108 +0,0 @@ -#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 System.IO; -using System.Text; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Layout -{ - /// - /// A Layout that renders only the Exception text from the logging event - /// - /// - /// - /// A Layout that renders only the Exception text from the logging event. - /// - /// - /// This Layout should only be used with appenders that utilize multiple - /// layouts (e.g. ). - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class ExceptionLayout : LayoutSkeleton - { - #region Constructors - - /// - /// Default constructor - /// - /// - /// - /// Constructs a ExceptionLayout - /// - /// - public ExceptionLayout() - { - this.IgnoresException = false; - } - - #endregion - - #region Implementation of IOptionHandler - - /// - /// Activate component options - /// - /// - /// - /// Part of the component activation - /// framework. - /// - /// - /// This method does nothing as options become effective immediately. - /// - /// - override public void ActivateOptions() - { - // nothing to do. - } - - #endregion - - #region Override implementation of LayoutSkeleton - - /// - /// Gets the exception text from the logging event - /// - /// The TextWriter to write the formatted event to - /// the event being logged - /// - /// - /// Write the exception string to the . - /// The exception string is retrieved from . - /// - /// - override public void Format(TextWriter writer, LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - writer.Write(loggingEvent.GetExceptionString()); - } - - #endregion - } -} diff --git a/src/log4net/Layout/ILayout.cs b/src/log4net/Layout/ILayout.cs deleted file mode 100644 index 2bb6aef4..00000000 --- a/src/log4net/Layout/ILayout.cs +++ /dev/null @@ -1,121 +0,0 @@ -#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 System.IO; - -using log4net; -using log4net.Core; - -namespace log4net.Layout -{ - /// - /// Interface implemented by layout objects - /// - /// - /// - /// An object is used to format a - /// as text. The method is called by an - /// appender to transform the into a string. - /// - /// - /// The layout can also supply and - /// text that is appender before any events and after all the events respectively. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface ILayout - { - /// - /// Implement this method to create your own layout format. - /// - /// The TextWriter to write the formatted event to - /// The event to format - /// - /// - /// This method is called by an appender to format - /// the as text and output to a writer. - /// - /// - /// If the caller does not have a and prefers the - /// event to be formatted as a then the following - /// code can be used to format the event into a . - /// - /// - /// StringWriter writer = new StringWriter(); - /// Layout.Format(writer, loggingEvent); - /// string formattedEvent = writer.ToString(); - /// - /// - void Format(TextWriter writer, LoggingEvent loggingEvent); - - /// - /// The content type output by this layout. - /// - /// The content type - /// - /// - /// The content type output by this layout. - /// - /// - /// This is a MIME type e.g. "text/plain". - /// - /// - string ContentType { get; } - - /// - /// The header for the layout format. - /// - /// the layout header - /// - /// - /// The Header text will be appended before any logging events - /// are formatted and appended. - /// - /// - string Header { get; } - - /// - /// The footer for the layout format. - /// - /// the layout footer - /// - /// - /// The Footer text will be appended after all the logging events - /// have been formatted and appended. - /// - /// - string Footer { get; } - - /// - /// Flag indicating if this layout handle exceptions - /// - /// false if this layout handles exceptions - /// - /// - /// If this layout handles the exception object contained within - /// , then the layout should return - /// false. Otherwise, if the layout ignores the exception - /// object, then the layout should return true. - /// - /// - bool IgnoresException { get; } - } -} diff --git a/src/log4net/Layout/IRawLayout.cs b/src/log4net/Layout/IRawLayout.cs deleted file mode 100644 index 41cbf975..00000000 --- a/src/log4net/Layout/IRawLayout.cs +++ /dev/null @@ -1,61 +0,0 @@ -#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; -using log4net.Core; -using log4net.Util.TypeConverters; - -namespace log4net.Layout -{ - /// - /// Interface for raw layout objects - /// - /// - /// - /// Interface used to format a - /// to an object. - /// - /// - /// This interface should not be confused with the - /// interface. This interface is used in - /// only certain specialized situations where a raw object is - /// required rather than a formatted string. The - /// is not generally useful than this interface. - /// - /// - /// Nicko Cadell - /// Gert Driesen - [TypeConverter(typeof(RawLayoutConverter))] - public interface IRawLayout - { - /// - /// Implement this method to create your own layout format. - /// - /// The event to format - /// returns the formatted event - /// - /// - /// Implement this method to create your own layout format. - /// - /// - object Format(LoggingEvent loggingEvent); - } -} diff --git a/src/log4net/Layout/Layout2RawLayoutAdapter.cs b/src/log4net/Layout/Layout2RawLayoutAdapter.cs deleted file mode 100644 index 5b3707c2..00000000 --- a/src/log4net/Layout/Layout2RawLayoutAdapter.cs +++ /dev/null @@ -1,93 +0,0 @@ -#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 System.IO; - -using log4net; -using log4net.Core; - -namespace log4net.Layout -{ - /// - /// Adapts any to a - /// - /// - /// - /// Where an is required this adapter - /// allows a to be specified. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class Layout2RawLayoutAdapter : IRawLayout - { - #region Member Variables - - /// - /// The layout to adapt - /// - private ILayout m_layout; - - #endregion - - #region Constructors - - /// - /// Construct a new adapter - /// - /// the layout to adapt - /// - /// - /// Create the adapter for the specified . - /// - /// - public Layout2RawLayoutAdapter(ILayout layout) - { - m_layout = layout; - } - - #endregion - - #region Implementation of IRawLayout - - /// - /// Format the logging event as an object. - /// - /// The event to format - /// returns the formatted event - /// - /// - /// Format the logging event as an object. - /// - /// - /// Uses the object supplied to - /// the constructor to perform the formatting. - /// - /// - virtual public object Format(LoggingEvent loggingEvent) - { - StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture); - m_layout.Format(writer, loggingEvent); - return writer.ToString(); - } - - #endregion - } -} diff --git a/src/log4net/Layout/LayoutSkeleton.cs b/src/log4net/Layout/LayoutSkeleton.cs deleted file mode 100644 index b373ee14..00000000 --- a/src/log4net/Layout/LayoutSkeleton.cs +++ /dev/null @@ -1,232 +0,0 @@ -#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 System.IO; - -using log4net; -using log4net.Core; - -namespace log4net.Layout -{ - /// - /// Extend this abstract class to create your own log layout format. - /// - /// - /// - /// This is the base implementation of the - /// interface. Most layout objects should extend this class. - /// - /// - /// - /// - /// - /// Subclasses must implement the - /// method. - /// - /// - /// Subclasses should set the in their default - /// constructor. - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - public abstract class LayoutSkeleton : ILayout, IOptionHandler - { - #region Member Variables - - /// - /// The header text - /// - /// - /// - /// See for more information. - /// - /// - private string m_header = null; - - /// - /// The footer text - /// - /// - /// - /// See for more information. - /// - /// - private string m_footer = null; - - /// - /// Flag indicating if this layout handles exceptions - /// - /// - /// - /// false if this layout handles exceptions - /// - /// - private bool m_ignoresException = true; - - #endregion - - #region Constructors - - /// - /// Empty default constructor - /// - /// - /// - /// Empty default constructor - /// - /// - protected LayoutSkeleton() - { - } - - #endregion - - #region Implementation of IOptionHandler - - /// - /// Activate component options - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// This method must be implemented by the subclass. - /// - /// - abstract public void ActivateOptions(); - - #endregion - - #region Implementation of ILayout - - /// - /// Implement this method to create your own layout format. - /// - /// The TextWriter to write the formatted event to - /// The event to format - /// - /// - /// This method is called by an appender to format - /// the as text. - /// - /// - abstract public void Format(TextWriter writer, LoggingEvent loggingEvent); - - /// - /// Convenience method for easily formatting the logging event into a string variable. - /// - /// - /// - /// Creates a new StringWriter instance to store the formatted logging event. - /// - public string Format(LoggingEvent loggingEvent) - { - StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture); - Format(writer, loggingEvent); - return writer.ToString(); - } - - /// - /// The content type output by this layout. - /// - /// The content type is "text/plain" - /// - /// - /// The content type output by this layout. - /// - /// - /// This base class uses the value "text/plain". - /// To change this value a subclass must override this - /// property. - /// - /// - virtual public string ContentType - { - get { return "text/plain"; } - } - - /// - /// The header for the layout format. - /// - /// the layout header - /// - /// - /// The Header text will be appended before any logging events - /// are formatted and appended. - /// - /// - virtual public string Header - { - get { return m_header; } - set { m_header = value; } - } - - /// - /// The footer for the layout format. - /// - /// the layout footer - /// - /// - /// The Footer text will be appended after all the logging events - /// have been formatted and appended. - /// - /// - virtual public string Footer - { - get { return m_footer; } - set { m_footer = value; } - } - - /// - /// Flag indicating if this layout handles exceptions - /// - /// false if this layout handles exceptions - /// - /// - /// If this layout handles the exception object contained within - /// , then the layout should return - /// false. Otherwise, if the layout ignores the exception - /// object, then the layout should return true. - /// - /// - /// Set this value to override a this default setting. The default - /// value is true, this layout does not handle the exception. - /// - /// - virtual public bool IgnoresException - { - get { return m_ignoresException; } - set { m_ignoresException = value; } - } - - #endregion - } -} diff --git a/src/log4net/Layout/Pattern/AppDomainPatternConverter.cs b/src/log4net/Layout/Pattern/AppDomainPatternConverter.cs deleted file mode 100644 index 37369c4f..00000000 --- a/src/log4net/Layout/Pattern/AppDomainPatternConverter.cs +++ /dev/null @@ -1,55 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the event appdomain name to the output - /// - /// - /// - /// Writes the to the output writer. - /// - /// - /// Daniel Cazzulino - /// Nicko Cadell - internal sealed class AppDomainPatternConverter : PatternLayoutConverter - { - /// - /// Write the event appdomain name to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the to the output . - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write(loggingEvent.Domain); - } - } -} diff --git a/src/log4net/Layout/Pattern/AspNetCachePatternConverter.cs b/src/log4net/Layout/Pattern/AspNetCachePatternConverter.cs deleted file mode 100644 index 39aaab6e..00000000 --- a/src/log4net/Layout/Pattern/AspNetCachePatternConverter.cs +++ /dev/null @@ -1,76 +0,0 @@ -#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 - -// .NET Compact Framework has no support for ASP.NET -#if !NETCF && !CLIENT_PROFILE - -using System.IO; -using System.Web; -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter for items in the ASP.Net Cache. - /// - /// - /// - /// Outputs an item from the . - /// - /// - /// Ron Grabowski - internal sealed class AspNetCachePatternConverter : AspNetPatternLayoutConverter - { - /// - /// Write the ASP.Net Cache item to the output - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. If no property has been set, all key value pairs from the Cache will - /// be written to the output. - /// - /// - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) - { - if (HttpRuntime.Cache != null) - { - if (Option != null) - { - WriteObject(writer, loggingEvent.Repository, HttpRuntime.Cache[Option]); - } - else - { - WriteObject(writer, loggingEvent.Repository, HttpRuntime.Cache.GetEnumerator()); - } - } - else - { - writer.Write(SystemInfo.NotAvailableText); - } - } - } -} - -#endif \ No newline at end of file diff --git a/src/log4net/Layout/Pattern/AspNetContextPatternConverter.cs b/src/log4net/Layout/Pattern/AspNetContextPatternConverter.cs deleted file mode 100644 index 9a6e674e..00000000 --- a/src/log4net/Layout/Pattern/AspNetContextPatternConverter.cs +++ /dev/null @@ -1,67 +0,0 @@ -#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 - -// .NET Compact Framework has no support for ASP.NET -#if !NETCF && !CLIENT_PROFILE - -using System.IO; -using System.Web; -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter for items in the . - /// - /// - /// - /// Outputs an item from the . - /// - /// - /// Ron Grabowski - internal sealed class AspNetContextPatternConverter : AspNetPatternLayoutConverter - { - /// - /// Write the ASP.Net HttpContext item to the output - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. - /// - /// - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) - { - if (Option != null) - { - WriteObject(writer, loggingEvent.Repository, httpContext.Items[Option]); - } - else - { - WriteObject(writer, loggingEvent.Repository, httpContext.Items); - } - } - } -} - -#endif \ No newline at end of file diff --git a/src/log4net/Layout/Pattern/AspNetPatternConverter.cs b/src/log4net/Layout/Pattern/AspNetPatternConverter.cs deleted file mode 100644 index d16b5b34..00000000 --- a/src/log4net/Layout/Pattern/AspNetPatternConverter.cs +++ /dev/null @@ -1,64 +0,0 @@ -#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 - -// .NET Compact Framework has no support for ASP.NET -#if !NETCF && !CLIENT_PROFILE - -using System.IO; -using System.Web; -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout.Pattern -{ - /// - /// Abstract class that provides access to the current HttpContext () that - /// derived classes need. - /// - /// - /// This class handles the case when HttpContext.Current is null by writing - /// to the writer. - /// - /// Ron Grabowski - internal abstract class AspNetPatternLayoutConverter : PatternLayoutConverter - { - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - if (HttpContext.Current == null) - { - writer.Write(SystemInfo.NotAvailableText); - } - else - { - Convert(writer, loggingEvent, HttpContext.Current); - } - } - - /// - /// Derived pattern converters must override this method in order to - /// convert conversion specifiers in the correct way. - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - protected abstract void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext); - } -} - -#endif \ No newline at end of file diff --git a/src/log4net/Layout/Pattern/AspNetRequestPatternConverter.cs b/src/log4net/Layout/Pattern/AspNetRequestPatternConverter.cs deleted file mode 100644 index c83c4751..00000000 --- a/src/log4net/Layout/Pattern/AspNetRequestPatternConverter.cs +++ /dev/null @@ -1,85 +0,0 @@ -#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 - -// .NET Compact Framework has no support for ASP.NET -#if !NETCF && !CLIENT_PROFILE - -using System.IO; -using System.Web; -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter for items in the ASP.Net Cache. - /// - /// - /// - /// Outputs an item from the . - /// - /// - /// Ron Grabowski - internal sealed class AspNetRequestPatternConverter : AspNetPatternLayoutConverter - { - /// - /// Write the ASP.Net Cache item to the output - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. - /// - /// - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) - { - HttpRequest request = null; - try { - request = httpContext.Request; - } catch (HttpException) { - // likely a case of running in IIS integrated mode - // when inside an Application_Start event. - // treat it like a case of the Request - // property returning null - } - - if (request != null) - { - if (Option != null) - { - WriteObject(writer, loggingEvent.Repository, httpContext.Request.Params[Option]); - } - else - { - WriteObject(writer, loggingEvent.Repository, httpContext.Request.Params); - } - } - else - { - writer.Write(SystemInfo.NotAvailableText); - } - } - } -} - -#endif \ No newline at end of file diff --git a/src/log4net/Layout/Pattern/AspNetSessionPatternConverter.cs b/src/log4net/Layout/Pattern/AspNetSessionPatternConverter.cs deleted file mode 100644 index 782ddb97..00000000 --- a/src/log4net/Layout/Pattern/AspNetSessionPatternConverter.cs +++ /dev/null @@ -1,76 +0,0 @@ -#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 - -// .NET Compact Framework has no support for ASP.NET -#if !NETCF && !CLIENT_PROFILE - -using System.IO; -using System.Web; -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter for items in the ASP.Net Cache. - /// - /// - /// - /// Outputs an item from the . - /// - /// - /// Ron Grabowski - internal sealed class AspNetSessionPatternConverter : AspNetPatternLayoutConverter - { - /// - /// Write the ASP.Net Cache item to the output - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - /// The under which the ASP.Net request is running. - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. If no property has been set, all key value pairs from the Session will - /// be written to the output. - /// - /// - protected override void Convert(TextWriter writer, LoggingEvent loggingEvent, HttpContext httpContext) - { - if (httpContext.Session != null) - { - if (Option != null) - { - WriteObject(writer, loggingEvent.Repository, httpContext.Session.Contents[Option]); - } - else - { - WriteObject(writer, loggingEvent.Repository, httpContext.Session); - } - } - else - { - writer.Write(SystemInfo.NotAvailableText); - } - } - } -} - -#endif \ No newline at end of file diff --git a/src/log4net/Layout/Pattern/DatePatternConverter.cs b/src/log4net/Layout/Pattern/DatePatternConverter.cs deleted file mode 100644 index 91a4caa0..00000000 --- a/src/log4net/Layout/Pattern/DatePatternConverter.cs +++ /dev/null @@ -1,190 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; -using log4net.Util; -using log4net.DateFormatter; - -namespace log4net.Layout.Pattern -{ - /// - /// Date pattern converter, uses a to format - /// the date of a . - /// - /// - /// - /// Render the to the writer as a string. - /// - /// - /// The value of the determines - /// the formatting of the date. The following values are allowed: - /// - /// - /// Option value - /// Output - /// - /// - /// ISO8601 - /// - /// Uses the formatter. - /// Formats using the "yyyy-MM-dd HH:mm:ss,fff" pattern. - /// - /// - /// - /// DATE - /// - /// Uses the formatter. - /// Formats using the "dd MMM yyyy HH:mm:ss,fff" for example, "06 Nov 1994 15:49:37,459". - /// - /// - /// - /// ABSOLUTE - /// - /// Uses the formatter. - /// Formats using the "HH:mm:ss,yyyy" for example, "15:49:37,459". - /// - /// - /// - /// other - /// - /// Any other pattern string uses the formatter. - /// This formatter passes the pattern string to the - /// method. - /// For details on valid patterns see - /// DateTimeFormatInfo Class. - /// - /// - /// - /// - /// - /// The is in the local time zone and is rendered in that zone. - /// To output the time in Universal time see . - /// - /// - /// Nicko Cadell - internal class DatePatternConverter : PatternLayoutConverter, IOptionHandler - { - /// - /// The used to render the date to a string - /// - /// - /// - /// The used to render the date to a string - /// - /// - protected IDateFormatter m_dateFormatter; - - #region Implementation of IOptionHandler - - /// - /// Initialize the converter pattern based on the property. - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - public void ActivateOptions() - { - string dateFormatStr = Option; - if (dateFormatStr == null) - { - dateFormatStr = AbsoluteTimeDateFormatter.Iso8601TimeDateFormat; - } - - if (string.Compare(dateFormatStr, AbsoluteTimeDateFormatter.Iso8601TimeDateFormat, true, System.Globalization.CultureInfo.InvariantCulture) == 0) - { - m_dateFormatter = new Iso8601DateFormatter(); - } - else if (string.Compare(dateFormatStr, AbsoluteTimeDateFormatter.AbsoluteTimeDateFormat, true, System.Globalization.CultureInfo.InvariantCulture) == 0) - { - m_dateFormatter = new AbsoluteTimeDateFormatter(); - } - else if (string.Compare(dateFormatStr, AbsoluteTimeDateFormatter.DateAndTimeDateFormat, true, System.Globalization.CultureInfo.InvariantCulture) == 0) - { - m_dateFormatter = new DateTimeDateFormatter(); - } - else - { - try - { - m_dateFormatter = new SimpleDateFormatter(dateFormatStr); - } - catch (Exception e) - { - LogLog.Error(declaringType, "Could not instantiate SimpleDateFormatter with ["+dateFormatStr+"]", e); - m_dateFormatter = new Iso8601DateFormatter(); - } - } - } - - #endregion - - /// - /// Convert the pattern into the rendered message - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Pass the to the - /// for it to render it to the writer. - /// - /// - /// The passed is in the local time zone. - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - try - { - m_dateFormatter.FormatDate(loggingEvent.TimeStamp, writer); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Error occurred while converting date.", ex); - } - } - - #region Private Static Fields - - /// - /// The fully qualified type of the DatePatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(DatePatternConverter); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Layout/Pattern/ExceptionPatternConverter.cs b/src/log4net/Layout/Pattern/ExceptionPatternConverter.cs deleted file mode 100644 index f522d87d..00000000 --- a/src/log4net/Layout/Pattern/ExceptionPatternConverter.cs +++ /dev/null @@ -1,135 +0,0 @@ -#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.Diagnostics; -using System.IO; -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the exception text to the output - /// - /// - /// - /// If an exception object is stored in the logging event - /// it will be rendered into the pattern output with a - /// trailing newline. - /// - /// - /// If there is no exception then nothing will be output - /// and no trailing newline will be appended. - /// It is typical to put a newline before the exception - /// and to have the exception as the last data in the pattern. - /// - /// - /// Nicko Cadell - internal sealed class ExceptionPatternConverter : PatternLayoutConverter - { - /// - /// Default constructor - /// - public ExceptionPatternConverter() - { - // This converter handles the exception - IgnoresException = false; - } - - /// - /// Write the exception text to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// If an exception object is stored in the logging event - /// it will be rendered into the pattern output with a - /// trailing newline. - /// - /// - /// If there is no exception or the exception property specified - /// by the Option value does not exist then nothing will be output - /// and no trailing newline will be appended. - /// It is typical to put a newline before the exception - /// and to have the exception as the last data in the pattern. - /// - /// - /// Recognized values for the Option parameter are: - /// - /// - /// - /// Message - /// - /// - /// Source - /// - /// - /// StackTrace - /// - /// - /// TargetSite - /// - /// - /// HelpLink - /// - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - if (loggingEvent.ExceptionObject != null && Option != null && Option.Length > 0) - { - switch (Option.ToLower()) - { - case "message": - WriteObject(writer, loggingEvent.Repository, loggingEvent.ExceptionObject.Message); - break; -#if !NETCF - case "source": - WriteObject(writer, loggingEvent.Repository, loggingEvent.ExceptionObject.Source); - break; - case "stacktrace": - WriteObject(writer, loggingEvent.Repository, loggingEvent.ExceptionObject.StackTrace); - break; - case "targetsite": - WriteObject(writer, loggingEvent.Repository, loggingEvent.ExceptionObject.TargetSite); - break; - case "helplink": - WriteObject(writer, loggingEvent.Repository, loggingEvent.ExceptionObject.HelpLink); - break; -#endif - default: - // do not output SystemInfo.NotAvailableText - break; - } - } - else - { - string exceptionString = loggingEvent.GetExceptionString(); - if (exceptionString != null && exceptionString.Length > 0) - { - writer.WriteLine(exceptionString); - } - else - { - // do not output SystemInfo.NotAvailableText - } - } - } - } -} diff --git a/src/log4net/Layout/Pattern/FileLocationPatternConverter.cs b/src/log4net/Layout/Pattern/FileLocationPatternConverter.cs deleted file mode 100644 index bcec221e..00000000 --- a/src/log4net/Layout/Pattern/FileLocationPatternConverter.cs +++ /dev/null @@ -1,56 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Writes the caller location file name to the output - /// - /// - /// - /// Writes the value of the for - /// the event to the output writer. - /// - /// - /// Nicko Cadell - internal sealed class FileLocationPatternConverter : PatternLayoutConverter - { - /// - /// Write the caller location file name to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the value of the for - /// the to the output . - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write(loggingEvent.LocationInformation.FileName); - } - } -} diff --git a/src/log4net/Layout/Pattern/FullLocationPatternConverter.cs b/src/log4net/Layout/Pattern/FullLocationPatternConverter.cs deleted file mode 100644 index 2a3bedab..00000000 --- a/src/log4net/Layout/Pattern/FullLocationPatternConverter.cs +++ /dev/null @@ -1,54 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the caller location info to the output - /// - /// - /// - /// Writes the to the output writer. - /// - /// - /// Nicko Cadell - internal sealed class FullLocationPatternConverter : PatternLayoutConverter - { - /// - /// Write the caller location info to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the to the output writer. - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write( loggingEvent.LocationInformation.FullInfo ); - } - } -} diff --git a/src/log4net/Layout/Pattern/IdentityPatternConverter.cs b/src/log4net/Layout/Pattern/IdentityPatternConverter.cs deleted file mode 100644 index fd84299e..00000000 --- a/src/log4net/Layout/Pattern/IdentityPatternConverter.cs +++ /dev/null @@ -1,58 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Writes the event identity to the output - /// - /// - /// - /// Writes the value of the to - /// the output writer. - /// - /// - /// Daniel Cazzulino - /// Nicko Cadell - internal sealed class IdentityPatternConverter : PatternLayoutConverter - { - /// - /// Writes the event identity to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the value of the - /// to - /// the output . - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write(loggingEvent.Identity); - } - } -} diff --git a/src/log4net/Layout/Pattern/LevelPatternConverter.cs b/src/log4net/Layout/Pattern/LevelPatternConverter.cs deleted file mode 100644 index 35227e06..00000000 --- a/src/log4net/Layout/Pattern/LevelPatternConverter.cs +++ /dev/null @@ -1,56 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the event level to the output - /// - /// - /// - /// Writes the display name of the event - /// to the writer. - /// - /// - /// Nicko Cadell - internal sealed class LevelPatternConverter : PatternLayoutConverter - { - /// - /// Write the event level to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the of the - /// to the . - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write( loggingEvent.Level.DisplayName ); - } - } -} diff --git a/src/log4net/Layout/Pattern/LineLocationPatternConverter.cs b/src/log4net/Layout/Pattern/LineLocationPatternConverter.cs deleted file mode 100644 index 2e54dfae..00000000 --- a/src/log4net/Layout/Pattern/LineLocationPatternConverter.cs +++ /dev/null @@ -1,56 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the caller location line number to the output - /// - /// - /// - /// Writes the value of the for - /// the event to the output writer. - /// - /// - /// Nicko Cadell - internal sealed class LineLocationPatternConverter : PatternLayoutConverter - { - /// - /// Write the caller location line number to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the value of the for - /// the to the output . - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write(loggingEvent.LocationInformation.LineNumber); - } - } -} diff --git a/src/log4net/Layout/Pattern/LoggerPatternConverter.cs b/src/log4net/Layout/Pattern/LoggerPatternConverter.cs deleted file mode 100644 index b56f7c9d..00000000 --- a/src/log4net/Layout/Pattern/LoggerPatternConverter.cs +++ /dev/null @@ -1,54 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter for logger name - /// - /// - /// - /// Outputs the of the event. - /// - /// - /// Nicko Cadell - internal sealed class LoggerPatternConverter : NamedPatternConverter - { - /// - /// Gets the fully qualified name of the logger - /// - /// the event being logged - /// The fully qualified logger name - /// - /// - /// Returns the of the . - /// - /// - override protected string GetFullyQualifiedName(LoggingEvent loggingEvent) - { - return loggingEvent.LoggerName; - } - } -} diff --git a/src/log4net/Layout/Pattern/MessagePatternConverter.cs b/src/log4net/Layout/Pattern/MessagePatternConverter.cs deleted file mode 100644 index 43d13fe7..00000000 --- a/src/log4net/Layout/Pattern/MessagePatternConverter.cs +++ /dev/null @@ -1,56 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Writes the event message to the output - /// - /// - /// - /// Uses the method - /// to write out the event message. - /// - /// - /// Nicko Cadell - internal sealed class MessagePatternConverter : PatternLayoutConverter - { - /// - /// Writes the event message to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Uses the method - /// to write out the event message. - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - loggingEvent.WriteRenderedMessage(writer); - } - } -} diff --git a/src/log4net/Layout/Pattern/MethodLocationPatternConverter.cs b/src/log4net/Layout/Pattern/MethodLocationPatternConverter.cs deleted file mode 100644 index a0537adf..00000000 --- a/src/log4net/Layout/Pattern/MethodLocationPatternConverter.cs +++ /dev/null @@ -1,56 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the method name to the output - /// - /// - /// - /// Writes the caller location to - /// the output. - /// - /// - /// Nicko Cadell - internal sealed class MethodLocationPatternConverter : PatternLayoutConverter - { - /// - /// Write the method name to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the caller location to - /// the output. - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write(loggingEvent.LocationInformation.MethodName); - } - } -} diff --git a/src/log4net/Layout/Pattern/NamedPatternConverter.cs b/src/log4net/Layout/Pattern/NamedPatternConverter.cs deleted file mode 100644 index 8338706e..00000000 --- a/src/log4net/Layout/Pattern/NamedPatternConverter.cs +++ /dev/null @@ -1,171 +0,0 @@ -#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 System.Globalization; -using System.Text; -using System.IO; - -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter to output and truncate '.' separated strings - /// - /// - /// - /// This abstract class supports truncating a '.' separated string - /// to show a specified number of elements from the right hand side. - /// This is used to truncate class names that are fully qualified. - /// - /// - /// Subclasses should override the method to - /// return the fully qualified string. - /// - /// - /// Nicko Cadell - public abstract class NamedPatternConverter : PatternLayoutConverter, IOptionHandler - { - private int m_precision = 0; - - #region Implementation of IOptionHandler - - /// - /// Initialize the converter - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - public void ActivateOptions() - { - m_precision = 0; - - if (Option != null) - { - string optStr = Option.Trim(); - if (optStr.Length > 0) - { - int precisionVal; - if (SystemInfo.TryParse(optStr, out precisionVal)) - { - if (precisionVal <= 0) - { - LogLog.Error(declaringType, "NamedPatternConverter: Precision option (" + optStr + ") isn't a positive integer."); - } - else - { - m_precision = precisionVal; - } - } - else - { - LogLog.Error(declaringType, "NamedPatternConverter: Precision option \"" + optStr + "\" not a decimal integer."); - } - } - } - } - - #endregion - - /// - /// Get the fully qualified string data - /// - /// the event being logged - /// the fully qualified name - /// - /// - /// Overridden by subclasses to get the fully qualified name before the - /// precision is applied to it. - /// - /// - /// Return the fully qualified '.' (dot/period) separated string. - /// - /// - abstract protected string GetFullyQualifiedName(LoggingEvent loggingEvent); - - /// - /// Convert the pattern to the rendered message - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// Render the to the precision - /// specified by the property. - /// - sealed override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - string name = GetFullyQualifiedName(loggingEvent); - if (m_precision <= 0 || name == null || name.Length < 2) - { - writer.Write(name); - } - else - { - int len = name.Length; - string trailingDot = string.Empty; - if (name.EndsWith(DOT)) - { - trailingDot = DOT; - name = name.Substring(0, len - 1); - len--; - } - - int end = name.LastIndexOf(DOT); - for(int i = 1; end > 0 && i < m_precision; i++) - { - end = name.LastIndexOf('.', end - 1); - } - if (end == -1) - { - writer.Write(name + trailingDot); - } - else - { - writer.Write(name.Substring(end + 1, len - end - 1) + trailingDot); - } - } - } - - #region Private Static Fields - - /// - /// The fully qualified type of the NamedPatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(NamedPatternConverter); - - private const string DOT = "."; - #endregion Private Static Fields - } -} diff --git a/src/log4net/Layout/Pattern/NdcPatternConverter.cs b/src/log4net/Layout/Pattern/NdcPatternConverter.cs deleted file mode 100644 index 947fb129..00000000 --- a/src/log4net/Layout/Pattern/NdcPatternConverter.cs +++ /dev/null @@ -1,62 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter to include event NDC - /// - /// - /// - /// Outputs the value of the event property named NDC. - /// - /// - /// The should be used instead. - /// - /// - /// Nicko Cadell - internal sealed class NdcPatternConverter : PatternLayoutConverter - { - /// - /// Write the event NDC to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// As the thread context stacks are now stored in named event properties - /// this converter simply looks up the value of the NDC property. - /// - /// - /// The should be used instead. - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - // Write the value for the specified key - WriteObject(writer, loggingEvent.Repository, loggingEvent.LookupProperty("NDC")); - } - } -} diff --git a/src/log4net/Layout/Pattern/PatternLayoutConverter.cs b/src/log4net/Layout/Pattern/PatternLayoutConverter.cs deleted file mode 100644 index f0ed36f3..00000000 --- a/src/log4net/Layout/Pattern/PatternLayoutConverter.cs +++ /dev/null @@ -1,123 +0,0 @@ -#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 System.Text; -using System.IO; -using System.Collections; - -using log4net.Core; -using log4net.Util; -using log4net.Repository; - -namespace log4net.Layout.Pattern -{ - /// - /// Abstract class that provides the formatting functionality that - /// derived classes need. - /// - /// - /// Conversion specifiers in a conversion patterns are parsed to - /// individual PatternConverters. Each of which is responsible for - /// converting a logging event in a converter specific manner. - /// - /// Nicko Cadell - public abstract class PatternLayoutConverter : PatternConverter - { - #region Protected Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - protected PatternLayoutConverter() - { - } - - #endregion Protected Instance Constructors - - #region Public Properties - - /// - /// Flag indicating if this converter handles the logging event exception - /// - /// false if this converter handles the logging event exception - /// - /// - /// If this converter handles the exception object contained within - /// , then this property should be set to - /// false. Otherwise, if the layout ignores the exception - /// object, then the property should be set to true. - /// - /// - /// Set this value to override a this default setting. The default - /// value is true, this converter does not handle the exception. - /// - /// - virtual public bool IgnoresException - { - get { return m_ignoresException; } - set { m_ignoresException = value; } - } - - #endregion Public Properties - - #region Protected Abstract Methods - - /// - /// Derived pattern converters must override this method in order to - /// convert conversion specifiers in the correct way. - /// - /// that will receive the formatted result. - /// The on which the pattern converter should be executed. - abstract protected void Convert(TextWriter writer, LoggingEvent loggingEvent); - - #endregion Protected Abstract Methods - - #region Protected Methods - - /// - /// Derived pattern converters must override this method in order to - /// convert conversion specifiers in the correct way. - /// - /// that will receive the formatted result. - /// The state object on which the pattern converter should be executed. - override protected void Convert(TextWriter writer, object state) - { - LoggingEvent loggingEvent = state as LoggingEvent; - if (loggingEvent != null) - { - Convert(writer, loggingEvent); - } - else - { - throw new ArgumentException("state must be of type ["+typeof(LoggingEvent).FullName+"]", "state"); - } - } - - #endregion Protected Methods - - /// - /// Flag indicating if this converter handles exceptions - /// - /// - /// false if this converter handles exceptions - /// - private bool m_ignoresException = true; - } -} diff --git a/src/log4net/Layout/Pattern/PropertyPatternConverter.cs b/src/log4net/Layout/Pattern/PropertyPatternConverter.cs deleted file mode 100644 index f2d9e372..00000000 --- a/src/log4net/Layout/Pattern/PropertyPatternConverter.cs +++ /dev/null @@ -1,77 +0,0 @@ -#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 System.Text; -using System.IO; -using System.Collections; - -using log4net.Core; -using log4net.Repository; - -namespace log4net.Layout.Pattern -{ - /// - /// Property pattern converter - /// - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. - /// - /// - /// If the is set to null - /// then all the properties are written as key value pairs. - /// - /// - /// Nicko Cadell - internal sealed class PropertyPatternConverter : PatternLayoutConverter - { - /// - /// Write the property value to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. - /// - /// - /// If the is set to null - /// then all the properties are written as key value pairs. - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - if (Option != null) - { - // Write the value for the specified key - WriteObject(writer, loggingEvent.Repository, loggingEvent.LookupProperty(Option)); - } - else - { - // Write all the key value pairs - WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties()); - } - } - } -} diff --git a/src/log4net/Layout/Pattern/RelativeTimePatternConverter.cs b/src/log4net/Layout/Pattern/RelativeTimePatternConverter.cs deleted file mode 100644 index aa1cf276..00000000 --- a/src/log4net/Layout/Pattern/RelativeTimePatternConverter.cs +++ /dev/null @@ -1,70 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter to output the relative time of the event - /// - /// - /// - /// Converter to output the time of the event relative to the start of the program. - /// - /// - /// Nicko Cadell - internal sealed class RelativeTimePatternConverter : PatternLayoutConverter - { - /// - /// Write the relative time to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes out the relative time of the event in milliseconds. - /// That is the number of milliseconds between the event - /// and the . - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write( TimeDifferenceInMillis(LoggingEvent.StartTime, loggingEvent.TimeStamp).ToString(System.Globalization.NumberFormatInfo.InvariantInfo) ); - } - - /// - /// Helper method to get the time difference between two DateTime objects - /// - /// start time (in the current local time zone) - /// end time (in the current local time zone) - /// the time difference in milliseconds - private static long TimeDifferenceInMillis(DateTime start, DateTime end) - { - // We must convert all times to UTC before performing any mathematical - // operations on them. This allows use to take into account discontinuities - // caused by daylight savings time transitions. - return (long)(end.ToUniversalTime() - start.ToUniversalTime()).TotalMilliseconds; - } - } -} diff --git a/src/log4net/Layout/Pattern/StackTraceDetailPatternConverter.cs b/src/log4net/Layout/Pattern/StackTraceDetailPatternConverter.cs deleted file mode 100644 index 2bc54934..00000000 --- a/src/log4net/Layout/Pattern/StackTraceDetailPatternConverter.cs +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * 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. - * -*/ -#if !NETCF - -using System; -using System.Collections; -using System.Text; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the caller stack frames to the output - /// - /// - /// - /// Writes the to the output writer, using format: - /// type3.MethodCall3(type param,...) > type2.MethodCall2(type param,...) > type1.MethodCall1(type param,...) - /// - /// - /// Adam Davies - internal class StackTraceDetailPatternConverter : StackTracePatternConverter - { - internal override string GetMethodInformation(MethodItem method) - { - string returnValue=""; - - try - { - string param = ""; - string[] names = method.Parameters; - StringBuilder sb = new StringBuilder(); - if (names != null && names.GetUpperBound(0) > 0) - { - for (int i = 0; i <= names.GetUpperBound(0); i++) - { - sb.AppendFormat("{0}, ", names[i]); - } - } - - if (sb.Length > 0) - { - sb.Remove(sb.Length - 2, 2); - param = sb.ToString(); - } - - returnValue=base.GetMethodInformation(method) + "(" + param + ")"; - } - catch (Exception ex) - { - LogLog.Error(declaringType, "An exception ocurred while retreiving method information.", ex); - } - - return returnValue; - } - - #region Private Static Fields - - /// - /// The fully qualified type of the StackTraceDetailPatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(StackTracePatternConverter); - - #endregion Private Static Fields - } -} -#endif \ No newline at end of file diff --git a/src/log4net/Layout/Pattern/StackTracePatternConverter.cs b/src/log4net/Layout/Pattern/StackTracePatternConverter.cs deleted file mode 100644 index 747b6628..00000000 --- a/src/log4net/Layout/Pattern/StackTracePatternConverter.cs +++ /dev/null @@ -1,150 +0,0 @@ -#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 -#if !NETCF -using System; -using System.IO; -using System.Diagnostics; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the caller stack frames to the output - /// - /// - /// - /// Writes the to the output writer, using format: - /// type3.MethodCall3 > type2.MethodCall2 > type1.MethodCall1 - /// - /// - /// Michael Cromwell - internal class StackTracePatternConverter : PatternLayoutConverter, IOptionHandler - { - private int m_stackFrameLevel = 1; - - /// - /// Initialize the converter - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - public void ActivateOptions() - { - if (Option == null) - return; - - string optStr = Option.Trim(); - if (optStr.Length != 0) - { - int stackLevelVal; - if (SystemInfo.TryParse(optStr, out stackLevelVal)) - { - if (stackLevelVal <= 0) - { - LogLog.Error(declaringType, "StackTracePatternConverter: StackeFrameLevel option (" + optStr + ") isn't a positive integer."); - } - else - { - m_stackFrameLevel = stackLevelVal; - } - } - else - { - LogLog.Error(declaringType, "StackTracePatternConverter: StackFrameLevel option \"" + optStr + "\" not a decimal integer."); - } - } - } - - /// - /// Write the strack frames to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the to the output writer. - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - StackFrameItem[] stackframes = loggingEvent.LocationInformation.StackFrames; - if ((stackframes == null) || (stackframes.Length <= 0)) - { - LogLog.Error(declaringType, "loggingEvent.LocationInformation.StackFrames was null or empty."); - return; - } - - int stackFrameIndex = m_stackFrameLevel - 1; - while (stackFrameIndex >= 0) - { - if (stackFrameIndex >= stackframes.Length) - { - stackFrameIndex--; - continue; - } - - StackFrameItem stackFrame = stackframes[stackFrameIndex]; - writer.Write("{0}.{1}", stackFrame.ClassName, GetMethodInformation(stackFrame.Method)); - if (stackFrameIndex > 0) - { - // TODO: make this user settable? - writer.Write(" > "); - } - stackFrameIndex--; - } - } - - /// - /// Returns the Name of the method - /// - /// - /// This method was created, so this class could be used as a base class for StackTraceDetailPatternConverter - /// string - internal virtual string GetMethodInformation(MethodItem method) - { - return method.Name; - } - - #region Private Static Fields - - /// - /// The fully qualified type of the StackTracePatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(StackTracePatternConverter); - - #endregion Private Static Fields - } -} -#endif diff --git a/src/log4net/Layout/Pattern/ThreadPatternConverter.cs b/src/log4net/Layout/Pattern/ThreadPatternConverter.cs deleted file mode 100644 index c306a373..00000000 --- a/src/log4net/Layout/Pattern/ThreadPatternConverter.cs +++ /dev/null @@ -1,54 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter to include event thread name - /// - /// - /// - /// Writes the to the output. - /// - /// - /// Nicko Cadell - internal sealed class ThreadPatternConverter : PatternLayoutConverter - { - /// - /// Write the ThreadName to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Writes the to the . - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write(loggingEvent.ThreadName); - } - } -} diff --git a/src/log4net/Layout/Pattern/TypeNamePatternConverter.cs b/src/log4net/Layout/Pattern/TypeNamePatternConverter.cs deleted file mode 100644 index 0be44632..00000000 --- a/src/log4net/Layout/Pattern/TypeNamePatternConverter.cs +++ /dev/null @@ -1,54 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Pattern converter for the class name - /// - /// - /// - /// Outputs the of the event. - /// - /// - /// Nicko Cadell - internal sealed class TypeNamePatternConverter : NamedPatternConverter - { - /// - /// Gets the fully qualified name of the class - /// - /// the event being logged - /// The fully qualified type name for the caller location - /// - /// - /// Returns the of the . - /// - /// - override protected string GetFullyQualifiedName(LoggingEvent loggingEvent) - { - return loggingEvent.LocationInformation.ClassName; - } - } -} diff --git a/src/log4net/Layout/Pattern/UserNamePatternConverter.cs b/src/log4net/Layout/Pattern/UserNamePatternConverter.cs deleted file mode 100644 index 8c0518f5..00000000 --- a/src/log4net/Layout/Pattern/UserNamePatternConverter.cs +++ /dev/null @@ -1,45 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; - -namespace log4net.Layout.Pattern -{ - /// - /// Converter to include event user name - /// - /// Douglas de la Torre - /// Nicko Cadell - internal sealed class UserNamePatternConverter : PatternLayoutConverter - { - /// - /// Convert the pattern to the rendered message - /// - /// that will receive the formatted result. - /// the event being logged - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - writer.Write( loggingEvent.UserName ); - } - } -} diff --git a/src/log4net/Layout/Pattern/UtcDatePatternConverter.cs b/src/log4net/Layout/Pattern/UtcDatePatternConverter.cs deleted file mode 100644 index ea691f63..00000000 --- a/src/log4net/Layout/Pattern/UtcDatePatternConverter.cs +++ /dev/null @@ -1,91 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; -using log4net.Util; -using log4net.DateFormatter; - -namespace log4net.Layout.Pattern -{ - /// - /// Write the TimeStamp to the output - /// - /// - /// - /// Date pattern converter, uses a to format - /// the date of a . - /// - /// - /// Uses a to format the - /// in Universal time. - /// - /// - /// See the for details on the date pattern syntax. - /// - /// - /// - /// Nicko Cadell - internal class UtcDatePatternConverter : DatePatternConverter - { - /// - /// Write the TimeStamp to the output - /// - /// that will receive the formatted result. - /// the event being logged - /// - /// - /// Pass the to the - /// for it to render it to the writer. - /// - /// - /// The passed is in the local time zone, this is converted - /// to Universal time before it is rendered. - /// - /// - /// - override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) - { - try - { - m_dateFormatter.FormatDate(loggingEvent.TimeStamp.ToUniversalTime(), writer); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Error occurred while converting date.", ex); - } - } - - #region Private Static Fields - - /// - /// The fully qualified type of the UtcDatePatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(UtcDatePatternConverter); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Layout/PatternLayout.cs b/src/log4net/Layout/PatternLayout.cs deleted file mode 100644 index d7dcaa6a..00000000 --- a/src/log4net/Layout/PatternLayout.cs +++ /dev/null @@ -1,1169 +0,0 @@ -#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 System.Collections; -using System.IO; - -using log4net.Core; -using log4net.Layout.Pattern; -using log4net.Util; -using log4net.Util.PatternStringConverters; -using AppDomainPatternConverter=log4net.Layout.Pattern.AppDomainPatternConverter; -using DatePatternConverter=log4net.Layout.Pattern.DatePatternConverter; -using IdentityPatternConverter=log4net.Layout.Pattern.IdentityPatternConverter; -using PropertyPatternConverter=log4net.Layout.Pattern.PropertyPatternConverter; -using UserNamePatternConverter=log4net.Layout.Pattern.UserNamePatternConverter; -using UtcDatePatternConverter=log4net.Layout.Pattern.UtcDatePatternConverter; - -namespace log4net.Layout -{ - /// - /// A flexible layout configurable with pattern string. - /// - /// - /// - /// The goal of this class is to a - /// as a string. The results - /// depend on the conversion pattern. - /// - /// - /// The conversion pattern is closely related to the conversion - /// pattern of the printf function in C. A conversion pattern is - /// composed of literal text and format control expressions called - /// conversion specifiers. - /// - /// - /// You are free to insert any literal text within the conversion - /// pattern. - /// - /// - /// Each conversion specifier starts with a percent sign (%) and is - /// followed by optional format modifiers and a conversion - /// pattern name. The conversion pattern name specifies the type of - /// data, e.g. logger, level, date, thread name. The format - /// modifiers control such things as field width, padding, left and - /// right justification. The following is a simple example. - /// - /// - /// Let the conversion pattern be "%-5level [%thread]: %message%newline" and assume - /// that the log4net environment was set to use a PatternLayout. Then the - /// statements - /// - /// - /// ILog log = LogManager.GetLogger(typeof(TestApp)); - /// log.Debug("Message 1"); - /// log.Warn("Message 2"); - /// - /// would yield the output - /// - /// DEBUG [main]: Message 1 - /// WARN [main]: Message 2 - /// - /// - /// Note that there is no explicit separator between text and - /// conversion specifiers. The pattern parser knows when it has reached - /// the end of a conversion specifier when it reads a conversion - /// character. In the example above the conversion specifier - /// %-5level means the level of the logging event should be left - /// justified to a width of five characters. - /// - /// - /// The recognized conversion pattern names are: - /// - /// - /// - /// Conversion Pattern Name - /// Effect - /// - /// - /// a - /// Equivalent to appdomain - /// - /// - /// appdomain - /// - /// Used to output the friendly name of the AppDomain where the - /// logging event was generated. - /// - /// - /// - /// aspnet-cache - /// - /// - /// Used to output all cache items in the case of %aspnet-cache or just one named item if used as %aspnet-cache{key} - /// - /// - /// This pattern is not available for Compact Framework or Client Profile assemblies. - /// - /// - /// - /// - /// aspnet-context - /// - /// - /// Used to output all context items in the case of %aspnet-context or just one named item if used as %aspnet-context{key} - /// - /// - /// This pattern is not available for Compact Framework or Client Profile assemblies. - /// - /// - /// - /// - /// aspnet-request - /// - /// - /// Used to output all request parameters in the case of %aspnet-request or just one named param if used as %aspnet-request{key} - /// - /// - /// This pattern is not available for Compact Framework or Client Profile assemblies. - /// - /// - /// - /// - /// aspnet-session - /// - /// - /// Used to output all session items in the case of %aspnet-session or just one named item if used as %aspnet-session{key} - /// - /// - /// This pattern is not available for Compact Framework or Client Profile assemblies. - /// - /// - /// - /// - /// c - /// Equivalent to logger - /// - /// - /// C - /// Equivalent to type - /// - /// - /// class - /// Equivalent to type - /// - /// - /// d - /// Equivalent to date - /// - /// - /// date - /// - /// - /// Used to output the date of the logging event in the local time zone. - /// To output the date in universal time use the %utcdate pattern. - /// The date conversion - /// specifier may be followed by a date format specifier enclosed - /// between braces. For example, %date{HH:mm:ss,fff} or - /// %date{dd MMM yyyy HH:mm:ss,fff}. If no date format specifier is - /// given then ISO8601 format is - /// assumed (). - /// - /// - /// The date format specifier admits the same syntax as the - /// time pattern string of the . - /// - /// - /// For better results it is recommended to use the log4net date - /// formatters. These can be specified using one of the strings - /// "ABSOLUTE", "DATE" and "ISO8601" for specifying - /// , - /// and respectively - /// . For example, - /// %date{ISO8601} or %date{ABSOLUTE}. - /// - /// - /// These dedicated date formatters perform significantly - /// better than . - /// - /// - /// - /// - /// exception - /// - /// - /// Used to output the exception passed in with the log message. - /// - /// - /// If an exception object is stored in the logging event - /// it will be rendered into the pattern output with a - /// trailing newline. - /// If there is no exception then nothing will be output - /// and no trailing newline will be appended. - /// It is typical to put a newline before the exception - /// and to have the exception as the last data in the pattern. - /// - /// - /// - /// - /// F - /// Equivalent to file - /// - /// - /// file - /// - /// - /// Used to output the file name where the logging request was - /// issued. - /// - /// - /// WARNING Generating caller location information is - /// extremely slow. Its use should be avoided unless execution speed - /// is not an issue. - /// - /// - /// See the note below on the availability of caller location information. - /// - /// - /// - /// - /// identity - /// - /// - /// Used to output the user name for the currently active user - /// (Principal.Identity.Name). - /// - /// - /// WARNING Generating caller information is - /// extremely slow. Its use should be avoided unless execution speed - /// is not an issue. - /// - /// - /// - /// - /// l - /// Equivalent to location - /// - /// - /// L - /// Equivalent to line - /// - /// - /// location - /// - /// - /// Used to output location information of the caller which generated - /// the logging event. - /// - /// - /// The location information depends on the CLI implementation but - /// usually consists of the fully qualified name of the calling - /// method followed by the callers source the file name and line - /// number between parentheses. - /// - /// - /// The location information can be very useful. However, its - /// generation is extremely slow. Its use should be avoided - /// unless execution speed is not an issue. - /// - /// - /// See the note below on the availability of caller location information. - /// - /// - /// - /// - /// level - /// - /// - /// Used to output the level of the logging event. - /// - /// - /// - /// - /// line - /// - /// - /// Used to output the line number from where the logging request - /// was issued. - /// - /// - /// WARNING Generating caller location information is - /// extremely slow. Its use should be avoided unless execution speed - /// is not an issue. - /// - /// - /// See the note below on the availability of caller location information. - /// - /// - /// - /// - /// logger - /// - /// - /// Used to output the logger of the logging event. The - /// logger conversion specifier can be optionally followed by - /// precision specifier, that is a decimal constant in - /// brackets. - /// - /// - /// If a precision specifier is given, then only the corresponding - /// number of right most components of the logger name will be - /// printed. By default the logger name is printed in full. - /// - /// - /// For example, for the logger name "a.b.c" the pattern - /// %logger{2} will output "b.c". - /// - /// - /// - /// - /// m - /// Equivalent to message - /// - /// - /// M - /// Equivalent to method - /// - /// - /// message - /// - /// - /// Used to output the application supplied message associated with - /// the logging event. - /// - /// - /// - /// - /// mdc - /// - /// - /// The MDC (old name for the ThreadContext.Properties) is now part of the - /// combined event properties. This pattern is supported for compatibility - /// but is equivalent to property. - /// - /// - /// - /// - /// method - /// - /// - /// Used to output the method name where the logging request was - /// issued. - /// - /// - /// WARNING Generating caller location information is - /// extremely slow. Its use should be avoided unless execution speed - /// is not an issue. - /// - /// - /// See the note below on the availability of caller location information. - /// - /// - /// - /// - /// n - /// Equivalent to newline - /// - /// - /// newline - /// - /// - /// Outputs the platform dependent line separator character or - /// characters. - /// - /// - /// This conversion pattern offers the same performance as using - /// non-portable line separator strings such as "\n", or "\r\n". - /// Thus, it is the preferred way of specifying a line separator. - /// - /// - /// - /// - /// ndc - /// - /// - /// Used to output the NDC (nested diagnostic context) associated - /// with the thread that generated the logging event. - /// - /// - /// - /// - /// p - /// Equivalent to level - /// - /// - /// P - /// Equivalent to property - /// - /// - /// properties - /// Equivalent to property - /// - /// - /// property - /// - /// - /// Used to output the an event specific property. The key to - /// lookup must be specified within braces and directly following the - /// pattern specifier, e.g. %property{user} would include the value - /// from the property that is keyed by the string 'user'. Each property value - /// that is to be included in the log must be specified separately. - /// Properties are added to events by loggers or appenders. By default - /// the log4net:HostName property is set to the name of machine on - /// which the event was originally logged. - /// - /// - /// If no key is specified, e.g. %property then all the keys and their - /// values are printed in a comma separated list. - /// - /// - /// The properties of an event are combined from a number of different - /// contexts. These are listed below in the order in which they are searched. - /// - /// - /// - /// the event properties - /// - /// The event has that can be set. These - /// properties are specific to this event only. - /// - /// - /// - /// the thread properties - /// - /// The that are set on the current - /// thread. These properties are shared by all events logged on this thread. - /// - /// - /// - /// the global properties - /// - /// The that are set globally. These - /// properties are shared by all the threads in the AppDomain. - /// - /// - /// - /// - /// - /// - /// - /// r - /// Equivalent to timestamp - /// - /// - /// stacktrace - /// - /// - /// Used to output the stack trace of the logging event - /// The stack trace level specifier may be enclosed - /// between braces. For example, %stacktrace{level}. - /// If no stack trace level specifier is given then 1 is assumed - /// - /// - /// Output uses the format: - /// type3.MethodCall3 > type2.MethodCall2 > type1.MethodCall1 - /// - /// - /// This pattern is not available for Compact Framework assemblies. - /// - /// - /// - /// - /// stacktracedetail - /// - /// - /// Used to output the stack trace of the logging event - /// The stack trace level specifier may be enclosed - /// between braces. For example, %stacktracedetail{level}. - /// If no stack trace level specifier is given then 1 is assumed - /// - /// - /// Output uses the format: - /// type3.MethodCall3(type param,...) > type2.MethodCall2(type param,...) > type1.MethodCall1(type param,...) - /// - /// - /// This pattern is not available for Compact Framework assemblies. - /// - /// - /// - /// - /// t - /// Equivalent to thread - /// - /// - /// timestamp - /// - /// - /// Used to output the number of milliseconds elapsed since the start - /// of the application until the creation of the logging event. - /// - /// - /// - /// - /// thread - /// - /// - /// Used to output the name of the thread that generated the - /// logging event. Uses the thread number if no name is available. - /// - /// - /// - /// - /// type - /// - /// - /// Used to output the fully qualified type name of the caller - /// issuing the logging request. This conversion specifier - /// can be optionally followed by precision specifier, that - /// is a decimal constant in brackets. - /// - /// - /// If a precision specifier is given, then only the corresponding - /// number of right most components of the class name will be - /// printed. By default the class name is output in fully qualified form. - /// - /// - /// For example, for the class name "log4net.Layout.PatternLayout", the - /// pattern %type{1} will output "PatternLayout". - /// - /// - /// WARNING Generating the caller class information is - /// slow. Thus, its use should be avoided unless execution speed is - /// not an issue. - /// - /// - /// See the note below on the availability of caller location information. - /// - /// - /// - /// - /// u - /// Equivalent to identity - /// - /// - /// username - /// - /// - /// Used to output the WindowsIdentity for the currently - /// active user. - /// - /// - /// WARNING Generating caller WindowsIdentity information is - /// extremely slow. Its use should be avoided unless execution speed - /// is not an issue. - /// - /// - /// - /// - /// utcdate - /// - /// - /// Used to output the date of the logging event in universal time. - /// The date conversion - /// specifier may be followed by a date format specifier enclosed - /// between braces. For example, %utcdate{HH:mm:ss,fff} or - /// %utcdate{dd MMM yyyy HH:mm:ss,fff}. If no date format specifier is - /// given then ISO8601 format is - /// assumed (). - /// - /// - /// The date format specifier admits the same syntax as the - /// time pattern string of the . - /// - /// - /// For better results it is recommended to use the log4net date - /// formatters. These can be specified using one of the strings - /// "ABSOLUTE", "DATE" and "ISO8601" for specifying - /// , - /// and respectively - /// . For example, - /// %utcdate{ISO8601} or %utcdate{ABSOLUTE}. - /// - /// - /// These dedicated date formatters perform significantly - /// better than . - /// - /// - /// - /// - /// w - /// Equivalent to username - /// - /// - /// x - /// Equivalent to ndc - /// - /// - /// X - /// Equivalent to mdc - /// - /// - /// % - /// - /// - /// The sequence %% outputs a single percent sign. - /// - /// - /// - /// - /// - /// The single letter patterns are deprecated in favor of the - /// longer more descriptive pattern names. - /// - /// - /// By default the relevant information is output as is. However, - /// with the aid of format modifiers it is possible to change the - /// minimum field width, the maximum field width and justification. - /// - /// - /// The optional format modifier is placed between the percent sign - /// and the conversion pattern name. - /// - /// - /// The first optional format modifier is the left justification - /// flag which is just the minus (-) character. Then comes the - /// optional minimum field width modifier. This is a decimal - /// constant that represents the minimum number of characters to - /// output. If the data item requires fewer characters, it is padded on - /// either the left or the right until the minimum width is - /// reached. The default is to pad on the left (right justify) but you - /// can specify right padding with the left justification flag. The - /// padding character is space. If the data item is larger than the - /// minimum field width, the field is expanded to accommodate the - /// data. The value is never truncated. - /// - /// - /// This behavior can be changed using the maximum field - /// width modifier which is designated by a period followed by a - /// decimal constant. If the data item is longer than the maximum - /// field, then the extra characters are removed from the - /// beginning of the data item and not from the end. For - /// example, it the maximum field width is eight and the data item is - /// ten characters long, then the first two characters of the data item - /// are dropped. This behavior deviates from the printf function in C - /// where truncation is done from the end. - /// - /// - /// Below are various format modifier examples for the logger - /// conversion specifier. - /// - ///
    - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///
    Format modifierleft justifyminimum widthmaximum widthcomment
    %20loggerfalse20none - /// - /// Left pad with spaces if the logger name is less than 20 - /// characters long. - /// - ///
    %-20loggertrue20none - /// - /// Right pad with spaces if the logger - /// name is less than 20 characters long. - /// - ///
    %.30loggerNAnone30 - /// - /// Truncate from the beginning if the logger - /// name is longer than 30 characters. - /// - ///
    %20.30loggerfalse2030 - /// - /// Left pad with spaces if the logger name is shorter than 20 - /// characters. However, if logger name is longer than 30 characters, - /// then truncate from the beginning. - /// - ///
    %-20.30loggertrue2030 - /// - /// Right pad with spaces if the logger name is shorter than 20 - /// characters. However, if logger name is longer than 30 characters, - /// then truncate from the beginning. - /// - ///
    - ///
    - /// - /// Note about caller location information.
    - /// The following patterns %type %file %line %method %location %class %C %F %L %l %M - /// all generate caller location information. - /// Location information uses the System.Diagnostics.StackTrace class to generate - /// a call stack. The caller's information is then extracted from this stack. - ///
    - /// - /// - /// The System.Diagnostics.StackTrace class is not supported on the - /// .NET Compact Framework 1.0 therefore caller location information is not - /// available on that framework. - /// - /// - /// - /// - /// The System.Diagnostics.StackTrace class has this to say about Release builds: - /// - /// - /// "StackTrace information will be most informative with Debug build configurations. - /// By default, Debug builds include debug symbols, while Release builds do not. The - /// debug symbols contain most of the file, method name, line number, and column - /// information used in constructing StackFrame and StackTrace objects. StackTrace - /// might not report as many method calls as expected, due to code transformations - /// that occur during optimization." - /// - /// - /// This means that in a Release build the caller information may be incomplete or may - /// not exist at all! Therefore caller location information cannot be relied upon in a Release build. - /// - /// - /// - /// Additional pattern converters may be registered with a specific - /// instance using the method. - /// - ///
    - /// - /// This is a more detailed pattern. - /// %timestamp [%thread] %level %logger %ndc - %message%newline - /// - /// - /// A similar pattern except that the relative time is - /// right padded if less than 6 digits, thread name is right padded if - /// less than 15 characters and truncated if longer and the logger - /// name is left padded if shorter than 30 characters and truncated if - /// longer. - /// %-6timestamp [%15.15thread] %-5level %30.30logger %ndc - %message%newline - /// - /// Nicko Cadell - /// Gert Driesen - /// Douglas de la Torre - /// Daniel Cazzulino - public class PatternLayout : LayoutSkeleton - { - #region Constants - - /// - /// Default pattern string for log output. - /// - /// - /// - /// Default pattern string for log output. - /// Currently set to the string "%message%newline" - /// which just prints the application supplied message. - /// - /// - public const string DefaultConversionPattern ="%message%newline"; - - /// - /// A detailed conversion pattern - /// - /// - /// - /// A conversion pattern which includes Time, Thread, Logger, and Nested Context. - /// Current value is %timestamp [%thread] %level %logger %ndc - %message%newline. - /// - /// - public const string DetailConversionPattern = "%timestamp [%thread] %level %logger %ndc - %message%newline"; - - #endregion - - #region Static Fields - - /// - /// Internal map of converter identifiers to converter types. - /// - /// - /// - /// This static map is overridden by the m_converterRegistry instance map - /// - /// - private static Hashtable s_globalRulesRegistry; - - #endregion Static Fields - - #region Member Variables - - /// - /// the pattern - /// - private string m_pattern; - - /// - /// the head of the pattern converter chain - /// - private PatternConverter m_head; - - /// - /// patterns defined on this PatternLayout only - /// - private Hashtable m_instanceRulesRegistry = new Hashtable(); - - #endregion - - #region Static Constructor - - /// - /// Initialize the global registry - /// - /// - /// - /// Defines the builtin global rules. - /// - /// - static PatternLayout() - { - s_globalRulesRegistry = new Hashtable(45); - - s_globalRulesRegistry.Add("literal", typeof(LiteralPatternConverter)); - s_globalRulesRegistry.Add("newline", typeof(NewLinePatternConverter)); - s_globalRulesRegistry.Add("n", typeof(NewLinePatternConverter)); - -// .NET Compact Framework has no support for ASP.NET -#if !NETCF && !CLIENT_PROFILE - s_globalRulesRegistry.Add("aspnet-cache", typeof(AspNetCachePatternConverter)); - s_globalRulesRegistry.Add("aspnet-context", typeof(AspNetContextPatternConverter)); - s_globalRulesRegistry.Add("aspnet-request", typeof(AspNetRequestPatternConverter)); - s_globalRulesRegistry.Add("aspnet-session", typeof(AspNetSessionPatternConverter)); -#endif - - s_globalRulesRegistry.Add("c", typeof(LoggerPatternConverter)); - s_globalRulesRegistry.Add("logger", typeof(LoggerPatternConverter)); - - s_globalRulesRegistry.Add("C", typeof(TypeNamePatternConverter)); - s_globalRulesRegistry.Add("class", typeof(TypeNamePatternConverter)); - s_globalRulesRegistry.Add("type", typeof(TypeNamePatternConverter)); - - s_globalRulesRegistry.Add("d", typeof(DatePatternConverter)); - s_globalRulesRegistry.Add("date", typeof(DatePatternConverter)); - - s_globalRulesRegistry.Add("exception", typeof(ExceptionPatternConverter)); - - s_globalRulesRegistry.Add("F", typeof(FileLocationPatternConverter)); - s_globalRulesRegistry.Add("file", typeof(FileLocationPatternConverter)); - - s_globalRulesRegistry.Add("l", typeof(FullLocationPatternConverter)); - s_globalRulesRegistry.Add("location", typeof(FullLocationPatternConverter)); - - s_globalRulesRegistry.Add("L", typeof(LineLocationPatternConverter)); - s_globalRulesRegistry.Add("line", typeof(LineLocationPatternConverter)); - - s_globalRulesRegistry.Add("m", typeof(MessagePatternConverter)); - s_globalRulesRegistry.Add("message", typeof(MessagePatternConverter)); - - s_globalRulesRegistry.Add("M", typeof(MethodLocationPatternConverter)); - s_globalRulesRegistry.Add("method", typeof(MethodLocationPatternConverter)); - - s_globalRulesRegistry.Add("p", typeof(LevelPatternConverter)); - s_globalRulesRegistry.Add("level", typeof(LevelPatternConverter)); - - s_globalRulesRegistry.Add("P", typeof(PropertyPatternConverter)); - s_globalRulesRegistry.Add("property", typeof(PropertyPatternConverter)); - s_globalRulesRegistry.Add("properties", typeof(PropertyPatternConverter)); - - s_globalRulesRegistry.Add("r", typeof(RelativeTimePatternConverter)); - s_globalRulesRegistry.Add("timestamp", typeof(RelativeTimePatternConverter)); - -#if !NETCF - s_globalRulesRegistry.Add("stacktrace", typeof(StackTracePatternConverter)); - s_globalRulesRegistry.Add("stacktracedetail", typeof(StackTraceDetailPatternConverter)); -#endif - - s_globalRulesRegistry.Add("t", typeof(ThreadPatternConverter)); - s_globalRulesRegistry.Add("thread", typeof(ThreadPatternConverter)); - - // For backwards compatibility the NDC patterns - s_globalRulesRegistry.Add("x", typeof(NdcPatternConverter)); - s_globalRulesRegistry.Add("ndc", typeof(NdcPatternConverter)); - - // For backwards compatibility the MDC patterns just do a property lookup - s_globalRulesRegistry.Add("X", typeof(PropertyPatternConverter)); - s_globalRulesRegistry.Add("mdc", typeof(PropertyPatternConverter)); - - s_globalRulesRegistry.Add("a", typeof(AppDomainPatternConverter)); - s_globalRulesRegistry.Add("appdomain", typeof(AppDomainPatternConverter)); - - s_globalRulesRegistry.Add("u", typeof(IdentityPatternConverter)); - s_globalRulesRegistry.Add("identity", typeof(IdentityPatternConverter)); - - s_globalRulesRegistry.Add("utcdate", typeof(UtcDatePatternConverter)); - s_globalRulesRegistry.Add("utcDate", typeof(UtcDatePatternConverter)); - s_globalRulesRegistry.Add("UtcDate", typeof(UtcDatePatternConverter)); - - s_globalRulesRegistry.Add("w", typeof(UserNamePatternConverter)); - s_globalRulesRegistry.Add("username", typeof(UserNamePatternConverter)); - } - - #endregion Static Constructor - - #region Constructors - - /// - /// Constructs a PatternLayout using the DefaultConversionPattern - /// - /// - /// - /// The default pattern just produces the application supplied message. - /// - /// - /// Note to Inheritors: This constructor calls the virtual method - /// . If you override this method be - /// aware that it will be called before your is called constructor. - /// - /// - /// As per the contract the - /// method must be called after the properties on this object have been - /// configured. - /// - /// - public PatternLayout() : this(DefaultConversionPattern) - { - } - - /// - /// Constructs a PatternLayout using the supplied conversion pattern - /// - /// the pattern to use - /// - /// - /// Note to Inheritors: This constructor calls the virtual method - /// . If you override this method be - /// aware that it will be called before your is called constructor. - /// - /// - /// When using this constructor the method - /// need not be called. This may not be the case when using a subclass. - /// - /// - public PatternLayout(string pattern) - { - // By default we do not process the exception - IgnoresException = true; - - m_pattern = pattern; - if (m_pattern == null) - { - m_pattern = DefaultConversionPattern; - } - - ActivateOptions(); - } - - #endregion - - /// - /// The pattern formatting string - /// - /// - /// - /// The ConversionPattern option. This is the string which - /// controls formatting and consists of a mix of literal content and - /// conversion specifiers. - /// - /// - public string ConversionPattern - { - get { return m_pattern; } - set { m_pattern = value; } - } - - /// - /// Create the pattern parser instance - /// - /// the pattern to parse - /// The that will format the event - /// - /// - /// Creates the used to parse the conversion string. Sets the - /// global and instance rules on the . - /// - /// - virtual protected PatternParser CreatePatternParser(string pattern) - { - PatternParser patternParser = new PatternParser(pattern); - - // Add all the builtin patterns - foreach(DictionaryEntry entry in s_globalRulesRegistry) - { - ConverterInfo converterInfo = new ConverterInfo(); - converterInfo.Name = (string)entry.Key; - converterInfo.Type = (Type)entry.Value; - patternParser.PatternConverters[entry.Key] = converterInfo; - } - // Add the instance patterns - foreach(DictionaryEntry entry in m_instanceRulesRegistry) - { - patternParser.PatternConverters[entry.Key] = entry.Value; - } - - return patternParser; - } - - #region Implementation of IOptionHandler - - /// - /// Initialize layout options - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - override public void ActivateOptions() - { - m_head = CreatePatternParser(m_pattern).Parse(); - - PatternConverter curConverter = m_head; - while(curConverter != null) - { - PatternLayoutConverter layoutConverter = curConverter as PatternLayoutConverter; - if (layoutConverter != null) - { - if (!layoutConverter.IgnoresException) - { - // Found converter that handles the exception - this.IgnoresException = false; - - break; - } - } - curConverter = curConverter.Next; - } - } - - #endregion - - #region Override implementation of LayoutSkeleton - - /// - /// Produces a formatted string as specified by the conversion pattern. - /// - /// the event being logged - /// The TextWriter to write the formatted event to - /// - /// - /// Parse the using the patter format - /// specified in the property. - /// - /// - override public void Format(TextWriter writer, LoggingEvent loggingEvent) - { - if (writer == null) - { - throw new ArgumentNullException("writer"); - } - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - PatternConverter c = m_head; - - // loop through the chain of pattern converters - while(c != null) - { - c.Format(writer, loggingEvent); - c = c.Next; - } - } - - #endregion - - /// - /// Add a converter to this PatternLayout - /// - /// the converter info - /// - /// - /// This version of the method is used by the configurator. - /// Programmatic users should use the alternative method. - /// - /// - public void AddConverter(ConverterInfo converterInfo) - { - if (converterInfo == null) throw new ArgumentNullException("converterInfo"); - - if (!typeof(PatternConverter).IsAssignableFrom(converterInfo.Type)) - { - throw new ArgumentException("The converter type specified [" + converterInfo.Type + "] must be a subclass of log4net.Util.PatternConverter", "converterInfo"); - } - m_instanceRulesRegistry[converterInfo.Name] = converterInfo; - } - - /// - /// Add a converter to this PatternLayout - /// - /// the name of the conversion pattern for this converter - /// the type of the converter - /// - /// - /// Add a named pattern converter to this instance. This - /// converter will be used in the formatting of the event. - /// This method must be called before . - /// - /// - /// The specified must extend the - /// type. - /// - /// - public void AddConverter(string name, Type type) - { - if (name == null) throw new ArgumentNullException("name"); - if (type == null) throw new ArgumentNullException("type"); - - ConverterInfo converterInfo = new ConverterInfo(); - converterInfo.Name = name; - converterInfo.Type = type; - - AddConverter(converterInfo); - } - } -} diff --git a/src/log4net/Layout/RawLayoutConverter.cs b/src/log4net/Layout/RawLayoutConverter.cs deleted file mode 100644 index d287d7d9..00000000 --- a/src/log4net/Layout/RawLayoutConverter.cs +++ /dev/null @@ -1,88 +0,0 @@ -#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; -using log4net.Core; -using log4net.Util.TypeConverters; - -namespace log4net.Layout -{ - /// - /// Type converter for the interface - /// - /// - /// - /// Used to convert objects to the interface. - /// Supports converting from the interface to - /// the interface using the . - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class RawLayoutConverter : IConvertFrom - { - #region Override Implementation of IRawLayout - - /// - /// Can the sourceType be converted to an - /// - /// the source to be to be converted - /// true if the source type can be converted to - /// - /// - /// Test if the can be converted to a - /// . Only is supported - /// as the . - /// - /// - public bool CanConvertFrom(Type sourceType) - { - // Accept an ILayout object - return (typeof(ILayout).IsAssignableFrom(sourceType)); - } - - /// - /// Convert the value to a object - /// - /// the value to convert - /// the object - /// - /// - /// Convert the object to a - /// object. If the object - /// is a then the - /// is used to adapt between the two interfaces, otherwise an - /// exception is thrown. - /// - /// - public object ConvertFrom(object source) - { - ILayout layout = source as ILayout; - if (layout != null) - { - return new Layout2RawLayoutAdapter(layout); - } - throw ConversionNotSupportedException.Create(typeof(IRawLayout), source); - } - - #endregion - } -} diff --git a/src/log4net/Layout/RawPropertyLayout.cs b/src/log4net/Layout/RawPropertyLayout.cs deleted file mode 100644 index f50dda2c..00000000 --- a/src/log4net/Layout/RawPropertyLayout.cs +++ /dev/null @@ -1,90 +0,0 @@ -#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 System.Text; - -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout -{ - /// - /// Extract the value of a property from the - /// - /// - /// - /// Extract the value of a property from the - /// - /// - /// Nicko Cadell - public class RawPropertyLayout : IRawLayout - { - #region Constructors - - /// - /// Constructs a RawPropertyLayout - /// - public RawPropertyLayout() - { - } - - #endregion - - private string m_key; - - /// - /// The name of the value to lookup in the LoggingEvent Properties collection. - /// - /// - /// Value to lookup in the LoggingEvent Properties collection - /// - /// - /// - /// String name of the property to lookup in the . - /// - /// - public string Key - { - get { return m_key; } - set { m_key = value; } - } - - #region Implementation of IRawLayout - - /// - /// Lookup the property for - /// - /// The event to format - /// returns property value - /// - /// - /// Looks up and returns the object value of the property - /// named . If there is no property defined - /// with than name then null will be returned. - /// - /// - public virtual object Format(LoggingEvent loggingEvent) - { - return loggingEvent.LookupProperty(m_key); - } - - #endregion - } -} diff --git a/src/log4net/Layout/RawTimeStampLayout.cs b/src/log4net/Layout/RawTimeStampLayout.cs deleted file mode 100644 index 66a4dec5..00000000 --- a/src/log4net/Layout/RawTimeStampLayout.cs +++ /dev/null @@ -1,74 +0,0 @@ -#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 System.Text; - -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout -{ - /// - /// Extract the date from the - /// - /// - /// - /// Extract the date from the - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class RawTimeStampLayout : IRawLayout - { - #region Constructors - - /// - /// Constructs a RawTimeStampLayout - /// - public RawTimeStampLayout() - { - } - - #endregion - - #region Implementation of IRawLayout - - /// - /// Gets the as a . - /// - /// The event to format - /// returns the time stamp - /// - /// - /// Gets the as a . - /// - /// - /// The time stamp is in local time. To format the time stamp - /// in universal time use . - /// - /// - public virtual object Format(LoggingEvent loggingEvent) - { - return loggingEvent.TimeStamp; - } - - #endregion - } -} diff --git a/src/log4net/Layout/RawUtcTimeStampLayout.cs b/src/log4net/Layout/RawUtcTimeStampLayout.cs deleted file mode 100644 index 4a06329f..00000000 --- a/src/log4net/Layout/RawUtcTimeStampLayout.cs +++ /dev/null @@ -1,74 +0,0 @@ -#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 System.Text; - -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout -{ - /// - /// Extract the date from the - /// - /// - /// - /// Extract the date from the - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class RawUtcTimeStampLayout : IRawLayout - { - #region Constructors - - /// - /// Constructs a RawUtcTimeStampLayout - /// - public RawUtcTimeStampLayout() - { - } - - #endregion - - #region Implementation of IRawLayout - - /// - /// Gets the as a . - /// - /// The event to format - /// returns the time stamp - /// - /// - /// Gets the as a . - /// - /// - /// The time stamp is in universal time. To format the time stamp - /// in local time use . - /// - /// - public virtual object Format(LoggingEvent loggingEvent) - { - return loggingEvent.TimeStamp.ToUniversalTime(); - } - - #endregion - } -} diff --git a/src/log4net/Layout/SimpleLayout.cs b/src/log4net/Layout/SimpleLayout.cs deleted file mode 100644 index b330ee7a..00000000 --- a/src/log4net/Layout/SimpleLayout.cs +++ /dev/null @@ -1,111 +0,0 @@ -#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 System.IO; -using System.Text; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Layout -{ - /// - /// A very simple layout - /// - /// - /// - /// SimpleLayout consists of the level of the log statement, - /// followed by " - " and then the log message itself. For example, - /// - /// DEBUG - Hello world - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class SimpleLayout : LayoutSkeleton - { - #region Constructors - - /// - /// Constructs a SimpleLayout - /// - public SimpleLayout() - { - IgnoresException = true; - } - - #endregion - - #region Implementation of IOptionHandler - - /// - /// Initialize layout options - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - override public void ActivateOptions() - { - // nothing to do. - } - - #endregion - - #region Override implementation of LayoutSkeleton - - /// - /// Produces a simple formatted output. - /// - /// the event being logged - /// The TextWriter to write the formatted event to - /// - /// - /// Formats the event as the level of the even, - /// followed by " - " and then the log message itself. The - /// output is terminated by a newline. - /// - /// - override public void Format(TextWriter writer, LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - writer.Write(loggingEvent.Level.DisplayName); - writer.Write(" - "); - loggingEvent.WriteRenderedMessage(writer); - writer.WriteLine(); - } - - #endregion - } -} diff --git a/src/log4net/Layout/XmlLayout.cs b/src/log4net/Layout/XmlLayout.cs deleted file mode 100644 index cb704cff..00000000 --- a/src/log4net/Layout/XmlLayout.cs +++ /dev/null @@ -1,359 +0,0 @@ -#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 System.Text; -using System.Xml; - -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout -{ - /// - /// Layout that formats the log events as XML elements. - /// - /// - /// - /// The output of the consists of a series of - /// log4net:event elements. It does not output a complete well-formed XML - /// file. The output is designed to be included as an external entity - /// in a separate file to form a correct XML file. - /// - /// - /// For example, if abc is the name of the file where - /// the output goes, then a well-formed XML file would - /// be: - /// - /// - /// <?xml version="1.0" ?> - /// - /// <!DOCTYPE log4net:events SYSTEM "log4net-events.dtd" [<!ENTITY data SYSTEM "abc">]> - /// - /// <log4net:events version="1.2" xmlns:log4net="http://logging.apache.org/log4net/schemas/log4net-events-1.2> - /// &data; - /// </log4net:events> - /// - /// - /// This approach enforces the independence of the - /// and the appender where it is embedded. - /// - /// - /// The version attribute helps components to correctly - /// interpret output generated by . The value of - /// this attribute should be "1.2" for release 1.2 and later. - /// - /// - /// Alternatively the Header and Footer properties can be - /// configured to output the correct XML header, open tag and close tag. - /// When setting the Header and Footer properties it is essential - /// that the underlying data store not be appendable otherwise the data - /// will become invalid XML. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class XmlLayout : XmlLayoutBase - { - #region Public Instance Constructors - - /// - /// Constructs an XmlLayout - /// - public XmlLayout() : base() - { - } - - /// - /// Constructs an XmlLayout. - /// - /// - /// - /// The LocationInfo option takes a boolean value. By - /// default, it is set to false which means there will be no location - /// information output by this layout. If the the option is set to - /// true, then the file name and line number of the statement - /// at the origin of the log statement will be output. - /// - /// - /// If you are embedding this layout within an SmtpAppender - /// then make sure to set the LocationInfo option of that - /// appender as well. - /// - /// - public XmlLayout(bool locationInfo) : base(locationInfo) - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// The prefix to use for all element names - /// - /// - /// - /// The default prefix is log4net. Set this property - /// to change the prefix. If the prefix is set to an empty string - /// then no prefix will be written. - /// - /// - public string Prefix - { - get { return m_prefix; } - set { m_prefix = value; } - } - - - /// - /// Set whether or not to base64 encode the message. - /// - /// - /// - /// By default the log message will be written as text to the xml - /// output. This can cause problems when the message contains binary - /// data. By setting this to true the contents of the message will be - /// base64 encoded. If this is set then invalid character replacement - /// (see ) will not be performed - /// on the log message. - /// - /// - public bool Base64EncodeMessage - { - get {return m_base64Message;} - set {m_base64Message=value;} - } - - /// - /// Set whether or not to base64 encode the property values. - /// - /// - /// - /// By default the properties will be written as text to the xml - /// output. This can cause problems when one or more properties contain - /// binary data. By setting this to true the values of the properties - /// will be base64 encoded. If this is set then invalid character replacement - /// (see ) will not be performed - /// on the property values. - /// - /// - public bool Base64EncodeProperties - { - get {return m_base64Properties;} - set {m_base64Properties=value;} - } - - - #endregion Public Instance Properties - - #region Implementation of IOptionHandler - - /// - /// Initialize layout options - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// Builds a cache of the element names - /// - /// - override public void ActivateOptions() - { - base.ActivateOptions(); - - // Cache the full element names including the prefix - if (m_prefix != null && m_prefix.Length > 0) - { - m_elmEvent = m_prefix + ":" + ELM_EVENT; - m_elmMessage = m_prefix + ":" + ELM_MESSAGE; - m_elmProperties = m_prefix + ":" + ELM_PROPERTIES; - m_elmData = m_prefix + ":" + ELM_DATA; - m_elmException = m_prefix + ":" + ELM_EXCEPTION; - m_elmLocation = m_prefix + ":" + ELM_LOCATION; - } - } - - #endregion Implementation of IOptionHandler - - #region Override implementation of XMLLayoutBase - - /// - /// Does the actual writing of the XML. - /// - /// The writer to use to output the event to. - /// The event to write. - /// - /// - /// Override the base class method - /// to write the to the . - /// - /// - override protected void FormatXml(XmlWriter writer, LoggingEvent loggingEvent) - { - writer.WriteStartElement(m_elmEvent); - writer.WriteAttributeString(ATTR_LOGGER, loggingEvent.LoggerName); - - writer.WriteAttributeString(ATTR_TIMESTAMP, XmlConvert.ToString(loggingEvent.TimeStamp, XmlDateTimeSerializationMode.Local)); - - writer.WriteAttributeString(ATTR_LEVEL, loggingEvent.Level.DisplayName); - writer.WriteAttributeString(ATTR_THREAD, loggingEvent.ThreadName); - - if (loggingEvent.Domain != null && loggingEvent.Domain.Length > 0) - { - writer.WriteAttributeString(ATTR_DOMAIN, loggingEvent.Domain); - } - if (loggingEvent.Identity != null && loggingEvent.Identity.Length > 0) - { - writer.WriteAttributeString(ATTR_IDENTITY, loggingEvent.Identity); - } - if (loggingEvent.UserName != null && loggingEvent.UserName.Length > 0) - { - writer.WriteAttributeString(ATTR_USERNAME, loggingEvent.UserName); - } - - // Append the message text - writer.WriteStartElement(m_elmMessage); - if (!this.Base64EncodeMessage) - { - Transform.WriteEscapedXmlString(writer, loggingEvent.RenderedMessage, this.InvalidCharReplacement); - } - else - { - byte[] messageBytes = Encoding.UTF8.GetBytes(loggingEvent.RenderedMessage); - string base64Message = Convert.ToBase64String(messageBytes, 0, messageBytes.Length); - Transform.WriteEscapedXmlString(writer, base64Message,this.InvalidCharReplacement); - } - writer.WriteEndElement(); - - PropertiesDictionary properties = loggingEvent.GetProperties(); - - // Append the properties text - if (properties.Count > 0) - { - writer.WriteStartElement(m_elmProperties); - foreach(System.Collections.DictionaryEntry entry in properties) - { - writer.WriteStartElement(m_elmData); - writer.WriteAttributeString(ATTR_NAME, Transform.MaskXmlInvalidCharacters((string)entry.Key,this.InvalidCharReplacement)); - - // Use an ObjectRenderer to convert the object to a string - string valueStr =null; - if (!this.Base64EncodeProperties) - { - valueStr = Transform.MaskXmlInvalidCharacters(loggingEvent.Repository.RendererMap.FindAndRender(entry.Value),this.InvalidCharReplacement); - } - else - { - byte[] propertyValueBytes = Encoding.UTF8.GetBytes(loggingEvent.Repository.RendererMap.FindAndRender(entry.Value)); - valueStr = Convert.ToBase64String(propertyValueBytes, 0, propertyValueBytes.Length); - } - writer.WriteAttributeString(ATTR_VALUE, valueStr); - - writer.WriteEndElement(); - } - writer.WriteEndElement(); - } - - string exceptionStr = loggingEvent.GetExceptionString(); - if (exceptionStr != null && exceptionStr.Length > 0) - { - // Append the stack trace line - writer.WriteStartElement(m_elmException); - Transform.WriteEscapedXmlString(writer, exceptionStr,this.InvalidCharReplacement); - writer.WriteEndElement(); - } - - if (LocationInfo) - { - LocationInfo locationInfo = loggingEvent.LocationInformation; - - writer.WriteStartElement(m_elmLocation); - writer.WriteAttributeString(ATTR_CLASS, locationInfo.ClassName); - writer.WriteAttributeString(ATTR_METHOD, locationInfo.MethodName); - writer.WriteAttributeString(ATTR_FILE, locationInfo.FileName); - writer.WriteAttributeString(ATTR_LINE, locationInfo.LineNumber); - writer.WriteEndElement(); - } - - writer.WriteEndElement(); - } - - #endregion Override implementation of XMLLayoutBase - - #region Private Instance Fields - - /// - /// The prefix to use for all generated element names - /// - private string m_prefix = PREFIX; - - private string m_elmEvent = ELM_EVENT; - private string m_elmMessage = ELM_MESSAGE; - private string m_elmData = ELM_DATA; - private string m_elmProperties = ELM_PROPERTIES; - private string m_elmException = ELM_EXCEPTION; - private string m_elmLocation = ELM_LOCATION; - - private bool m_base64Message=false; - private bool m_base64Properties=false; - - #endregion Private Instance Fields - - #region Private Static Fields - - private const string PREFIX = "log4net"; - - private const string ELM_EVENT = "event"; - private const string ELM_MESSAGE = "message"; - private const string ELM_PROPERTIES = "properties"; - private const string ELM_GLOBAL_PROPERTIES = "global-properties"; - private const string ELM_DATA = "data"; - private const string ELM_EXCEPTION = "exception"; - private const string ELM_LOCATION = "locationInfo"; - - private const string ATTR_LOGGER = "logger"; - private const string ATTR_TIMESTAMP = "timestamp"; - private const string ATTR_LEVEL = "level"; - private const string ATTR_THREAD = "thread"; - private const string ATTR_DOMAIN = "domain"; - private const string ATTR_IDENTITY = "identity"; - private const string ATTR_USERNAME = "username"; - private const string ATTR_CLASS = "class"; - private const string ATTR_METHOD = "method"; - private const string ATTR_FILE = "file"; - private const string ATTR_LINE = "line"; - private const string ATTR_NAME = "name"; - private const string ATTR_VALUE = "value"; - - - #endregion Private Static Fields - } -} - diff --git a/src/log4net/Layout/XmlLayoutBase.cs b/src/log4net/Layout/XmlLayoutBase.cs deleted file mode 100644 index 2ec0e8c9..00000000 --- a/src/log4net/Layout/XmlLayoutBase.cs +++ /dev/null @@ -1,248 +0,0 @@ -#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 System.IO; -using System.Text; -using System.Xml; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Layout -{ - /// - /// Layout that formats the log events as XML elements. - /// - /// - /// - /// This is an abstract class that must be subclassed by an implementation - /// to conform to a specific schema. - /// - /// - /// Deriving classes must implement the method. - /// - /// - /// Nicko Cadell - /// Gert Driesen - abstract public class XmlLayoutBase : LayoutSkeleton - { - #region Protected Instance Constructors - - /// - /// Protected constructor to support subclasses - /// - /// - /// - /// Initializes a new instance of the class - /// with no location info. - /// - /// - protected XmlLayoutBase() : this(false) - { - IgnoresException = false; - } - - /// - /// Protected constructor to support subclasses - /// - /// - /// - /// The parameter determines whether - /// location information will be output by the layout. If - /// is set to true, then the - /// file name and line number of the statement at the origin of the log - /// statement will be output. - /// - /// - /// If you are embedding this layout within an SMTPAppender - /// then make sure to set the LocationInfo option of that - /// appender as well. - /// - /// - protected XmlLayoutBase(bool locationInfo) - { - IgnoresException = false; - m_locationInfo = locationInfo; - } - - #endregion Protected Instance Constructors - - #region Public Instance Properties - - /// - /// Gets a value indicating whether to include location information in - /// the XML events. - /// - /// - /// true if location information should be included in the XML - /// events; otherwise, false. - /// - /// - /// - /// If is set to true, then the file - /// name and line number of the statement at the origin of the log - /// statement will be output. - /// - /// - /// If you are embedding this layout within an SMTPAppender - /// then make sure to set the LocationInfo option of that - /// appender as well. - /// - /// - public bool LocationInfo - { - get { return m_locationInfo; } - set { m_locationInfo = value; } - } - /// - /// The string to replace characters that can not be expressed in XML with. - /// - /// - /// Not all characters may be expressed in XML. This property contains the - /// string to replace those that can not with. This defaults to a ?. Set it - /// to the empty string to simply remove offending characters. For more - /// details on the allowed character ranges see http://www.w3.org/TR/REC-xml/#charsets - /// Character replacement will occur in the log message, the property names - /// and the property values. - /// - /// - /// - public string InvalidCharReplacement - { - get {return m_invalidCharReplacement;} - set {m_invalidCharReplacement=value;} - } - #endregion - - #region Implementation of IOptionHandler - - /// - /// Initialize layout options - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - override public void ActivateOptions() - { - // nothing to do - } - - #endregion Implementation of IOptionHandler - - #region Override implementation of LayoutSkeleton - - /// - /// Gets the content type output by this layout. - /// - /// - /// As this is the XML layout, the value is always "text/xml". - /// - /// - /// - /// As this is the XML layout, the value is always "text/xml". - /// - /// - override public string ContentType - { - get { return "text/xml"; } - } - - /// - /// Produces a formatted string. - /// - /// The event being logged. - /// The TextWriter to write the formatted event to - /// - /// - /// Format the and write it to the . - /// - /// - /// This method creates an that writes to the - /// . The is passed - /// to the method. Subclasses should override the - /// method rather than this method. - /// - /// - override public void Format(TextWriter writer, LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - XmlTextWriter xmlWriter = new XmlTextWriter(new ProtectCloseTextWriter(writer)); - xmlWriter.Formatting = Formatting.None; - xmlWriter.Namespaces = false; - - // Write the event to the writer - FormatXml(xmlWriter, loggingEvent); - - xmlWriter.WriteWhitespace(SystemInfo.NewLine); - - // Close on xmlWriter will ensure xml is flushed - // the protected writer will ignore the actual close - xmlWriter.Close(); - } - - #endregion Override implementation of LayoutSkeleton - - #region Protected Instance Methods - - /// - /// Does the actual writing of the XML. - /// - /// The writer to use to output the event to. - /// The event to write. - /// - /// - /// Subclasses should override this method to format - /// the as XML. - /// - /// - abstract protected void FormatXml(XmlWriter writer, LoggingEvent loggingEvent); - - #endregion Protected Instance Methods - - #region Private Instance Fields - - /// - /// Flag to indicate if location information should be included in - /// the XML events. - /// - private bool m_locationInfo = false; - - /// - /// The string to replace invalid chars with - /// - private string m_invalidCharReplacement="?"; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Layout/XmlLayoutSchemaLog4j.cs b/src/log4net/Layout/XmlLayoutSchemaLog4j.cs deleted file mode 100644 index a6598367..00000000 --- a/src/log4net/Layout/XmlLayoutSchemaLog4j.cs +++ /dev/null @@ -1,252 +0,0 @@ -#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 System.Text; -using System.Xml; -using System.IO; - -using log4net.Core; -using log4net.Util; - -namespace log4net.Layout -{ - /// - /// Layout that formats the log events as XML elements compatible with the log4j schema - /// - /// - /// - /// Formats the log events according to the http://logging.apache.org/log4j schema. - /// - /// - /// Nicko Cadell - public class XmlLayoutSchemaLog4j : XmlLayoutBase - { - #region Static Members - - /// - /// The 1st of January 1970 in UTC - /// - private static readonly DateTime s_date1970 = new DateTime(1970, 1, 1); - - #endregion - - #region Constructors - - /// - /// Constructs an XMLLayoutSchemaLog4j - /// - public XmlLayoutSchemaLog4j() : base() - { - } - - /// - /// Constructs an XMLLayoutSchemaLog4j. - /// - /// - /// - /// The LocationInfo option takes a boolean value. By - /// default, it is set to false which means there will be no location - /// information output by this layout. If the the option is set to - /// true, then the file name and line number of the statement - /// at the origin of the log statement will be output. - /// - /// - /// If you are embedding this layout within an SMTPAppender - /// then make sure to set the LocationInfo option of that - /// appender as well. - /// - /// - public XmlLayoutSchemaLog4j(bool locationInfo) : base(locationInfo) - { - } - - #endregion - - #region Public Properties - - /// - /// The version of the log4j schema to use. - /// - /// - /// - /// Only version 1.2 of the log4j schema is supported. - /// - /// - public string Version - { - get { return "1.2"; } - set - { - if (value != "1.2") - { - throw new ArgumentException("Only version 1.2 of the log4j schema is currently supported"); - } - } - } - - #endregion - - /* Example log4j schema event - - - - - - - - - - - - - - - - */ - - /* Since log4j 1.3 the log4j:MDC has been combined into the log4j:properties element */ - - /// - /// Actually do the writing of the xml - /// - /// the writer to use - /// the event to write - /// - /// - /// Generate XML that is compatible with the log4j schema. - /// - /// - override protected void FormatXml(XmlWriter writer, LoggingEvent loggingEvent) - { - // Translate logging events for log4j - - // Translate hostname property - if (loggingEvent.LookupProperty(LoggingEvent.HostNameProperty) != null && - loggingEvent.LookupProperty("log4jmachinename") == null) - { - loggingEvent.GetProperties()["log4jmachinename"] = loggingEvent.LookupProperty(LoggingEvent.HostNameProperty); - } - - // translate appdomain name - if (loggingEvent.LookupProperty("log4japp") == null && - loggingEvent.Domain != null && - loggingEvent.Domain.Length > 0) - { - loggingEvent.GetProperties()["log4japp"] = loggingEvent.Domain; - } - - // translate identity name - if (loggingEvent.Identity != null && - loggingEvent.Identity.Length > 0 && - loggingEvent.LookupProperty(LoggingEvent.IdentityProperty) == null) - { - loggingEvent.GetProperties()[LoggingEvent.IdentityProperty] = loggingEvent.Identity; - } - - // translate user name - if (loggingEvent.UserName != null && - loggingEvent.UserName.Length > 0 && - loggingEvent.LookupProperty(LoggingEvent.UserNameProperty) == null) - { - loggingEvent.GetProperties()[LoggingEvent.UserNameProperty] = loggingEvent.UserName; - } - - // Write the start element - writer.WriteStartElement("log4j:event"); - writer.WriteAttributeString("logger", loggingEvent.LoggerName); - - // Calculate the timestamp as the number of milliseconds since january 1970 - // - // We must convert the TimeStamp to UTC before performing any mathematical - // operations. This allows use to take into account discontinuities - // caused by daylight savings time transitions. - TimeSpan timeSince1970 = loggingEvent.TimeStamp.ToUniversalTime() - s_date1970; - - writer.WriteAttributeString("timestamp", XmlConvert.ToString((long)timeSince1970.TotalMilliseconds)); - writer.WriteAttributeString("level", loggingEvent.Level.DisplayName); - writer.WriteAttributeString("thread", loggingEvent.ThreadName); - - // Append the message text - writer.WriteStartElement("log4j:message"); - Transform.WriteEscapedXmlString(writer, loggingEvent.RenderedMessage,this.InvalidCharReplacement); - writer.WriteEndElement(); - - object ndcObj = loggingEvent.LookupProperty("NDC"); - if (ndcObj != null) - { - string valueStr = loggingEvent.Repository.RendererMap.FindAndRender(ndcObj); - - if (valueStr != null && valueStr.Length > 0) - { - // Append the NDC text - writer.WriteStartElement("log4j:NDC"); - Transform.WriteEscapedXmlString(writer, valueStr,this.InvalidCharReplacement); - writer.WriteEndElement(); - } - } - - // Append the properties text - PropertiesDictionary properties = loggingEvent.GetProperties(); - if (properties.Count > 0) - { - writer.WriteStartElement("log4j:properties"); - foreach(System.Collections.DictionaryEntry entry in properties) - { - writer.WriteStartElement("log4j:data"); - writer.WriteAttributeString("name", (string)entry.Key); - - // Use an ObjectRenderer to convert the object to a string - string valueStr = loggingEvent.Repository.RendererMap.FindAndRender(entry.Value); - writer.WriteAttributeString("value", valueStr); - - writer.WriteEndElement(); - } - writer.WriteEndElement(); - } - - string exceptionStr = loggingEvent.GetExceptionString(); - if (exceptionStr != null && exceptionStr.Length > 0) - { - // Append the stack trace line - writer.WriteStartElement("log4j:throwable"); - Transform.WriteEscapedXmlString(writer, exceptionStr,this.InvalidCharReplacement); - writer.WriteEndElement(); - } - - if (LocationInfo) - { - LocationInfo locationInfo = loggingEvent.LocationInformation; - - writer.WriteStartElement("log4j:locationInfo"); - writer.WriteAttributeString("class", locationInfo.ClassName); - writer.WriteAttributeString("method", locationInfo.MethodName); - writer.WriteAttributeString("file", locationInfo.FileName); - writer.WriteAttributeString("line", locationInfo.LineNumber); - writer.WriteEndElement(); - } - - writer.WriteEndElement(); - } - } -} - diff --git a/src/log4net/Log4netAssemblyInfo.cs b/src/log4net/Log4netAssemblyInfo.cs deleted file mode 100644 index 14bc1115..00000000 --- a/src/log4net/Log4netAssemblyInfo.cs +++ /dev/null @@ -1,80 +0,0 @@ -#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 - -namespace log4net { - - /// - /// Provides information about the environment the assembly has - /// been built for. - /// - public sealed class AssemblyInfo { - /// Version of the assembly - public const string Version = "1.3.0"; - - /// Version of the framework targeted -#if FRAMEWORK_4_5_OR_ABOVE - public const decimal TargetFrameworkVersion = 4.5M; -#elif FRAMEWORK_4_0_OR_ABOVE - public const decimal TargetFrameworkVersion = 4.0M; -#elif FRAMEWORK_3_5_OR_ABOVE - public const decimal TargetFrameworkVersion = 3.5M; -#else - public const decimal TargetFrameworkVersion = 2.0M; -#endif - - /// Type of framework targeted -#if DOTNET - public const string TargetFramework = ".NET Framework"; -#elif NETCF - public const string TargetFramework = ".NET Compact Framework"; -#elif MONO - public const string TargetFramework = "Mono"; -#else - public const string TargetFramework = "Unknown"; -#endif - - /// Does it target a client profile? -#if !CLIENT_PROFILE - public const bool ClientProfile = false; -#else - public const bool ClientProfile = true; -#endif - - /// - /// Identifies the version and target for this assembly. - /// - public static string Info { - get { - return string.Format("Apache log4net version {0} compiled for {1}{2} {3}", - Version, TargetFramework, - /* Can't use - ClientProfile && true ? " Client Profile" : - or the compiler whines about unreachable expressions - */ -#if !CLIENT_PROFILE - string.Empty, -#else - " Client Profile", -#endif - TargetFrameworkVersion); - } - } - } - -} diff --git a/src/log4net/LogManager.cs b/src/log4net/LogManager.cs deleted file mode 100644 index a1979f41..00000000 --- a/src/log4net/LogManager.cs +++ /dev/null @@ -1,641 +0,0 @@ -#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 System.Reflection; - -using log4net.Core; -using log4net.Repository; - -namespace log4net -{ - /// - /// This class is used by client applications to request logger instances. - /// - /// - /// - /// This class has static methods that are used by a client to request - /// a logger instance. The method is - /// used to retrieve a logger. - /// - /// - /// See the interface for more details. - /// - /// - /// Simple example of logging messages - /// - /// ILog log = LogManager.GetLogger("application-log"); - /// - /// log.Info("Application Start"); - /// log.Debug("This is a debug message"); - /// - /// if (log.IsDebugEnabled) - /// { - /// log.Debug("This is another debug message"); - /// } - /// - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class LogManager - { - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// Uses a private access modifier to prevent instantiation of this class. - /// - private LogManager() - { - } - - #endregion Private Instance Constructors - - #region Type Specific Manager Methods - - /// Returns the named logger if it exists. - /// - /// Returns the named logger if it exists. - /// - /// - /// - /// If the named logger exists (in the default repository) then it - /// returns a reference to the logger, otherwise it returns null. - /// - /// - /// The fully qualified logger name to look for. - /// The logger found, or null if no logger could be found. - public static ILog Exists(string name) - { - return Exists(Assembly.GetCallingAssembly(), name); - } - - /// - /// Returns the named logger if it exists. - /// - /// - /// - /// If the named logger exists (in the specified repository) then it - /// returns a reference to the logger, otherwise it returns - /// null. - /// - /// - /// The repository to lookup in. - /// The fully qualified logger name to look for. - /// - /// The logger found, or null if the logger doesn't exist in the specified - /// repository. - /// - public static ILog Exists(string repository, string name) - { - return WrapLogger(LoggerManager.Exists(repository, name)); - } - - /// - /// Returns the named logger if it exists. - /// - /// - /// - /// If the named logger exists (in the repository for the specified assembly) then it - /// returns a reference to the logger, otherwise it returns - /// null. - /// - /// - /// The assembly to use to lookup the repository. - /// The fully qualified logger name to look for. - /// - /// The logger, or null if the logger doesn't exist in the specified - /// assembly's repository. - /// - public static ILog Exists(Assembly repositoryAssembly, string name) - { - return WrapLogger(LoggerManager.Exists(repositoryAssembly, name)); - } - - /// Get the currently defined loggers. - /// - /// Returns all the currently defined loggers in the default repository. - /// - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers. - public static ILog[] GetCurrentLoggers() - { - return GetCurrentLoggers(Assembly.GetCallingAssembly()); - } - - /// - /// Returns all the currently defined loggers in the specified repository. - /// - /// The repository to lookup in. - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers. - public static ILog[] GetCurrentLoggers(string repository) - { - return WrapLoggers(LoggerManager.GetCurrentLoggers(repository)); - } - - /// - /// Returns all the currently defined loggers in the specified assembly's repository. - /// - /// The assembly to use to lookup the repository. - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers. - public static ILog[] GetCurrentLoggers(Assembly repositoryAssembly) - { - return WrapLoggers(LoggerManager.GetCurrentLoggers(repositoryAssembly)); - } - - /// Get or create a logger. - /// - /// Retrieves or creates a named logger. - /// - /// - /// - /// Retrieves a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// - /// The name of the logger to retrieve. - /// The logger with the name specified. - public static ILog GetLogger(string name) - { - return GetLogger(Assembly.GetCallingAssembly(), name); - } - - /// - /// Retrieves or creates a named logger. - /// - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// - /// The repository to lookup in. - /// The name of the logger to retrieve. - /// The logger with the name specified. - public static ILog GetLogger(string repository, string name) - { - return WrapLogger(LoggerManager.GetLogger(repository, name)); - } - - /// - /// Retrieves or creates a named logger. - /// - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// - /// The assembly to use to lookup the repository. - /// The name of the logger to retrieve. - /// The logger with the name specified. - public static ILog GetLogger(Assembly repositoryAssembly, string name) - { - return WrapLogger(LoggerManager.GetLogger(repositoryAssembly, name)); - } - - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// The full name of will be used as the name of the logger to retrieve. - /// The logger with the name specified. - public static ILog GetLogger(Type type) - { - return GetLogger(Assembly.GetCallingAssembly(), type.FullName); - } - - /// - /// Shorthand for . - /// - /// - /// Gets the logger for the fully qualified name of the type specified. - /// - /// The repository to lookup in. - /// The full name of will be used as the name of the logger to retrieve. - /// The logger with the name specified. - public static ILog GetLogger(string repository, Type type) - { - return WrapLogger(LoggerManager.GetLogger(repository, type)); - } - - /// - /// Shorthand for . - /// - /// - /// Gets the logger for the fully qualified name of the type specified. - /// - /// The assembly to use to lookup the repository. - /// The full name of will be used as the name of the logger to retrieve. - /// The logger with the name specified. - public static ILog GetLogger(Assembly repositoryAssembly, Type type) - { - return WrapLogger(LoggerManager.GetLogger(repositoryAssembly, type)); - } - - #endregion Type Specific Manager Methods - - #region Domain & Repository Manager Methods - - /// - /// Shuts down the log4net system. - /// - /// - /// - /// Calling this method will safely close and remove all - /// appenders in all the loggers including root contained in all the - /// default repositories. - /// - /// - /// Some appenders need to be closed before the application exists. - /// Otherwise, pending logging events might be lost. - /// - /// The shutdown method is careful to close nested - /// appenders before closing regular appenders. This is allows - /// configurations where a regular appender is attached to a logger - /// and again to a nested appender. - /// - /// - public static void Shutdown() - { - LoggerManager.Shutdown(); - } - - /// Shutdown a logger repository. - /// - /// Shuts down the default repository. - /// - /// - /// - /// Calling this method will safely close and remove all - /// appenders in all the loggers including root contained in the - /// default repository. - /// - /// Some appenders need to be closed before the application exists. - /// Otherwise, pending logging events might be lost. - /// - /// The shutdown method is careful to close nested - /// appenders before closing regular appenders. This is allows - /// configurations where a regular appender is attached to a logger - /// and again to a nested appender. - /// - /// - public static void ShutdownRepository() - { - ShutdownRepository(Assembly.GetCallingAssembly()); - } - - /// - /// Shuts down the repository for the repository specified. - /// - /// - /// - /// Calling this method will safely close and remove all - /// appenders in all the loggers including root contained in the - /// specified. - /// - /// - /// Some appenders need to be closed before the application exists. - /// Otherwise, pending logging events might be lost. - /// - /// The shutdown method is careful to close nested - /// appenders before closing regular appenders. This is allows - /// configurations where a regular appender is attached to a logger - /// and again to a nested appender. - /// - /// - /// The repository to shutdown. - public static void ShutdownRepository(string repository) - { - LoggerManager.ShutdownRepository(repository); - } - - /// - /// Shuts down the repository specified. - /// - /// - /// - /// Calling this method will safely close and remove all - /// appenders in all the loggers including root contained in the - /// repository. The repository is looked up using - /// the specified. - /// - /// - /// Some appenders need to be closed before the application exists. - /// Otherwise, pending logging events might be lost. - /// - /// - /// The shutdown method is careful to close nested - /// appenders before closing regular appenders. This is allows - /// configurations where a regular appender is attached to a logger - /// and again to a nested appender. - /// - /// - /// The assembly to use to lookup the repository. - public static void ShutdownRepository(Assembly repositoryAssembly) - { - LoggerManager.ShutdownRepository(repositoryAssembly); - } - - /// Reset the configuration of a repository - /// - /// Resets all values contained in this repository instance to their defaults. - /// - /// - /// - /// Resets all values contained in the repository instance to their - /// defaults. This removes all appenders from all loggers, sets - /// the level of all non-root loggers to null, - /// sets their additivity flag to true and sets the level - /// of the root logger to . Moreover, - /// message disabling is set to its default "off" value. - /// - /// - public static void ResetConfiguration() - { - ResetConfiguration(Assembly.GetCallingAssembly()); - } - - /// - /// Resets all values contained in this repository instance to their defaults. - /// - /// - /// - /// Reset all values contained in the repository instance to their - /// defaults. This removes all appenders from all loggers, sets - /// the level of all non-root loggers to null, - /// sets their additivity flag to true and sets the level - /// of the root logger to . Moreover, - /// message disabling is set to its default "off" value. - /// - /// - /// The repository to reset. - public static void ResetConfiguration(string repository) - { - LoggerManager.ResetConfiguration(repository); - } - - /// - /// Resets all values contained in this repository instance to their defaults. - /// - /// - /// - /// Reset all values contained in the repository instance to their - /// defaults. This removes all appenders from all loggers, sets - /// the level of all non-root loggers to null, - /// sets their additivity flag to true and sets the level - /// of the root logger to . Moreover, - /// message disabling is set to its default "off" value. - /// - /// - /// The assembly to use to lookup the repository to reset. - public static void ResetConfiguration(Assembly repositoryAssembly) - { - LoggerManager.ResetConfiguration(repositoryAssembly); - } - - /// Get a logger repository. - /// - /// Returns the default instance. - /// - /// - /// - /// Gets the for the repository specified - /// by the callers assembly (). - /// - /// - /// The instance for the default repository. - public static ILoggerRepository GetRepository() - { - return GetRepository(Assembly.GetCallingAssembly()); - } - - /// - /// Returns the default instance. - /// - /// The default instance. - /// - /// - /// Gets the for the repository specified - /// by the argument. - /// - /// - /// The repository to lookup in. - public static ILoggerRepository GetRepository(string repository) - { - return LoggerManager.GetRepository(repository); - } - - /// - /// Returns the default instance. - /// - /// The default instance. - /// - /// - /// Gets the for the repository specified - /// by the argument. - /// - /// - /// The assembly to use to lookup the repository. - public static ILoggerRepository GetRepository(Assembly repositoryAssembly) - { - return LoggerManager.GetRepository(repositoryAssembly); - } - - /// Create a logger repository. - /// - /// Creates a repository with the specified repository type. - /// - /// A that implements - /// and has a no arg constructor. An instance of this type will be created to act - /// as the for the repository specified. - /// The created for the repository. - /// - /// - /// The created will be associated with the repository - /// specified such that a call to will return - /// the same repository instance. - /// - /// - public static ILoggerRepository CreateRepository(Type repositoryType) - { - return CreateRepository(Assembly.GetCallingAssembly(), repositoryType); - } - - /// - /// Creates a repository with the specified name. - /// - /// - /// - /// Creates the default type of which is a - /// object. - /// - /// - /// The name must be unique. Repositories cannot be redefined. - /// An will be thrown if the repository already exists. - /// - /// - /// The name of the repository, this must be unique amongst repositories. - /// The created for the repository. - /// The specified repository already exists. - public static ILoggerRepository CreateRepository(string repository) - { - return LoggerManager.CreateRepository(repository); - } - - /// - /// Creates a repository with the specified name and repository type. - /// - /// - /// - /// The name must be unique. Repositories cannot be redefined. - /// An will be thrown if the repository already exists. - /// - /// - /// The name of the repository, this must be unique to the repository. - /// A that implements - /// and has a no arg constructor. An instance of this type will be created to act - /// as the for the repository specified. - /// The created for the repository. - /// The specified repository already exists. - public static ILoggerRepository CreateRepository(string repository, Type repositoryType) - { - return LoggerManager.CreateRepository(repository, repositoryType); - } - - /// - /// Creates a repository for the specified assembly and repository type. - /// - /// - /// - /// The created will be associated with the repository - /// specified such that a call to with the - /// same assembly specified will return the same repository instance. - /// - /// - /// The assembly to use to get the name of the repository. - /// A that implements - /// and has a no arg constructor. An instance of this type will be created to act - /// as the for the repository specified. - /// The created for the repository. - public static ILoggerRepository CreateRepository(Assembly repositoryAssembly, Type repositoryType) - { - return LoggerManager.CreateRepository(repositoryAssembly, repositoryType); - } - - /// - /// Gets the list of currently defined repositories. - /// - /// - /// - /// Get an array of all the objects that have been created. - /// - /// - /// An array of all the known objects. - public static ILoggerRepository[] GetAllRepositories() - { - return LoggerManager.GetAllRepositories(); - } - - #endregion Domain & Repository Manager Methods - - #region Extension Handlers - - /// - /// Looks up the wrapper object for the logger specified. - /// - /// The logger to get the wrapper for. - /// The wrapper for the logger specified. - private static ILog WrapLogger(ILogger logger) - { - return (ILog)s_wrapperMap.GetWrapper(logger); - } - - /// - /// Looks up the wrapper objects for the loggers specified. - /// - /// The loggers to get the wrappers for. - /// The wrapper objects for the loggers specified. - private static ILog[] WrapLoggers(ILogger[] loggers) - { - ILog[] results = new ILog[loggers.Length]; - for(int i=0; i - /// Create the objects used by - /// this manager. - ///
    - /// The logger to wrap. - /// The wrapper for the logger specified. - private static ILoggerWrapper WrapperCreationHandler(ILogger logger) - { - return new LogImpl(logger); - } - - #endregion - - #region Private Static Fields - - /// - /// The wrapper map to use to hold the objects. - /// - private static readonly WrapperMap s_wrapperMap = new WrapperMap(new WrapperCreationHandler(WrapperCreationHandler)); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/LogicalThreadContext.cs b/src/log4net/LogicalThreadContext.cs deleted file mode 100644 index 40357c46..00000000 --- a/src/log4net/LogicalThreadContext.cs +++ /dev/null @@ -1,151 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for System.Runtime.Remoting.Messaging.CallContext -#if !NETCF - -using System; -using System.Collections; - -using log4net.Util; - -namespace log4net -{ - /// - /// The log4net Logical Thread Context. - /// - /// - /// - /// The LogicalThreadContext provides a location for specific debugging - /// information to be stored. - /// The LogicalThreadContext properties override any or - /// properties with the same name. - /// - /// - /// The Logical Thread Context has a properties map and a stack. - /// The properties and stack can - /// be included in the output of log messages. The - /// supports selecting and outputting these properties. - /// - /// - /// The Logical Thread Context provides a diagnostic context for the current call context. - /// This is an instrument for distinguishing interleaved log - /// output from different sources. Log output is typically interleaved - /// when a server handles multiple clients near-simultaneously. - /// - /// - /// The Logical Thread Context is managed on a per basis. - /// - /// - /// The requires a link time - /// for the - /// . - /// If the calling code does not have this permission then this context will be disabled. - /// It will not store any property values set on it. - /// - /// - /// Example of using the thread context properties to store a username. - /// - /// LogicalThreadContext.Properties["user"] = userName; - /// log.Info("This log message has a LogicalThreadContext Property called 'user'"); - /// - /// - /// Example of how to push a message into the context stack - /// - /// using(LogicalThreadContext.Stacks["LDC"].Push("my context message")) - /// { - /// log.Info("This log message has a LogicalThreadContext Stack message that includes 'my context message'"); - /// - /// } // at the end of the using block the message is automatically popped - /// - /// - /// - /// Nicko Cadell - public sealed class LogicalThreadContext - { - #region Private Instance Constructors - - /// - /// Private Constructor. - /// - /// - /// - /// Uses a private access modifier to prevent instantiation of this class. - /// - /// - private LogicalThreadContext() - { - } - - #endregion Private Instance Constructors - - #region Public Static Properties - - /// - /// The thread properties map - /// - /// - /// The thread properties map - /// - /// - /// - /// The LogicalThreadContext properties override any - /// or properties with the same name. - /// - /// - public static LogicalThreadContextProperties Properties - { - get { return s_properties; } - } - - /// - /// The thread stacks - /// - /// - /// stack map - /// - /// - /// - /// The logical thread stacks. - /// - /// - public static LogicalThreadContextStacks Stacks - { - get { return s_stacks; } - } - - #endregion Public Static Properties - - #region Private Static Fields - - /// - /// The thread context properties instance - /// - private readonly static LogicalThreadContextProperties s_properties = new LogicalThreadContextProperties(); - - /// - /// The thread context stacks instance - /// - private readonly static LogicalThreadContextStacks s_stacks = new LogicalThreadContextStacks(s_properties); - - #endregion Private Static Fields - } -} - -#endif \ No newline at end of file diff --git a/src/log4net/MDC.cs b/src/log4net/MDC.cs deleted file mode 100644 index dd1cbf0b..00000000 --- a/src/log4net/MDC.cs +++ /dev/null @@ -1,164 +0,0 @@ -#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 System.Collections; - -namespace log4net -{ - /// - /// Implementation of Mapped Diagnostic Contexts. - /// - /// - /// - /// - /// The MDC is deprecated and has been replaced by the . - /// The current MDC implementation forwards to the ThreadContext.Properties. - /// - /// - /// - /// The MDC class is similar to the class except that it is - /// based on a map instead of a stack. It provides mapped - /// diagnostic contexts. A Mapped Diagnostic Context, or - /// MDC in short, is an instrument for distinguishing interleaved log - /// output from different sources. Log output is typically interleaved - /// when a server handles multiple clients near-simultaneously. - /// - /// - /// The MDC is managed on a per thread basis. - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class MDC - { - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// Uses a private access modifier to prevent instantiation of this class. - /// - private MDC() - { - } - - #endregion Private Instance Constructors - - #region Public Static Methods - - /// - /// Gets the context value identified by the parameter. - /// - /// The key to lookup in the MDC. - /// The string value held for the key, or a null reference if no corresponding value is found. - /// - /// - /// - /// The MDC is deprecated and has been replaced by the . - /// The current MDC implementation forwards to the ThreadContext.Properties. - /// - /// - /// - /// If the parameter does not look up to a - /// previously defined context then null will be returned. - /// - /// - public static string Get(string key) - { - object obj = ThreadContext.Properties[key]; - if (obj == null) - { - return null; - } - return obj.ToString(); - } - - /// - /// Add an entry to the MDC - /// - /// The key to store the value under. - /// The value to store. - /// - /// - /// - /// The MDC is deprecated and has been replaced by the . - /// The current MDC implementation forwards to the ThreadContext.Properties. - /// - /// - /// - /// Puts a context value (the parameter) as identified - /// with the parameter into the current thread's - /// context map. - /// - /// - /// If a value is already defined for the - /// specified then the value will be replaced. If the - /// is specified as null then the key value mapping will be removed. - /// - /// - public static void Set(string key, string value) - { - ThreadContext.Properties[key] = value; - } - - /// - /// Removes the key value mapping for the key specified. - /// - /// The key to remove. - /// - /// - /// - /// The MDC is deprecated and has been replaced by the . - /// The current MDC implementation forwards to the ThreadContext.Properties. - /// - /// - /// - /// Remove the specified entry from this thread's MDC - /// - /// - public static void Remove(string key) - { - ThreadContext.Properties.Remove(key); - } - - /// - /// Clear all entries in the MDC - /// - /// - /// - /// - /// The MDC is deprecated and has been replaced by the . - /// The current MDC implementation forwards to the ThreadContext.Properties. - /// - /// - /// - /// Remove all the entries from this thread's MDC - /// - /// - public static void Clear() - { - ThreadContext.Properties.Clear(); - } - - #endregion Public Static Methods - } -} diff --git a/src/log4net/NDC.cs b/src/log4net/NDC.cs deleted file mode 100644 index 56cae131..00000000 --- a/src/log4net/NDC.cs +++ /dev/null @@ -1,298 +0,0 @@ -#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 System.Collections; - -namespace log4net -{ - /// - /// Implementation of Nested Diagnostic Contexts. - /// - /// - /// - /// - /// The NDC is deprecated and has been replaced by the . - /// The current NDC implementation forwards to the ThreadContext.Stacks["NDC"]. - /// - /// - /// - /// A Nested Diagnostic Context, or NDC in short, is an instrument - /// to distinguish interleaved log output from different sources. Log - /// output is typically interleaved when a server handles multiple - /// clients near-simultaneously. - /// - /// - /// Interleaved log output can still be meaningful if each log entry - /// from different contexts had a distinctive stamp. This is where NDCs - /// come into play. - /// - /// - /// Note that NDCs are managed on a per thread basis. The NDC class - /// is made up of static methods that operate on the context of the - /// calling thread. - /// - /// - /// How to push a message into the context - /// - /// using(NDC.Push("my context message")) - /// { - /// ... all log calls will have 'my context message' included ... - /// - /// } // at the end of the using block the message is automatically removed - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class NDC - { - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// Uses a private access modifier to prevent instantiation of this class. - /// - private NDC() - { - } - - #endregion Private Instance Constructors - - #region Public Static Properties - - /// - /// Gets the current context depth. - /// - /// The current context depth. - /// - /// - /// - /// The NDC is deprecated and has been replaced by the . - /// The current NDC implementation forwards to the ThreadContext.Stacks["NDC"]. - /// - /// - /// - /// The number of context values pushed onto the context stack. - /// - /// - /// Used to record the current depth of the context. This can then - /// be restored using the method. - /// - /// - /// - public static int Depth - { - get { return ThreadContext.Stacks["NDC"].Count; } - } - - #endregion Public Static Properties - - #region Public Static Methods - - /// - /// Clears all the contextual information held on the current thread. - /// - /// - /// - /// - /// The NDC is deprecated and has been replaced by the . - /// The current NDC implementation forwards to the ThreadContext.Stacks["NDC"]. - /// - /// - /// - /// Clears the stack of NDC data held on the current thread. - /// - /// - public static void Clear() - { - ThreadContext.Stacks["NDC"].Clear(); - } - - /// - /// Creates a clone of the stack of context information. - /// - /// A clone of the context info for this thread. - /// - /// - /// - /// The NDC is deprecated and has been replaced by the . - /// The current NDC implementation forwards to the ThreadContext.Stacks["NDC"]. - /// - /// - /// - /// The results of this method can be passed to the - /// method to allow child threads to inherit the context of their - /// parent thread. - /// - /// - public static Stack CloneStack() - { - return ThreadContext.Stacks["NDC"].InternalStack; - } - - /// - /// Inherits the contextual information from another thread. - /// - /// The context stack to inherit. - /// - /// - /// - /// The NDC is deprecated and has been replaced by the . - /// The current NDC implementation forwards to the ThreadContext.Stacks["NDC"]. - /// - /// - /// - /// This thread will use the context information from the stack - /// supplied. This can be used to initialize child threads with - /// the same contextual information as their parent threads. These - /// contexts will NOT be shared. Any further contexts that - /// are pushed onto the stack will not be visible to the other. - /// Call to obtain a stack to pass to - /// this method. - /// - /// - public static void Inherit(Stack stack) - { - ThreadContext.Stacks["NDC"].InternalStack = stack; - } - - /// - /// Removes the top context from the stack. - /// - /// - /// The message in the context that was removed from the top - /// of the stack. - /// - /// - /// - /// - /// The NDC is deprecated and has been replaced by the . - /// The current NDC implementation forwards to the ThreadContext.Stacks["NDC"]. - /// - /// - /// - /// Remove the top context from the stack, and return - /// it to the caller. If the stack is empty then an - /// empty string (not null) is returned. - /// - /// - public static string Pop() - { - return ThreadContext.Stacks["NDC"].Pop(); - } - - /// - /// Pushes a new context message. - /// - /// The new context message. - /// - /// An that can be used to clean up - /// the context stack. - /// - /// - /// - /// - /// The NDC is deprecated and has been replaced by the . - /// The current NDC implementation forwards to the ThreadContext.Stacks["NDC"]. - /// - /// - /// - /// Pushes a new context onto the context stack. An - /// is returned that can be used to clean up the context stack. This - /// can be easily combined with the using keyword to scope the - /// context. - /// - /// - /// Simple example of using the Push method with the using keyword. - /// - /// using(log4net.NDC.Push("NDC_Message")) - /// { - /// log.Warn("This should have an NDC message"); - /// } - /// - /// - public static IDisposable Push(string message) - { - return ThreadContext.Stacks["NDC"].Push(message); - } - - /// - /// Removes the context information for this thread. It is - /// not required to call this method. - /// - /// - /// - /// - /// The NDC is deprecated and has been replaced by the . - /// The current NDC implementation forwards to the ThreadContext.Stacks["NDC"]. - /// - /// - /// - /// This method is not implemented. - /// - /// - public static void Remove() - { - } - - /// - /// Forces the stack depth to be at most . - /// - /// The maximum depth of the stack - /// - /// - /// - /// The NDC is deprecated and has been replaced by the . - /// The current NDC implementation forwards to the ThreadContext.Stacks["NDC"]. - /// - /// - /// - /// Forces the stack depth to be at most . - /// This may truncate the head of the stack. This only affects the - /// stack in the current thread. Also it does not prevent it from - /// growing, it only sets the maximum depth at the time of the - /// call. This can be used to return to a known context depth. - /// - /// - public static void SetMaxDepth(int maxDepth) - { - if (maxDepth >= 0) - { - log4net.Util.ThreadContextStack stack = ThreadContext.Stacks["NDC"]; - - if (maxDepth == 0) - { - stack.Clear(); - } - else - { - while(stack.Count > maxDepth) - { - stack.Pop(); - } - } - } - } - - #endregion Public Static Methods - } -} diff --git a/src/log4net/ObjectRenderer/DefaultRenderer.cs b/src/log4net/ObjectRenderer/DefaultRenderer.cs deleted file mode 100644 index 8dc603df..00000000 --- a/src/log4net/ObjectRenderer/DefaultRenderer.cs +++ /dev/null @@ -1,310 +0,0 @@ -#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 System.Text; -using System.IO; -using System.Collections; - -using log4net.Util; - -namespace log4net.ObjectRenderer -{ - /// - /// The default object Renderer. - /// - /// - /// - /// The default renderer supports rendering objects and collections to strings. - /// - /// - /// See the method for details of the output. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class DefaultRenderer : IObjectRenderer - { - #region Constructors - - /// - /// Default constructor - /// - /// - /// - /// Default constructor - /// - /// - public DefaultRenderer() - { - } - - #endregion - - #region Implementation of IObjectRenderer - - /// - /// Render the object to a string - /// - /// The map used to lookup renderers - /// The object to render - /// The writer to render to - /// - /// - /// Render the object to a string. - /// - /// - /// The parameter is - /// provided to lookup and render other objects. This is - /// very useful where contains - /// nested objects of unknown type. The - /// method can be used to render these objects. - /// - /// - /// The default renderer supports rendering objects to strings as follows: - /// - /// - /// - /// Value - /// Rendered String - /// - /// - /// null - /// - /// "(null)" - /// - /// - /// - /// - /// - /// - /// For a one dimensional array this is the - /// array type name, an open brace, followed by a comma - /// separated list of the elements (using the appropriate - /// renderer), followed by a close brace. - /// - /// - /// For example: int[] {1, 2, 3}. - /// - /// - /// If the array is not one dimensional the - /// Array.ToString() is returned. - /// - /// - /// - /// - /// , & - /// - /// - /// Rendered as an open brace, followed by a comma - /// separated list of the elements (using the appropriate - /// renderer), followed by a close brace. - /// - /// - /// For example: {a, b, c}. - /// - /// - /// All collection classes that implement its subclasses, - /// or generic equivalents all implement the interface. - /// - /// - /// - /// - /// - /// - /// - /// Rendered as the key, an equals sign ('='), and the value (using the appropriate - /// renderer). - /// - /// - /// For example: key=value. - /// - /// - /// - /// - /// other - /// - /// Object.ToString() - /// - /// - /// - /// - public void RenderObject(RendererMap rendererMap, object obj, TextWriter writer) - { - if (rendererMap == null) - { - throw new ArgumentNullException("rendererMap"); - } - - if (obj == null) - { - writer.Write(SystemInfo.NullText); - return; - } - - Array objArray = obj as Array; - if (objArray != null) - { - RenderArray(rendererMap, objArray, writer); - return; - } - - // Test if we are dealing with some form of collection object - IEnumerable objEnumerable = obj as IEnumerable; - if (objEnumerable != null) - { - // Get a collection interface if we can as its .Count property may be more - // performant than getting the IEnumerator object and trying to advance it. - ICollection objCollection = obj as ICollection; - if (objCollection != null && objCollection.Count == 0) - { - writer.Write("{}"); - return; - } - - // This is a special check to allow us to get the enumerator from the IDictionary - // interface as this guarantees us DictionaryEntry objects. Note that in .NET 2.0 - // the generic IDictionary<> interface enumerates KeyValuePair objects rather than - // DictionaryEntry ones. However the implementation of the plain IDictionary - // interface on the generic Dictionary<> still returns DictionaryEntry objects. - IDictionary objDictionary = obj as IDictionary; - if (objDictionary != null) - { - RenderEnumerator(rendererMap, objDictionary.GetEnumerator(), writer); - return; - } - - RenderEnumerator(rendererMap, objEnumerable.GetEnumerator(), writer); - return; - } - - IEnumerator objEnumerator = obj as IEnumerator; - if (objEnumerator != null) - { - RenderEnumerator(rendererMap, objEnumerator, writer); - return; - } - - if (obj is DictionaryEntry) - { - RenderDictionaryEntry(rendererMap, (DictionaryEntry)obj, writer); - return; - } - - string str = obj.ToString(); - writer.Write( (str==null) ? SystemInfo.NullText : str ); - } - - #endregion - - /// - /// Render the array argument into a string - /// - /// The map used to lookup renderers - /// the array to render - /// The writer to render to - /// - /// - /// For a one dimensional array this is the - /// array type name, an open brace, followed by a comma - /// separated list of the elements (using the appropriate - /// renderer), followed by a close brace. For example: - /// int[] {1, 2, 3}. - /// - /// - /// If the array is not one dimensional the - /// Array.ToString() is returned. - /// - /// - private void RenderArray(RendererMap rendererMap, Array array, TextWriter writer) - { - if (array.Rank != 1) - { - writer.Write(array.ToString()); - } - else - { - writer.Write(array.GetType().Name + " {"); - int len = array.Length; - - if (len > 0) - { - rendererMap.FindAndRender(array.GetValue(0), writer); - for(int i=1; i - /// Render the enumerator argument into a string - ///
    - /// The map used to lookup renderers - /// the enumerator to render - /// The writer to render to - /// - /// - /// Rendered as an open brace, followed by a comma - /// separated list of the elements (using the appropriate - /// renderer), followed by a close brace. For example: - /// {a, b, c}. - /// - /// - private void RenderEnumerator(RendererMap rendererMap, IEnumerator enumerator, TextWriter writer) - { - writer.Write("{"); - - if (enumerator != null && enumerator.MoveNext()) - { - rendererMap.FindAndRender(enumerator.Current, writer); - - while (enumerator.MoveNext()) - { - writer.Write(", "); - rendererMap.FindAndRender(enumerator.Current, writer); - } - } - - writer.Write("}"); - } - - /// - /// Render the DictionaryEntry argument into a string - /// - /// The map used to lookup renderers - /// the DictionaryEntry to render - /// The writer to render to - /// - /// - /// Render the key, an equals sign ('='), and the value (using the appropriate - /// renderer). For example: key=value. - /// - /// - private void RenderDictionaryEntry(RendererMap rendererMap, DictionaryEntry entry, TextWriter writer) - { - rendererMap.FindAndRender(entry.Key, writer); - writer.Write("="); - rendererMap.FindAndRender(entry.Value, writer); - } - } -} diff --git a/src/log4net/ObjectRenderer/IObjectRenderer.cs b/src/log4net/ObjectRenderer/IObjectRenderer.cs deleted file mode 100644 index 3a79d1e1..00000000 --- a/src/log4net/ObjectRenderer/IObjectRenderer.cs +++ /dev/null @@ -1,61 +0,0 @@ -#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 System.IO; - -namespace log4net.ObjectRenderer -{ - /// - /// Implement this interface in order to render objects as strings - /// - /// - /// - /// Certain types require special case conversion to - /// string form. This conversion is done by an object renderer. - /// Object renderers implement the - /// interface. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IObjectRenderer - { - /// - /// Render the object to a string - /// - /// The map used to lookup renderers - /// The object to render - /// The writer to render to - /// - /// - /// Render the object to a - /// string. - /// - /// - /// The parameter is - /// provided to lookup and render other objects. This is - /// very useful where contains - /// nested objects of unknown type. The - /// method can be used to render these objects. - /// - /// - void RenderObject(RendererMap rendererMap, object obj, TextWriter writer); - } -} diff --git a/src/log4net/ObjectRenderer/RendererMap.cs b/src/log4net/ObjectRenderer/RendererMap.cs deleted file mode 100644 index 122a6c10..00000000 --- a/src/log4net/ObjectRenderer/RendererMap.cs +++ /dev/null @@ -1,326 +0,0 @@ -#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 System.IO; -using log4net.Util; - -namespace log4net.ObjectRenderer -{ - /// - /// Map class objects to an . - /// - /// - /// - /// Maintains a mapping between types that require special - /// rendering and the that - /// is used to render them. - /// - /// - /// The method is used to render an - /// object using the appropriate renderers defined in this map. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class RendererMap - { - private readonly static Type declaringType = typeof(RendererMap); - - #region Member Variables - - private System.Collections.Hashtable m_map; - private System.Collections.Hashtable m_cache = new System.Collections.Hashtable(); - - private static IObjectRenderer s_defaultRenderer = new DefaultRenderer(); - - #endregion - - #region Constructors - - /// - /// Default Constructor - /// - /// - /// - /// Default constructor. - /// - /// - public RendererMap() - { - m_map = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - } - - #endregion - - /// - /// Render using the appropriate renderer. - /// - /// the object to render to a string - /// the object rendered as a string - /// - /// - /// This is a convenience method used to render an object to a string. - /// The alternative method - /// should be used when streaming output to a . - /// - /// - public string FindAndRender(object obj) - { - // Optimisation for strings - string strData = obj as String; - if (strData != null) - { - return strData; - } - - StringWriter stringWriter = new StringWriter(System.Globalization.CultureInfo.InvariantCulture); - FindAndRender(obj, stringWriter); - return stringWriter.ToString(); - } - - /// - /// Render using the appropriate renderer. - /// - /// the object to render to a string - /// The writer to render to - /// - /// - /// Find the appropriate renderer for the type of the - /// parameter. This is accomplished by calling the - /// method. Once a renderer is found, it is - /// applied on the object and the result is returned - /// as a . - /// - /// - public void FindAndRender(object obj, TextWriter writer) - { - if (obj == null) - { - writer.Write(SystemInfo.NullText); - } - else - { - // Optimisation for strings - string str = obj as string; - if (str != null) - { - writer.Write(str); - } - else - { - // Lookup the renderer for the specific type - try - { - Get(obj.GetType()).RenderObject(this, obj, writer); - } - catch(Exception ex) - { - // Exception rendering the object - log4net.Util.LogLog.Error(declaringType, "Exception while rendering object of type ["+obj.GetType().FullName+"]", ex); - - // return default message - string objectTypeName = ""; - if (obj != null && obj.GetType() != null) - { - objectTypeName = obj.GetType().FullName; - } - - writer.Write("Exception rendering object type ["+objectTypeName+"]"); - if (ex != null) - { - string exceptionText = null; - - try - { - exceptionText = ex.ToString(); - } - catch - { - // Ignore exception - } - - writer.Write("" + exceptionText + ""); - } - writer.Write(""); - } - } - } - } - - /// - /// Gets the renderer for the specified object type - /// - /// the object to lookup the renderer for - /// the renderer for - /// - /// - /// Gets the renderer for the specified object type. - /// - /// - /// Syntactic sugar method that calls - /// with the type of the object parameter. - /// - /// - public IObjectRenderer Get(Object obj) - { - if (obj == null) - { - return null; - } - else - { - return Get(obj.GetType()); - } - } - - /// - /// Gets the renderer for the specified type - /// - /// the type to lookup the renderer for - /// the renderer for the specified type - /// - /// - /// Returns the renderer for the specified type. - /// If no specific renderer has been defined the - /// will be returned. - /// - /// - public IObjectRenderer Get(Type type) - { - if (type == null) - { - throw new ArgumentNullException("type"); - } - - IObjectRenderer result = null; - - // Check cache - result = (IObjectRenderer)m_cache[type]; - - if (result == null) - { - for(Type cur = type; cur != null; cur = cur.BaseType) - { - // Search the type's interfaces - result = SearchTypeAndInterfaces(cur); - if (result != null) - { - break; - } - } - - // if not set then use the default renderer - if (result == null) - { - result = s_defaultRenderer; - } - - // Add to cache - m_cache[type] = result; - } - - return result; - } - - /// - /// Internal function to recursively search interfaces - /// - /// the type to lookup the renderer for - /// the renderer for the specified type - private IObjectRenderer SearchTypeAndInterfaces(Type type) - { - IObjectRenderer r = (IObjectRenderer)m_map[type]; - if (r != null) - { - return r; - } - else - { - foreach(Type t in type.GetInterfaces()) - { - r = SearchTypeAndInterfaces(t); - if (r != null) - { - return r; - } - } - } - return null; - } - - /// - /// Get the default renderer instance - /// - /// the default renderer - /// - /// - /// Get the default renderer - /// - /// - public IObjectRenderer DefaultRenderer - { - get { return s_defaultRenderer; } - } - - /// - /// Clear the map of renderers - /// - /// - /// - /// Clear the custom renderers defined by using - /// . The - /// cannot be removed. - /// - /// - public void Clear() - { - m_map.Clear(); - m_cache.Clear(); - } - - /// - /// Register an for . - /// - /// the type that will be rendered by - /// the renderer for - /// - /// - /// Register an object renderer for a specific source type. - /// This renderer will be returned from a call to - /// specifying the same as an argument. - /// - /// - public void Put(Type typeToRender, IObjectRenderer renderer) - { - m_cache.Clear(); - - if (typeToRender == null) - { - throw new ArgumentNullException("typeToRender"); - } - if (renderer == null) - { - throw new ArgumentNullException("renderer"); - } - - m_map[typeToRender] = renderer; - } - } -} diff --git a/src/log4net/Plugin/IPlugin.cs b/src/log4net/Plugin/IPlugin.cs deleted file mode 100644 index 065898e8..00000000 --- a/src/log4net/Plugin/IPlugin.cs +++ /dev/null @@ -1,85 +0,0 @@ -#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 log4net.Repository; - -namespace log4net.Plugin -{ - /// - /// Interface implemented by logger repository plugins. - /// - /// - /// - /// Plugins define additional behavior that can be associated - /// with a . - /// The held by the - /// property is used to store the plugins for a repository. - /// - /// - /// The log4net.Config.PluginAttribute can be used to - /// attach plugins to repositories created using configuration - /// attributes. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IPlugin - { - /// - /// Gets the name of the plugin. - /// - /// - /// The name of the plugin. - /// - /// - /// - /// Plugins are stored in the - /// keyed by name. Each plugin instance attached to a - /// repository must be a unique name. - /// - /// - string Name { get; } - - /// - /// Attaches the plugin to the specified . - /// - /// The that this plugin should be attached to. - /// - /// - /// A plugin may only be attached to a single repository. - /// - /// - /// This method is called when the plugin is attached to the repository. - /// - /// - void Attach(ILoggerRepository repository); - - /// - /// Is called when the plugin is to shutdown. - /// - /// - /// - /// This method is called to notify the plugin that - /// it should stop operating and should detach from - /// the repository. - /// - /// - void Shutdown(); - } -} diff --git a/src/log4net/Plugin/IPluginFactory.cs b/src/log4net/Plugin/IPluginFactory.cs deleted file mode 100644 index 460a4d46..00000000 --- a/src/log4net/Plugin/IPluginFactory.cs +++ /dev/null @@ -1,45 +0,0 @@ -#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 - -namespace log4net.Plugin -{ - /// - /// Interface used to create plugins. - /// - /// - /// - /// Interface used to create a plugin. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IPluginFactory - { - /// - /// Creates the plugin object. - /// - /// the new plugin instance - /// - /// - /// Create and return a new plugin instance. - /// - /// - IPlugin CreatePlugin(); - } -} diff --git a/src/log4net/Plugin/PluginCollection.cs b/src/log4net/Plugin/PluginCollection.cs deleted file mode 100644 index d068f550..00000000 --- a/src/log4net/Plugin/PluginCollection.cs +++ /dev/null @@ -1,873 +0,0 @@ -#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 System.Collections; - -namespace log4net.Plugin -{ - /// - /// A strongly-typed collection of objects. - /// - /// Nicko Cadell - public class PluginCollection : ICollection, IList, IEnumerable, ICloneable - { - #region Interfaces - - /// - /// Supports type-safe iteration over a . - /// - /// - public interface IPluginCollectionEnumerator - { - /// - /// Gets the current element in the collection. - /// - IPlugin Current { get; } - - /// - /// Advances the enumerator to the next element in the collection. - /// - /// - /// true if the enumerator was successfully advanced to the next element; - /// false if the enumerator has passed the end of the collection. - /// - /// - /// The collection was modified after the enumerator was created. - /// - bool MoveNext(); - - /// - /// Sets the enumerator to its initial position, before the first element in the collection. - /// - void Reset(); - } - - #endregion Interfaces - - private const int DEFAULT_CAPACITY = 16; - - #region Implementation (data) - - private IPlugin[] m_array; - private int m_count = 0; - private int m_version = 0; - - #endregion Implementation (data) - - #region Static Wrappers - - /// - /// Creates a read-only wrapper for a PluginCollection instance. - /// - /// list to create a readonly wrapper arround - /// - /// A PluginCollection wrapper that is read-only. - /// - public static PluginCollection ReadOnly(PluginCollection list) - { - if(list == null) throw new ArgumentNullException("list"); - - return new ReadOnlyPluginCollection(list); - } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the PluginCollection class - /// that is empty and has the default initial capacity. - /// - public PluginCollection() - { - m_array = new IPlugin[DEFAULT_CAPACITY]; - } - - /// - /// Initializes a new instance of the PluginCollection class - /// that has the specified initial capacity. - /// - /// - /// The number of elements that the new PluginCollection is initially capable of storing. - /// - public PluginCollection(int capacity) - { - m_array = new IPlugin[capacity]; - } - - /// - /// Initializes a new instance of the PluginCollection class - /// that contains elements copied from the specified PluginCollection. - /// - /// The PluginCollection whose elements are copied to the new collection. - public PluginCollection(PluginCollection c) - { - m_array = new IPlugin[c.Count]; - AddRange(c); - } - - /// - /// Initializes a new instance of the PluginCollection class - /// that contains elements copied from the specified array. - /// - /// The array whose elements are copied to the new list. - public PluginCollection(IPlugin[] a) - { - m_array = new IPlugin[a.Length]; - AddRange(a); - } - - /// - /// Initializes a new instance of the PluginCollection class - /// that contains elements copied from the specified collection. - /// - /// The collection whose elements are copied to the new list. - public PluginCollection(ICollection col) - { - m_array = new IPlugin[col.Count]; - AddRange(col); - } - - /// - /// Type visible only to our subclasses - /// Used to access protected constructor - /// - /// - protected internal enum Tag - { - /// - /// A value - /// - Default - } - - /// - /// Allow subclasses to avoid our default constructors - /// - /// - /// - protected internal PluginCollection(Tag tag) - { - m_array = null; - } - - #endregion - - #region Operations (type-safe ICollection) - - /// - /// Gets the number of elements actually contained in the PluginCollection. - /// - public virtual int Count - { - get { return m_count; } - } - - /// - /// Copies the entire PluginCollection to a one-dimensional - /// array. - /// - /// The one-dimensional array to copy to. - public virtual void CopyTo(IPlugin[] array) - { - this.CopyTo(array, 0); - } - - /// - /// Copies the entire PluginCollection to a one-dimensional - /// array, starting at the specified index of the target array. - /// - /// The one-dimensional array to copy to. - /// The zero-based index in at which copying begins. - public virtual void CopyTo(IPlugin[] array, int start) - { - if (m_count > array.GetUpperBound(0) + 1 - start) - { - throw new System.ArgumentException("Destination array was not long enough."); - } - - Array.Copy(m_array, 0, array, start, m_count); - } - - /// - /// Gets a value indicating whether access to the collection is synchronized (thread-safe). - /// - /// true if access to the ICollection is synchronized (thread-safe); otherwise, false. - public virtual bool IsSynchronized - { - get { return m_array.IsSynchronized; } - } - - /// - /// Gets an object that can be used to synchronize access to the collection. - /// - /// - /// An object that can be used to synchronize access to the collection. - /// - public virtual object SyncRoot - { - get { return m_array.SyncRoot; } - } - - #endregion - - #region Operations (type-safe IList) - - /// - /// Gets or sets the at the specified index. - /// - /// - /// The at the specified index. - /// - /// The zero-based index of the element to get or set. - /// - /// is less than zero. - /// -or- - /// is equal to or greater than . - /// - public virtual IPlugin this[int index] - { - get - { - ValidateIndex(index); // throws - return m_array[index]; - } - set - { - ValidateIndex(index); // throws - ++m_version; - m_array[index] = value; - } - } - - /// - /// Adds a to the end of the PluginCollection. - /// - /// The to be added to the end of the PluginCollection. - /// The index at which the value has been added. - public virtual int Add(IPlugin item) - { - if (m_count == m_array.Length) - { - EnsureCapacity(m_count + 1); - } - - m_array[m_count] = item; - m_version++; - - return m_count++; - } - - /// - /// Removes all elements from the PluginCollection. - /// - public virtual void Clear() - { - ++m_version; - m_array = new IPlugin[DEFAULT_CAPACITY]; - m_count = 0; - } - - /// - /// Creates a shallow copy of the . - /// - /// A new with a shallow copy of the collection data. - public virtual object Clone() - { - PluginCollection newCol = new PluginCollection(m_count); - Array.Copy(m_array, 0, newCol.m_array, 0, m_count); - newCol.m_count = m_count; - newCol.m_version = m_version; - - return newCol; - } - - /// - /// Determines whether a given is in the PluginCollection. - /// - /// The to check for. - /// true if is found in the PluginCollection; otherwise, false. - public virtual bool Contains(IPlugin item) - { - for (int i=0; i != m_count; ++i) - { - if (m_array[i].Equals(item)) - { - return true; - } - } - return false; - } - - /// - /// Returns the zero-based index of the first occurrence of a - /// in the PluginCollection. - /// - /// The to locate in the PluginCollection. - /// - /// The zero-based index of the first occurrence of - /// in the entire PluginCollection, if found; otherwise, -1. - /// - public virtual int IndexOf(IPlugin item) - { - for (int i=0; i != m_count; ++i) - { - if (m_array[i].Equals(item)) - { - return i; - } - } - return -1; - } - - /// - /// Inserts an element into the PluginCollection at the specified index. - /// - /// The zero-based index at which should be inserted. - /// The to insert. - /// - /// is less than zero - /// -or- - /// is equal to or greater than . - /// - public virtual void Insert(int index, IPlugin item) - { - ValidateIndex(index, true); // throws - - if (m_count == m_array.Length) - { - EnsureCapacity(m_count + 1); - } - - if (index < m_count) - { - Array.Copy(m_array, index, m_array, index + 1, m_count - index); - } - - m_array[index] = item; - m_count++; - m_version++; - } - - /// - /// Removes the first occurrence of a specific from the PluginCollection. - /// - /// The to remove from the PluginCollection. - /// - /// The specified was not found in the PluginCollection. - /// - public virtual void Remove(IPlugin item) - { - int i = IndexOf(item); - if (i < 0) - { - throw new System.ArgumentException("Cannot remove the specified item because it was not found in the specified Collection."); - } - ++m_version; - RemoveAt(i); - } - - /// - /// Removes the element at the specified index of the PluginCollection. - /// - /// The zero-based index of the element to remove. - /// - /// is less than zero. - /// -or- - /// is equal to or greater than . - /// - public virtual void RemoveAt(int index) - { - ValidateIndex(index); // throws - - m_count--; - - if (index < m_count) - { - Array.Copy(m_array, index + 1, m_array, index, m_count - index); - } - - // We can't set the deleted entry equal to null, because it might be a value type. - // Instead, we'll create an empty single-element array of the right type and copy it - // over the entry we want to erase. - IPlugin[] temp = new IPlugin[1]; - Array.Copy(temp, 0, m_array, m_count, 1); - m_version++; - } - - /// - /// Gets a value indicating whether the collection has a fixed size. - /// - /// true if the collection has a fixed size; otherwise, false. The default is false. - public virtual bool IsFixedSize - { - get { return false; } - } - - /// - /// Gets a value indicating whether the IList is read-only. - /// - /// true if the collection is read-only; otherwise, false. The default is false. - public virtual bool IsReadOnly - { - get { return false; } - } - - #endregion - - #region Operations (type-safe IEnumerable) - - /// - /// Returns an enumerator that can iterate through the PluginCollection. - /// - /// An for the entire PluginCollection. - public virtual IPluginCollectionEnumerator GetEnumerator() - { - return new Enumerator(this); - } - - #endregion - - #region Public helpers (just to mimic some nice features of ArrayList) - - /// - /// Gets or sets the number of elements the PluginCollection can contain. - /// - /// - /// The number of elements the PluginCollection can contain. - /// - public virtual int Capacity - { - get - { - return m_array.Length; - } - set - { - if (value < m_count) - { - value = m_count; - } - - if (value != m_array.Length) - { - if (value > 0) - { - IPlugin[] temp = new IPlugin[value]; - Array.Copy(m_array, 0, temp, 0, m_count); - m_array = temp; - } - else - { - m_array = new IPlugin[DEFAULT_CAPACITY]; - } - } - } - } - - /// - /// Adds the elements of another PluginCollection to the current PluginCollection. - /// - /// The PluginCollection whose elements should be added to the end of the current PluginCollection. - /// The new of the PluginCollection. - public virtual int AddRange(PluginCollection x) - { - if (m_count + x.Count >= m_array.Length) - { - EnsureCapacity(m_count + x.Count); - } - - Array.Copy(x.m_array, 0, m_array, m_count, x.Count); - m_count += x.Count; - m_version++; - - return m_count; - } - - /// - /// Adds the elements of a array to the current PluginCollection. - /// - /// The array whose elements should be added to the end of the PluginCollection. - /// The new of the PluginCollection. - public virtual int AddRange(IPlugin[] x) - { - if (m_count + x.Length >= m_array.Length) - { - EnsureCapacity(m_count + x.Length); - } - - Array.Copy(x, 0, m_array, m_count, x.Length); - m_count += x.Length; - m_version++; - - return m_count; - } - - /// - /// Adds the elements of a collection to the current PluginCollection. - /// - /// The collection whose elements should be added to the end of the PluginCollection. - /// The new of the PluginCollection. - public virtual int AddRange(ICollection col) - { - if (m_count + col.Count >= m_array.Length) - { - EnsureCapacity(m_count + col.Count); - } - - foreach(object item in col) - { - Add((IPlugin)item); - } - - return m_count; - } - - /// - /// Sets the capacity to the actual number of elements. - /// - public virtual void TrimToSize() - { - this.Capacity = m_count; - } - - #endregion - - #region Implementation (helpers) - - /// - /// is less than zero. - /// -or- - /// is equal to or greater than . - /// - private void ValidateIndex(int i) - { - ValidateIndex(i, false); - } - - /// - /// is less than zero. - /// -or- - /// is equal to or greater than . - /// - private void ValidateIndex(int i, bool allowEqualEnd) - { - int max = (allowEqualEnd) ? (m_count) : (m_count-1); - if (i < 0 || i > max) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("i", (object)i, "Index was out of range. Must be non-negative and less than the size of the collection. [" + (object)i + "] Specified argument was out of the range of valid values."); - } - } - - private void EnsureCapacity(int min) - { - int newCapacity = ((m_array.Length == 0) ? DEFAULT_CAPACITY : m_array.Length * 2); - if (newCapacity < min) - { - newCapacity = min; - } - - this.Capacity = newCapacity; - } - - #endregion - - #region Implementation (ICollection) - - void ICollection.CopyTo(Array array, int start) - { - Array.Copy(m_array, 0, array, start, m_count); - } - - #endregion - - #region Implementation (IList) - - object IList.this[int i] - { - get { return (object)this[i]; } - set { this[i] = (IPlugin)value; } - } - - int IList.Add(object x) - { - return this.Add((IPlugin)x); - } - - bool IList.Contains(object x) - { - return this.Contains((IPlugin)x); - } - - int IList.IndexOf(object x) - { - return this.IndexOf((IPlugin)x); - } - - void IList.Insert(int pos, object x) - { - this.Insert(pos, (IPlugin)x); - } - - void IList.Remove(object x) - { - this.Remove((IPlugin)x); - } - - void IList.RemoveAt(int pos) - { - this.RemoveAt(pos); - } - - #endregion - - #region Implementation (IEnumerable) - - IEnumerator IEnumerable.GetEnumerator() - { - return (IEnumerator)(this.GetEnumerator()); - } - - #endregion Implementation (IEnumerable) - - #region Nested enumerator class - - /// - /// Supports simple iteration over a . - /// - /// - private sealed class Enumerator : IEnumerator, IPluginCollectionEnumerator - { - #region Implementation (data) - - private readonly PluginCollection m_collection; - private int m_index; - private int m_version; - - #endregion Implementation (data) - - #region Construction - - /// - /// Initializes a new instance of the Enumerator class. - /// - /// - internal Enumerator(PluginCollection tc) - { - m_collection = tc; - m_index = -1; - m_version = tc.m_version; - } - - #endregion - - #region Operations (type-safe IEnumerator) - - /// - /// Gets the current element in the collection. - /// - /// - /// The current element in the collection. - /// - public IPlugin Current - { - get { return m_collection[m_index]; } - } - - /// - /// Advances the enumerator to the next element in the collection. - /// - /// - /// true if the enumerator was successfully advanced to the next element; - /// false if the enumerator has passed the end of the collection. - /// - /// - /// The collection was modified after the enumerator was created. - /// - public bool MoveNext() - { - if (m_version != m_collection.m_version) - { - throw new System.InvalidOperationException("Collection was modified; enumeration operation may not execute."); - } - - ++m_index; - return (m_index < m_collection.Count); - } - - /// - /// Sets the enumerator to its initial position, before the first element in the collection. - /// - public void Reset() - { - m_index = -1; - } - - #endregion - - #region Implementation (IEnumerator) - - object IEnumerator.Current - { - get { return this.Current; } - } - - #endregion - } - - #endregion - - #region Nested Read Only Wrapper class - - /// - private sealed class ReadOnlyPluginCollection : PluginCollection - { - #region Implementation (data) - - private readonly PluginCollection m_collection; - - #endregion - - #region Construction - - internal ReadOnlyPluginCollection(PluginCollection list) : base(Tag.Default) - { - m_collection = list; - } - - #endregion - - #region Type-safe ICollection - - public override void CopyTo(IPlugin[] array) - { - m_collection.CopyTo(array); - } - - public override void CopyTo(IPlugin[] array, int start) - { - m_collection.CopyTo(array,start); - } - public override int Count - { - get { return m_collection.Count; } - } - - public override bool IsSynchronized - { - get { return m_collection.IsSynchronized; } - } - - public override object SyncRoot - { - get { return this.m_collection.SyncRoot; } - } - - #endregion - - #region Type-safe IList - - public override IPlugin this[int i] - { - get { return m_collection[i]; } - set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); } - } - - public override int Add(IPlugin x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override void Clear() - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override bool Contains(IPlugin x) - { - return m_collection.Contains(x); - } - - public override int IndexOf(IPlugin x) - { - return m_collection.IndexOf(x); - } - - public override void Insert(int pos, IPlugin x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override void Remove(IPlugin x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override void RemoveAt(int pos) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override bool IsFixedSize - { - get { return true; } - } - - public override bool IsReadOnly - { - get { return true; } - } - - #endregion - - #region Type-safe IEnumerable - - public override IPluginCollectionEnumerator GetEnumerator() - { - return m_collection.GetEnumerator(); - } - - #endregion - - #region Public Helpers - - // (just to mimic some nice features of ArrayList) - public override int Capacity - { - get { return m_collection.Capacity; } - set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); } - } - - public override int AddRange(PluginCollection x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - public override int AddRange(IPlugin[] x) - { - throw new NotSupportedException("This is a Read Only Collection and can not be modified"); - } - - #endregion - } - - #endregion - } -} diff --git a/src/log4net/Plugin/PluginMap.cs b/src/log4net/Plugin/PluginMap.cs deleted file mode 100644 index d05223f2..00000000 --- a/src/log4net/Plugin/PluginMap.cs +++ /dev/null @@ -1,189 +0,0 @@ -#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 System.Collections; - -using log4net.Util; -using log4net.Repository; - -namespace log4net.Plugin -{ - /// - /// Map of repository plugins. - /// - /// - /// - /// This class is a name keyed map of the plugins that are - /// attached to a repository. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class PluginMap - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// The repository that the plugins should be attached to. - /// - /// - /// Initialize a new instance of the class with a - /// repository that the plugins should be attached to. - /// - /// - public PluginMap(ILoggerRepository repository) - { - m_repository = repository; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets a by name. - /// - /// The name of the to lookup. - /// - /// The from the map with the name specified, or - /// null if no plugin is found. - /// - /// - /// - /// Lookup a plugin by name. If the plugin is not found null - /// will be returned. - /// - /// - public IPlugin this[string name] - { - get - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - lock(this) - { - return (IPlugin)m_mapName2Plugin[name]; - } - } - } - - /// - /// Gets all possible plugins as a list of objects. - /// - /// All possible plugins as a list of objects. - /// - /// - /// Get a collection of all the plugins defined in this map. - /// - /// - public PluginCollection AllPlugins - { - get - { - lock(this) - { - return new PluginCollection(m_mapName2Plugin.Values); - } - } - } - - #endregion Public Instance Properties - - #region Public Instance Methods - - /// - /// Adds a to the map. - /// - /// The to add to the map. - /// - /// - /// The will be attached to the repository when added. - /// - /// - /// If there already exists a plugin with the same name - /// attached to the repository then the old plugin will - /// be and replaced with - /// the new plugin. - /// - /// - public void Add(IPlugin plugin) - { - if (plugin == null) - { - throw new ArgumentNullException("plugin"); - } - - IPlugin curPlugin = null; - - lock(this) - { - // Get the current plugin if it exists - curPlugin = m_mapName2Plugin[plugin.Name] as IPlugin; - - // Store new plugin - m_mapName2Plugin[plugin.Name] = plugin; - } - - // Shutdown existing plugin with same name - if (curPlugin != null) - { - curPlugin.Shutdown(); - } - - // Attach new plugin to repository - plugin.Attach(m_repository); - } - - /// - /// Removes a from the map. - /// - /// The to remove from the map. - /// - /// - /// Remove a specific plugin from this map. - /// - /// - public void Remove(IPlugin plugin) - { - if (plugin == null) - { - throw new ArgumentNullException("plugin"); - } - lock(this) - { - m_mapName2Plugin.Remove(plugin.Name); - } - } - - #endregion Public Instance Methods - - #region Private Instance Fields - - private readonly Hashtable m_mapName2Plugin = new Hashtable(); - private readonly ILoggerRepository m_repository; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Plugin/PluginSkeleton.cs b/src/log4net/Plugin/PluginSkeleton.cs deleted file mode 100644 index 56ce5c3b..00000000 --- a/src/log4net/Plugin/PluginSkeleton.cs +++ /dev/null @@ -1,148 +0,0 @@ -#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 log4net.Repository; - -namespace log4net.Plugin -{ - /// - /// Base implementation of - /// - /// - /// - /// Default abstract implementation of the - /// interface. This base class can be used by implementors - /// of the interface. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public abstract class PluginSkeleton : IPlugin - { - #region Protected Instance Constructors - - /// - /// Constructor - /// - /// the name of the plugin - /// - /// Initializes a new Plugin with the specified name. - /// - protected PluginSkeleton(string name) - { - m_name = name; - } - - #endregion Protected Instance Constructors - - #region Implementation of IPlugin - - /// - /// Gets or sets the name of the plugin. - /// - /// - /// The name of the plugin. - /// - /// - /// - /// Plugins are stored in the - /// keyed by name. Each plugin instance attached to a - /// repository must be a unique name. - /// - /// - /// The name of the plugin must not change one the - /// plugin has been attached to a repository. - /// - /// - public virtual string Name - { - get { return m_name; } - set { m_name = value; } - } - - /// - /// Attaches this plugin to a . - /// - /// The that this plugin should be attached to. - /// - /// - /// A plugin may only be attached to a single repository. - /// - /// - /// This method is called when the plugin is attached to the repository. - /// - /// - public virtual void Attach(ILoggerRepository repository) - { - m_repository = repository; - } - - /// - /// Is called when the plugin is to shutdown. - /// - /// - /// - /// This method is called to notify the plugin that - /// it should stop operating and should detach from - /// the repository. - /// - /// - public virtual void Shutdown() - { - } - - #endregion Implementation of IPlugin - - #region Protected Instance Properties - - /// - /// The repository for this plugin - /// - /// - /// The that this plugin is attached to. - /// - /// - /// - /// Gets or sets the that this plugin is - /// attached to. - /// - /// - protected virtual ILoggerRepository LoggerRepository - { - get { return this.m_repository; } - set { this.m_repository = value; } - } - - #endregion Protected Instance Properties - - #region Private Instance Fields - - /// - /// The name of this plugin. - /// - private string m_name; - - /// - /// The repository this plugin is attached to. - /// - private ILoggerRepository m_repository; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Plugin/RemoteLoggingServerPlugin.cs b/src/log4net/Plugin/RemoteLoggingServerPlugin.cs deleted file mode 100644 index ce7cffeb..00000000 --- a/src/log4net/Plugin/RemoteLoggingServerPlugin.cs +++ /dev/null @@ -1,279 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for System.Runtime.Remoting -#if !NETCF - -using System; -using System.Runtime.Remoting; - -using log4net.Util; -using log4net.Repository; -using log4net.Core; -using IRemoteLoggingSink = log4net.Appender.RemotingAppender.IRemoteLoggingSink; - -namespace log4net.Plugin -{ - /// - /// Plugin that listens for events from the - /// - /// - /// - /// This plugin publishes an instance of - /// on a specified . This listens for logging events delivered from - /// a remote . - /// - /// - /// When an event is received it is relogged within the attached repository - /// as if it had been raised locally. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class RemoteLoggingServerPlugin : PluginSkeleton - { - #region Public Instance Constructors - - /// - /// Default constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - /// The property must be set. - /// - /// - public RemoteLoggingServerPlugin() : base("RemoteLoggingServerPlugin:Unset URI") - { - } - - /// - /// Construct with sink Uri. - /// - /// The name to publish the sink under in the remoting infrastructure. - /// See for more details. - /// - /// - /// Initializes a new instance of the class - /// with specified name. - /// - /// - public RemoteLoggingServerPlugin(string sinkUri) : base("RemoteLoggingServerPlugin:"+sinkUri) - { - m_sinkUri = sinkUri; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the URI of this sink. - /// - /// - /// The URI of this sink. - /// - /// - /// - /// This is the name under which the object is marshaled. - /// - /// - /// - public virtual string SinkUri - { - get { return m_sinkUri; } - set { m_sinkUri = value; } - } - - #endregion Public Instance Properties - - #region Override implementation of PluginSkeleton - - /// - /// Attaches this plugin to a . - /// - /// The that this plugin should be attached to. - /// - /// - /// A plugin may only be attached to a single repository. - /// - /// - /// This method is called when the plugin is attached to the repository. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - override public void Attach(ILoggerRepository repository) - { - base.Attach(repository); - - // Create the sink and marshal it - m_sink = new RemoteLoggingSinkImpl(repository); - - try - { - RemotingServices.Marshal(m_sink, m_sinkUri, typeof(IRemoteLoggingSink)); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Failed to Marshal remoting sink", ex); - } - } - - /// - /// Is called when the plugin is to shutdown. - /// - /// - /// - /// When the plugin is shutdown the remote logging - /// sink is disconnected. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - override public void Shutdown() - { - // Stops the sink from receiving messages - RemotingServices.Disconnect(m_sink); - m_sink = null; - - base.Shutdown(); - } - - #endregion Override implementation of PluginSkeleton - - #region Private Instance Fields - - private RemoteLoggingSinkImpl m_sink; - private string m_sinkUri; - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the RemoteLoggingServerPlugin class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(RemoteLoggingServerPlugin); - - #endregion Private Static Fields - - /// - /// Delivers objects to a remote sink. - /// - /// - /// - /// Internal class used to listen for logging events - /// and deliver them to the local repository. - /// - /// - private class RemoteLoggingSinkImpl : MarshalByRefObject, IRemoteLoggingSink - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// The repository to log to. - /// - /// - /// Initializes a new instance of the for the - /// specified . - /// - /// - public RemoteLoggingSinkImpl(ILoggerRepository repository) - { - m_repository = repository; - } - - #endregion Public Instance Constructors - - #region Implementation of IRemoteLoggingSink - - /// - /// Logs the events to the repository. - /// - /// The events to log. - /// - /// - /// The events passed are logged to the - /// - /// - public void LogEvents(LoggingEvent[] events) - { - if (events != null) - { - foreach(LoggingEvent logEvent in events) - { - if (logEvent != null) - { - m_repository.Log(logEvent); - } - } - } - } - - #endregion Implementation of IRemoteLoggingSink - - #region Override implementation of MarshalByRefObject - - /// - /// Obtains a lifetime service object to control the lifetime - /// policy for this instance. - /// - /// null to indicate that this instance should live forever. - /// - /// - /// Obtains a lifetime service object to control the lifetime - /// policy for this instance. This object should live forever - /// therefore this implementation returns null. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecurityCritical] -#endif - public override object InitializeLifetimeService() - { - return null; - } - - #endregion Override implementation of MarshalByRefObject - - #region Private Instance Fields - - /// - /// The underlying that events should - /// be logged to. - /// - private readonly ILoggerRepository m_repository; - - #endregion Private Instance Fields - } - } -} - -#endif // !NETCF \ No newline at end of file diff --git a/src/log4net/Repository/ConfigurationChangedEventArgs.cs b/src/log4net/Repository/ConfigurationChangedEventArgs.cs deleted file mode 100644 index 77df7d41..00000000 --- a/src/log4net/Repository/ConfigurationChangedEventArgs.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * 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.Collections; - -namespace log4net.Repository -{ - /// - /// - /// - public class ConfigurationChangedEventArgs : EventArgs - { - private readonly ICollection configurationMessages; - - /// - /// - /// - /// - public ConfigurationChangedEventArgs(ICollection configurationMessages) - { - this.configurationMessages = configurationMessages; - } - - /// - /// - /// - public ICollection ConfigurationMessages - { - get { return configurationMessages; } - } - } -} diff --git a/src/log4net/Repository/Hierarchy/DefaultLoggerFactory.cs b/src/log4net/Repository/Hierarchy/DefaultLoggerFactory.cs deleted file mode 100644 index 78239c57..00000000 --- a/src/log4net/Repository/Hierarchy/DefaultLoggerFactory.cs +++ /dev/null @@ -1,114 +0,0 @@ -#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 log4net.Core; - -namespace log4net.Repository.Hierarchy -{ - /// - /// Default implementation of - /// - /// - /// - /// This default implementation of the - /// interface is used to create the default subclass - /// of the object. - /// - /// - /// Nicko Cadell - /// Gert Driesen - internal class DefaultLoggerFactory : ILoggerFactory - { - #region Internal Instance Constructors - - /// - /// Default constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - internal DefaultLoggerFactory() - { - } - - #endregion Internal Instance Constructors - - #region Implementation of ILoggerFactory - - /// - /// Create a new instance - /// - /// The that will own the . - /// The name of the . - /// The instance for the specified name. - /// - /// - /// Create a new instance with the - /// specified name. - /// - /// - /// Called by the to create - /// new named instances. - /// - /// - /// If the is null then the root logger - /// must be returned. - /// - /// - public Logger CreateLogger(ILoggerRepository repository, string name) - { - if (name == null) - { - return new RootLogger(repository.LevelMap.LookupWithDefault(Level.Debug)); - } - return new LoggerImpl(name); - } - - #endregion - - /// - /// Default internal subclass of - /// - /// - /// - /// This subclass has no additional behavior over the - /// class but does allow instances - /// to be created. - /// - /// - internal sealed class LoggerImpl : Logger - { - /// - /// Construct a new Logger - /// - /// the name of the logger - /// - /// - /// Initializes a new instance of the class - /// with the specified name. - /// - /// - internal LoggerImpl(string name) : base(name) - { - } - } - } -} diff --git a/src/log4net/Repository/Hierarchy/Hierarchy.cs b/src/log4net/Repository/Hierarchy/Hierarchy.cs deleted file mode 100644 index 444d98b1..00000000 --- a/src/log4net/Repository/Hierarchy/Hierarchy.cs +++ /dev/null @@ -1,1077 +0,0 @@ -#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 System.Collections; -using log4net.Appender; -using log4net.Core; -using log4net.Repository; -using log4net.Util; - -namespace log4net.Repository.Hierarchy -{ - #region LoggerCreationEvent - - /// - /// Delegate used to handle logger creation event notifications. - /// - /// The in which the has been created. - /// The event args that hold the instance that has been created. - /// - /// - /// Delegate used to handle logger creation event notifications. - /// - /// - public delegate void LoggerCreationEventHandler(object sender, LoggerCreationEventArgs e); - - /// - /// Provides data for the event. - /// - /// - /// - /// A event is raised every time a - /// is created. - /// - /// - public class LoggerCreationEventArgs : EventArgs - { - /// - /// The created - /// - private Logger m_log; - - /// - /// Constructor - /// - /// The that has been created. - /// - /// - /// Initializes a new instance of the event argument - /// class,with the specified . - /// - /// - public LoggerCreationEventArgs(Logger log) - { - m_log = log; - } - - /// - /// Gets the that has been created. - /// - /// - /// The that has been created. - /// - /// - /// - /// The that has been created. - /// - /// - public Logger Logger - { - get { return m_log; } - } - } - - #endregion LoggerCreationEvent - - /// - /// Hierarchical organization of loggers - /// - /// - /// - /// The casual user should not have to deal with this class - /// directly. - /// - /// - /// This class is specialized in retrieving loggers by name and - /// also maintaining the logger hierarchy. Implements the - /// interface. - /// - /// - /// The structure of the logger hierarchy is maintained by the - /// method. The hierarchy is such that children - /// link to their parent but parents do not have any references to their - /// children. Moreover, loggers can be instantiated in any order, in - /// particular descendant before ancestor. - /// - /// - /// In case a descendant is created before a particular ancestor, - /// then it creates a provision node for the ancestor and adds itself - /// to the provision node. Other descendants of the same ancestor add - /// themselves to the previously created provision node. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class Hierarchy : LoggerRepositorySkeleton, IBasicRepositoryConfigurator, IXmlRepositoryConfigurator - { - #region Public Events - - /// - /// Event used to notify that a logger has been created. - /// - /// - /// - /// Event raised when a logger is created. - /// - /// - public event LoggerCreationEventHandler LoggerCreatedEvent - { - add { m_loggerCreatedEvent += value; } - remove { m_loggerCreatedEvent -= value; } - } - - #endregion Public Events - - #region Public Instance Constructors - - /// - /// Default constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public Hierarchy() : this(new DefaultLoggerFactory()) - { - } - - /// - /// Construct with properties - /// - /// The properties to pass to this repository. - /// - /// - /// Initializes a new instance of the class. - /// - /// - public Hierarchy(PropertiesDictionary properties) : this(properties, new DefaultLoggerFactory()) - { - } - - /// - /// Construct with a logger factory - /// - /// The factory to use to create new logger instances. - /// - /// - /// Initializes a new instance of the class with - /// the specified . - /// - /// - public Hierarchy(ILoggerFactory loggerFactory) : this(new PropertiesDictionary(), loggerFactory) - { - } - - /// - /// Construct with properties and a logger factory - /// - /// The properties to pass to this repository. - /// The factory to use to create new logger instances. - /// - /// - /// Initializes a new instance of the class with - /// the specified . - /// - /// - public Hierarchy(PropertiesDictionary properties, ILoggerFactory loggerFactory) : base(properties) - { - if (loggerFactory == null) - { - throw new ArgumentNullException("loggerFactory"); - } - - m_defaultFactory = loggerFactory; - - m_ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Has no appender warning been emitted - /// - /// - /// - /// Flag to indicate if we have already issued a warning - /// about not having an appender warning. - /// - /// - public bool EmittedNoAppenderWarning - { - get { return m_emittedNoAppenderWarning; } - set { m_emittedNoAppenderWarning = value; } - } - - /// - /// Get the root of this hierarchy - /// - /// - /// - /// Get the root of this hierarchy. - /// - /// - public Logger Root - { - get - { - if (m_root == null) - { - lock(this) - { - if (m_root == null) - { - // Create the root logger - Logger root = m_defaultFactory.CreateLogger(this, null); - root.Hierarchy = this; - - // Store root - m_root = root; - } - } - } - return m_root; - } - } - - /// - /// Gets or sets the default instance. - /// - /// The default - /// - /// - /// The logger factory is used to create logger instances. - /// - /// - public ILoggerFactory LoggerFactory - { - get { return m_defaultFactory; } - set - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - m_defaultFactory = value; - } - } - - #endregion Public Instance Properties - - #region Override Implementation of LoggerRepositorySkeleton - - /// - /// Test if a logger exists - /// - /// The name of the logger to lookup - /// The Logger object with the name specified - /// - /// - /// Check if the named logger exists in the hierarchy. If so return - /// its reference, otherwise returns null. - /// - /// - override public ILogger Exists(string name) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - return m_ht[new LoggerKey(name)] as Logger; - } - - /// - /// Returns all the currently defined loggers in the hierarchy as an Array - /// - /// All the defined loggers - /// - /// - /// Returns all the currently defined loggers in the hierarchy as an Array. - /// The root logger is not included in the returned - /// enumeration. - /// - /// - override public ILogger[] GetCurrentLoggers() - { - // The accumulation in loggers is necessary because not all elements in - // ht are Logger objects as there might be some ProvisionNodes - // as well. - System.Collections.ArrayList loggers = new System.Collections.ArrayList(m_ht.Count); - - // Iterate through m_ht values - foreach(object node in m_ht.Values) - { - if (node is Logger) - { - loggers.Add(node); - } - } - return (Logger[])loggers.ToArray(typeof(Logger)); - } - - /// - /// Return a new logger instance named as the first parameter using - /// the default factory. - /// - /// - /// - /// Return a new logger instance named as the first parameter using - /// the default factory. - /// - /// - /// If a logger of that name already exists, then it will be - /// returned. Otherwise, a new logger will be instantiated and - /// then linked with its existing ancestors as well as children. - /// - /// - /// The name of the logger to retrieve - /// The logger object with the name specified - override public ILogger GetLogger(string name) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - return GetLogger(name, m_defaultFactory); - } - - /// - /// Shutting down a hierarchy will safely close and remove - /// all appenders in all loggers including the root logger. - /// - /// - /// - /// Shutting down a hierarchy will safely close and remove - /// all appenders in all loggers including the root logger. - /// - /// - /// Some appenders need to be closed before the - /// application exists. Otherwise, pending logging events might be - /// lost. - /// - /// - /// The Shutdown method is careful to close nested - /// appenders before closing regular appenders. This is allows - /// configurations where a regular appender is attached to a logger - /// and again to a nested appender. - /// - /// - override public void Shutdown() - { - LogLog.Debug(declaringType, "Shutdown called on Hierarchy ["+this.Name+"]"); - - // begin by closing nested appenders - Root.CloseNestedAppenders(); - - lock(m_ht) - { - ILogger[] currentLoggers = this.GetCurrentLoggers(); - - foreach(Logger logger in currentLoggers) - { - logger.CloseNestedAppenders(); - } - - // then, remove all appenders - Root.RemoveAllAppenders(); - - foreach(Logger logger in currentLoggers) - { - logger.RemoveAllAppenders(); - } - } - - base.Shutdown(); - } - - /// - /// Reset all values contained in this hierarchy instance to their default. - /// - /// - /// - /// Reset all values contained in this hierarchy instance to their - /// default. This removes all appenders from all loggers, sets - /// the level of all non-root loggers to null, - /// sets their additivity flag to true and sets the level - /// of the root logger to . Moreover, - /// message disabling is set its default "off" value. - /// - /// - /// Existing loggers are not removed. They are just reset. - /// - /// - /// This method should be used sparingly and with care as it will - /// block all logging until it is completed. - /// - /// - override public void ResetConfiguration() - { - Root.Level = LevelMap.LookupWithDefault(Level.Debug); - Threshold = LevelMap.LookupWithDefault(Level.All); - - // the synchronization is needed to prevent hashtable surprises - lock(m_ht) - { - Shutdown(); // nested locks are OK - - foreach(Logger l in this.GetCurrentLoggers()) - { - l.Level = null; - l.Additivity = true; - } - } - - base.ResetConfiguration(); - - // Notify listeners - OnConfigurationChanged(null); - } - - /// - /// Log the logEvent through this hierarchy. - /// - /// the event to log - /// - /// - /// This method should not normally be used to log. - /// The interface should be used - /// for routine logging. This interface can be obtained - /// using the method. - /// - /// - /// The logEvent is delivered to the appropriate logger and - /// that logger is then responsible for logging the event. - /// - /// - override public void Log(LoggingEvent logEvent) - { - if (logEvent == null) - { - throw new ArgumentNullException("logEvent"); - } - - this.GetLogger(logEvent.LoggerName, m_defaultFactory).Log(logEvent); - } - - /// - /// Returns all the Appenders that are currently configured - /// - /// An array containing all the currently configured appenders - /// - /// - /// Returns all the instances that are currently configured. - /// All the loggers are searched for appenders. The appenders may also be containers - /// for appenders and these are also searched for additional loggers. - /// - /// - /// The list returned is unordered but does not contain duplicates. - /// - /// - override public Appender.IAppender[] GetAppenders() - { - System.Collections.ArrayList appenderList = new System.Collections.ArrayList(); - - CollectAppenders(appenderList, Root); - - foreach(Logger logger in GetCurrentLoggers()) - { - CollectAppenders(appenderList, logger); - } - - return (Appender.IAppender[])appenderList.ToArray(typeof(Appender.IAppender)); - } - - #endregion Override Implementation of LoggerRepositorySkeleton - - #region Private Static Methods - - /// - /// Collect the appenders from an . - /// The appender may also be a container. - /// - /// - /// - private static void CollectAppender(System.Collections.ArrayList appenderList, Appender.IAppender appender) - { - if (!appenderList.Contains(appender)) - { - appenderList.Add(appender); - - IAppenderAttachable container = appender as IAppenderAttachable; - if (container != null) - { - CollectAppenders(appenderList, container); - } - } - } - - /// - /// Collect the appenders from an container - /// - /// - /// - private static void CollectAppenders(System.Collections.ArrayList appenderList, IAppenderAttachable container) - { - foreach(Appender.IAppender appender in container.Appenders) - { - CollectAppender(appenderList, appender); - } - } - - #endregion - - #region Implementation of IBasicRepositoryConfigurator - - /// - /// Initialize the log4net system using the specified appender - /// - /// the appender to use to log all logging events - void IBasicRepositoryConfigurator.Configure(IAppender appender) - { - BasicRepositoryConfigure(appender); - } - - /// - /// Initialize the log4net system using the specified appenders - /// - /// the appenders to use to log all logging events - void IBasicRepositoryConfigurator.Configure(params IAppender[] appenders) - { - BasicRepositoryConfigure(appenders); - } - - /// - /// Initialize the log4net system using the specified appenders - /// - /// the appenders to use to log all logging events - /// - /// - /// This method provides the same functionality as the - /// method implemented - /// on this object, but it is protected and therefore can be called by subclasses. - /// - /// - protected void BasicRepositoryConfigure(params IAppender[] appenders) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - foreach (IAppender appender in appenders) - { - Root.AddAppender(appender); - } - } - - Configured = true; - - ConfigurationMessages = configurationMessages; - - // Notify listeners - OnConfigurationChanged(new ConfigurationChangedEventArgs(configurationMessages)); - } - - #endregion Implementation of IBasicRepositoryConfigurator - - #region Implementation of IXmlRepositoryConfigurator - - /// - /// Initialize the log4net system using the specified config - /// - /// the element containing the root of the config - void IXmlRepositoryConfigurator.Configure(System.Xml.XmlElement element) - { - XmlRepositoryConfigure(element); - } - - /// - /// Initialize the log4net system using the specified config - /// - /// the element containing the root of the config - /// - /// - /// This method provides the same functionality as the - /// method implemented - /// on this object, but it is protected and therefore can be called by subclasses. - /// - /// - protected void XmlRepositoryConfigure(System.Xml.XmlElement element) - { - ArrayList configurationMessages = new ArrayList(); - - using (new LogLog.LogReceivedAdapter(configurationMessages)) - { - XmlHierarchyConfigurator config = new XmlHierarchyConfigurator(this); - config.Configure(element); - } - - Configured = true; - - ConfigurationMessages = configurationMessages; - - // Notify listeners - OnConfigurationChanged(new ConfigurationChangedEventArgs(configurationMessages)); - } - - #endregion Implementation of IXmlRepositoryConfigurator - - #region Public Instance Methods - - /// - /// Test if this hierarchy is disabled for the specified . - /// - /// The level to check against. - /// - /// true if the repository is disabled for the level argument, false otherwise. - /// - /// - /// - /// If this hierarchy has not been configured then this method will - /// always return true. - /// - /// - /// This method will return true if this repository is - /// disabled for level object passed as parameter and - /// false otherwise. - /// - /// - /// See also the property. - /// - /// - public bool IsDisabled(Level level) - { - // Cast level to object for performance - if ((object)level == null) - { - throw new ArgumentNullException("level"); - } - - if (Configured) - { - return Threshold > level; - } - else - { - // If not configured the hierarchy is effectively disabled - return true; - } - } - - /// - /// Clear all logger definitions from the internal hashtable - /// - /// - /// - /// This call will clear all logger definitions from the internal - /// hashtable. Invoking this method will irrevocably mess up the - /// logger hierarchy. - /// - /// - /// You should really know what you are doing before - /// invoking this method. - /// - /// - public void Clear() - { - m_ht.Clear(); - } - - /// - /// Return a new logger instance named as the first parameter using - /// . - /// - /// The name of the logger to retrieve - /// The factory that will make the new logger instance - /// The logger object with the name specified - /// - /// - /// If a logger of that name already exists, then it will be - /// returned. Otherwise, a new logger will be instantiated by the - /// parameter and linked with its existing - /// ancestors as well as children. - /// - /// - public Logger GetLogger(string name, ILoggerFactory factory) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - if (factory == null) - { - throw new ArgumentNullException("factory"); - } - - LoggerKey key = new LoggerKey(name); - - // Synchronize to prevent write conflicts. Read conflicts (in - // GetEffectiveLevel() method) are possible only if variable - // assignments are non-atomic. - - lock(m_ht) - { - Logger logger = null; - - Object node = m_ht[key]; - if (node == null) - { - logger = factory.CreateLogger(this, name); - logger.Hierarchy = this; - m_ht[key] = logger; - UpdateParents(logger); - OnLoggerCreationEvent(logger); - return logger; - } - - Logger nodeLogger = node as Logger; - if (nodeLogger != null) - { - return nodeLogger; - } - - ProvisionNode nodeProvisionNode = node as ProvisionNode; - if (nodeProvisionNode != null) - { - logger = factory.CreateLogger(this, name); - logger.Hierarchy = this; - m_ht[key] = logger; - UpdateChildren(nodeProvisionNode, logger); - UpdateParents(logger); - OnLoggerCreationEvent(logger); - return logger; - } - - // It should be impossible to arrive here but let's keep the compiler happy. - return null; - } - } - - #endregion Public Instance Methods - - #region Protected Instance Methods - - /// - /// Sends a logger creation event to all registered listeners - /// - /// The newly created logger - /// - /// Raises the logger creation event. - /// - protected virtual void OnLoggerCreationEvent(Logger logger) - { - LoggerCreationEventHandler handler = m_loggerCreatedEvent; - if (handler != null) - { - handler(this, new LoggerCreationEventArgs(logger)); - } - } - - #endregion Protected Instance Methods - - #region Private Instance Methods - - /// - /// Updates all the parents of the specified logger - /// - /// The logger to update the parents for - /// - /// - /// This method loops through all the potential parents of - /// . There 3 possible cases: - /// - /// - /// - /// No entry for the potential parent of exists - /// - /// We create a ProvisionNode for this potential - /// parent and insert in that provision node. - /// - /// - /// - /// The entry is of type Logger for the potential parent. - /// - /// The entry is 's nearest existing parent. We - /// update 's parent field with this entry. We also break from - /// he loop because updating our parent's parent is our parent's - /// responsibility. - /// - /// - /// - /// The entry is of type ProvisionNode for this potential parent. - /// - /// We add to the list of children for this - /// potential parent. - /// - /// - /// - /// - private void UpdateParents(Logger log) - { - string name = log.Name; - int length = name.Length; - bool parentFound = false; - - // if name = "w.x.y.z", loop through "w.x.y", "w.x" and "w", but not "w.x.y.z" - for(int i = name.LastIndexOf('.', length-1); i >= 0; i = name.LastIndexOf('.', i-1)) - { - string substr = name.Substring(0, i); - - LoggerKey key = new LoggerKey(substr); // simple constructor - Object node = m_ht[key]; - // Create a provision node for a future parent. - if (node == null) - { - ProvisionNode pn = new ProvisionNode(log); - m_ht[key] = pn; - } - else - { - Logger nodeLogger = node as Logger; - if (nodeLogger != null) - { - parentFound = true; - log.Parent = nodeLogger; - break; // no need to update the ancestors of the closest ancestor - } - else - { - ProvisionNode nodeProvisionNode = node as ProvisionNode; - if (nodeProvisionNode != null) - { - nodeProvisionNode.Add(log); - } - else - { - LogLog.Error(declaringType, "Unexpected object type ["+node.GetType()+"] in ht.", new LogException()); - } - } - } - if (i == 0) { - // logger name starts with a dot - // and we've hit the start - break; - } - } - - // If we could not find any existing parents, then link with root. - if (!parentFound) - { - log.Parent = this.Root; - } - } - - /// - /// Replace a with a in the hierarchy. - /// - /// - /// - /// - /// - /// We update the links for all the children that placed themselves - /// in the provision node 'pn'. The second argument 'log' is a - /// reference for the newly created Logger, parent of all the - /// children in 'pn'. - /// - /// - /// We loop on all the children 'c' in 'pn'. - /// - /// - /// If the child 'c' has been already linked to a child of - /// 'log' then there is no need to update 'c'. - /// - /// - /// Otherwise, we set log's parent field to c's parent and set - /// c's parent field to log. - /// - /// - private static void UpdateChildren(ProvisionNode pn, Logger log) - { - for(int i = 0; i < pn.Count; i++) - { - Logger childLogger = (Logger)pn[i]; - - // Unless this child already points to a correct (lower) parent, - // make log.Parent point to childLogger.Parent and childLogger.Parent to log. - if (!childLogger.Parent.Name.StartsWith(log.Name)) - { - log.Parent = childLogger.Parent; - childLogger.Parent = log; - } - } - } - - /// - /// Define or redefine a Level using the values in the argument - /// - /// the level values - /// - /// - /// Define or redefine a Level using the values in the argument - /// - /// - /// Supports setting levels via the configuration file. - /// - /// - internal void AddLevel(LevelEntry levelEntry) - { - if (levelEntry == null) throw new ArgumentNullException("levelEntry"); - if (levelEntry.Name == null) throw new ArgumentNullException("levelEntry.Name"); - - // Lookup replacement value - if (levelEntry.Value == -1) - { - Level previousLevel = LevelMap[levelEntry.Name]; - if (previousLevel == null) - { - throw new InvalidOperationException("Cannot redefine level ["+levelEntry.Name+"] because it is not defined in the LevelMap. To define the level supply the level value."); - } - - levelEntry.Value = previousLevel.Value; - } - - LevelMap.Add(levelEntry.Name, levelEntry.Value, levelEntry.DisplayName); - } - - /// - /// A class to hold the value, name and display name for a level - /// - /// - /// - /// A class to hold the value, name and display name for a level - /// - /// - internal class LevelEntry - { - private int m_levelValue = -1; - private string m_levelName = null; - private string m_levelDisplayName = null; - - /// - /// Value of the level - /// - /// - /// - /// If the value is not set (defaults to -1) the value will be looked - /// up for the current level with the same name. - /// - /// - public int Value - { - get { return m_levelValue; } - set { m_levelValue = value; } - } - - /// - /// Name of the level - /// - /// - /// The name of the level - /// - /// - /// - /// The name of the level. - /// - /// - public string Name - { - get { return m_levelName; } - set { m_levelName = value; } - } - - /// - /// Display name for the level - /// - /// - /// The display name of the level - /// - /// - /// - /// The display name of the level. - /// - /// - public string DisplayName - { - get { return m_levelDisplayName; } - set { m_levelDisplayName = value; } - } - - /// - /// Override Object.ToString to return sensible debug info - /// - /// string info about this object - public override string ToString() - { - return "LevelEntry(Value="+m_levelValue+", Name="+m_levelName+", DisplayName="+m_levelDisplayName+")"; - } - } - - /// - /// Set a Property using the values in the argument - /// - /// the property value - /// - /// - /// Set a Property using the values in the argument. - /// - /// - /// Supports setting property values via the configuration file. - /// - /// - internal void AddProperty(PropertyEntry propertyEntry) - { - if (propertyEntry == null) throw new ArgumentNullException("propertyEntry"); - if (propertyEntry.Key == null) throw new ArgumentNullException("propertyEntry.Key"); - - Properties[propertyEntry.Key] = propertyEntry.Value; - } - - #endregion Private Instance Methods - - #region Private Instance Fields - - private ILoggerFactory m_defaultFactory; - - private System.Collections.Hashtable m_ht; - private Logger m_root; - - private bool m_emittedNoAppenderWarning = false; - - private event LoggerCreationEventHandler m_loggerCreatedEvent; - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the Hierarchy class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(Hierarchy); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Repository/Hierarchy/ILoggerFactory.cs b/src/log4net/Repository/Hierarchy/ILoggerFactory.cs deleted file mode 100644 index 52966f4e..00000000 --- a/src/log4net/Repository/Hierarchy/ILoggerFactory.cs +++ /dev/null @@ -1,64 +0,0 @@ -#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 - -namespace log4net.Repository.Hierarchy -{ - /// - /// Interface abstracts creation of instances - /// - /// - /// - /// This interface is used by the to - /// create new objects. - /// - /// - /// The method is called - /// to create a named . - /// - /// - /// Implement this interface to create new subclasses of . - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface ILoggerFactory - { - /// - /// Create a new instance - /// - /// The that will own the . - /// The name of the . - /// The instance for the specified name. - /// - /// - /// Create a new instance with the - /// specified name. - /// - /// - /// Called by the to create - /// new named instances. - /// - /// - /// If the is null then the root logger - /// must be returned. - /// - /// - Logger CreateLogger(ILoggerRepository repository, string name); - } -} diff --git a/src/log4net/Repository/Hierarchy/Logger.cs b/src/log4net/Repository/Hierarchy/Logger.cs deleted file mode 100644 index b74ac429..00000000 --- a/src/log4net/Repository/Hierarchy/Logger.cs +++ /dev/null @@ -1,789 +0,0 @@ -#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 System.Collections; - -using log4net.Appender; -using log4net.Util; -using log4net.Core; - -namespace log4net.Repository.Hierarchy -{ - /// - /// Implementation of used by - /// - /// - /// - /// Internal class used to provide implementation of - /// interface. Applications should use to get - /// logger instances. - /// - /// - /// This is one of the central classes in the log4net implementation. One of the - /// distinctive features of log4net are hierarchical loggers and their - /// evaluation. The organizes the - /// instances into a rooted tree hierarchy. - /// - /// - /// The class is abstract. Only concrete subclasses of - /// can be created. The - /// is used to create instances of this type for the . - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Aspi Havewala - /// Douglas de la Torre - public abstract class Logger : IAppenderAttachable, ILogger - { - #region Protected Instance Constructors - - /// - /// This constructor created a new instance and - /// sets its name. - /// - /// The name of the . - /// - /// - /// This constructor is protected and designed to be used by - /// a subclass that is not abstract. - /// - /// - /// Loggers are constructed by - /// objects. See for the default - /// logger creator. - /// - /// - protected Logger(string name) - { -#if NETCF - // NETCF: String.Intern causes Native Exception - m_name = name; -#else - m_name = string.Intern(name); -#endif - } - - #endregion Protected Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the parent logger in the hierarchy. - /// - /// - /// The parent logger in the hierarchy. - /// - /// - /// - /// Part of the Composite pattern that makes the hierarchy. - /// The hierarchy is parent linked rather than child linked. - /// - /// - virtual public Logger Parent - { - get { return m_parent; } - set { m_parent = value; } - } - - /// - /// Gets or sets a value indicating if child loggers inherit their parent's appenders. - /// - /// - /// true if child loggers inherit their parent's appenders. - /// - /// - /// - /// Additivity is set to true by default, that is children inherit - /// the appenders of their ancestors by default. If this variable is - /// set to false then the appenders found in the - /// ancestors of this logger are not used. However, the children - /// of this logger will inherit its appenders, unless the children - /// have their additivity flag set to false too. See - /// the user manual for more details. - /// - /// - virtual public bool Additivity - { - get { return m_additive; } - set { m_additive = value; } - } - - /// - /// Gets the effective level for this logger. - /// - /// The nearest level in the logger hierarchy. - /// - /// - /// Starting from this logger, searches the logger hierarchy for a - /// non-null level and returns it. Otherwise, returns the level of the - /// root logger. - /// - /// The Logger class is designed so that this method executes as - /// quickly as possible. - /// - virtual public Level EffectiveLevel - { - get - { - for(Logger c = this; c != null; c = c.Parent) - { - Level level = c.Level; - - // Casting level to Object for performance, otherwise the overloaded operator is called - if ((object)level != null) - { - return level; - } - } - return null; // If reached will cause an NullPointerException. - } - } - - /// - /// Gets or sets the where this - /// Logger instance is attached to. - /// - /// The hierarchy that this logger belongs to. - /// - /// - /// This logger must be attached to a single . - /// - /// - virtual public Hierarchy Hierarchy - { - get { return m_hierarchy; } - set { m_hierarchy = value; } - } - - /// - /// Gets or sets the assigned , if any, for this Logger. - /// - /// - /// The of this logger. - /// - /// - /// - /// The assigned can be null. - /// - /// - virtual public Level Level - { - get { return m_level; } - set { m_level = value; } - } - - #endregion Public Instance Properties - - #region Implementation of IAppenderAttachable - - /// - /// Add to the list of appenders of this - /// Logger instance. - /// - /// An appender to add to this logger - /// - /// - /// Add to the list of appenders of this - /// Logger instance. - /// - /// - /// If is already in the list of - /// appenders, then it won't be added again. - /// - /// - virtual public void AddAppender(IAppender newAppender) - { - if (newAppender == null) - { - throw new ArgumentNullException("newAppender"); - } - - m_appenderLock.AcquireWriterLock(); - try - { - if (m_appenderAttachedImpl == null) - { - m_appenderAttachedImpl = new log4net.Util.AppenderAttachedImpl(); - } - m_appenderAttachedImpl.AddAppender(newAppender); - } - finally - { - m_appenderLock.ReleaseWriterLock(); - } - } - - /// - /// Get the appenders contained in this logger as an - /// . - /// - /// A collection of the appenders in this logger - /// - /// - /// Get the appenders contained in this logger as an - /// . If no appenders - /// can be found, then a is returned. - /// - /// - virtual public AppenderCollection Appenders - { - get - { - m_appenderLock.AcquireReaderLock(); - try - { - if (m_appenderAttachedImpl == null) - { - return AppenderCollection.EmptyCollection; - } - else - { - return m_appenderAttachedImpl.Appenders; - } - } - finally - { - m_appenderLock.ReleaseReaderLock(); - } - } - } - - /// - /// Look for the appender named as name - /// - /// The name of the appender to lookup - /// The appender with the name specified, or null. - /// - /// - /// Returns the named appender, or null if the appender is not found. - /// - /// - virtual public IAppender GetAppender(string name) - { - m_appenderLock.AcquireReaderLock(); - try - { - if (m_appenderAttachedImpl == null || name == null) - { - return null; - } - - return m_appenderAttachedImpl.GetAppender(name); - } - finally - { - m_appenderLock.ReleaseReaderLock(); - } - } - - /// - /// Remove all previously added appenders from this Logger instance. - /// - /// - /// - /// Remove all previously added appenders from this Logger instance. - /// - /// - /// This is useful when re-reading configuration information. - /// - /// - virtual public void RemoveAllAppenders() - { - m_appenderLock.AcquireWriterLock(); - try - { - if (m_appenderAttachedImpl != null) - { - m_appenderAttachedImpl.RemoveAllAppenders(); - m_appenderAttachedImpl = null; - } - } - finally - { - m_appenderLock.ReleaseWriterLock(); - } - } - - /// - /// Remove the appender passed as parameter form the list of appenders. - /// - /// The appender to remove - /// The appender removed from the list - /// - /// - /// Remove the appender passed as parameter form the list of appenders. - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - /// - virtual public IAppender RemoveAppender(IAppender appender) - { - m_appenderLock.AcquireWriterLock(); - try - { - if (appender != null && m_appenderAttachedImpl != null) - { - return m_appenderAttachedImpl.RemoveAppender(appender); - } - } - finally - { - m_appenderLock.ReleaseWriterLock(); - } - return null; - } - - /// - /// Remove the appender passed as parameter form the list of appenders. - /// - /// The name of the appender to remove - /// The appender removed from the list - /// - /// - /// Remove the named appender passed as parameter form the list of appenders. - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - /// - virtual public IAppender RemoveAppender(string name) - { - m_appenderLock.AcquireWriterLock(); - try - { - if (name != null && m_appenderAttachedImpl != null) - { - return m_appenderAttachedImpl.RemoveAppender(name); - } - } - finally - { - m_appenderLock.ReleaseWriterLock(); - } - return null; - } - - #endregion - - #region Implementation of ILogger - - /// - /// Gets the logger name. - /// - /// - /// The name of the logger. - /// - /// - /// - /// The name of this logger - /// - /// - virtual public string Name - { - get { return m_name; } - } - - /// - /// This generic form is intended to be used by wrappers. - /// - /// The declaring type of the method that is - /// the stack boundary into the logging system for this call. - /// The level of the message to be logged. - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// Generate a logging event for the specified using - /// the and . - /// - /// - /// This method must not throw any exception to the caller. - /// - /// - virtual public void Log(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception) - { - try - { - if (IsEnabledFor(level)) - { - ForcedLog((callerStackBoundaryDeclaringType != null) ? callerStackBoundaryDeclaringType : declaringType, level, message, exception); - } - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } -#if NETCF - catch - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging"); - } -#endif - } - - /// - /// This is the most generic printing method that is intended to be used - /// by wrappers. - /// - /// The event being logged. - /// - /// - /// Logs the specified logging event through this logger. - /// - /// - /// This method must not throw any exception to the caller. - /// - /// - virtual public void Log(LoggingEvent logEvent) - { - try - { - if (logEvent != null) - { - if (IsEnabledFor(logEvent.Level)) - { - ForcedLog(logEvent); - } - } - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } -#if NETCF - catch - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging"); - } -#endif - } - - /// - /// Checks if this logger is enabled for a given passed as parameter. - /// - /// The level to check. - /// - /// true if this logger is enabled for level, otherwise false. - /// - /// - /// - /// Test if this logger is going to log events of the specified . - /// - /// - /// This method must not throw any exception to the caller. - /// - /// - virtual public bool IsEnabledFor(Level level) - { - try - { - if (level != null) - { - if (Hierarchy.IsDisabled(level)) - { - return false; - } - return level >= this.EffectiveLevel; - } - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } -#if NETCF - catch - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging"); - } -#endif - return false; - } - - /// - /// Gets the where this - /// Logger instance is attached to. - /// - /// - /// The that this logger belongs to. - /// - /// - /// - /// Gets the where this - /// Logger instance is attached to. - /// - /// - public ILoggerRepository Repository - { - get { return Hierarchy; } - } - - #endregion Implementation of ILogger - - /// - /// Deliver the to the attached appenders. - /// - /// The event to log. - /// - /// - /// Call the appenders in the hierarchy starting at - /// this. If no appenders could be found, emit a - /// warning. - /// - /// - /// This method calls all the appenders inherited from the - /// hierarchy circumventing any evaluation of whether to log or not - /// to log the particular log request. - /// - /// - virtual protected void CallAppenders(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - int writes = 0; - - for(Logger c=this; c != null; c=c.Parent) - { - if (c.m_appenderAttachedImpl != null) - { - // Protected against simultaneous call to addAppender, removeAppender,... - c.m_appenderLock.AcquireReaderLock(); - try - { - if (c.m_appenderAttachedImpl != null) - { - writes += c.m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent); - } - } - finally - { - c.m_appenderLock.ReleaseReaderLock(); - } - } - - if (!c.Additivity) - { - break; - } - } - - // No appenders in hierarchy, warn user only once. - // - // Note that by including the AppDomain values for the currently running - // thread, it becomes much easier to see which application the warning - // is from, which is especially helpful in a multi-AppDomain environment - // (like IIS with multiple VDIRS). Without this, it can be difficult - // or impossible to determine which .config file is missing appender - // definitions. - // - if (!Hierarchy.EmittedNoAppenderWarning && writes == 0) - { - Hierarchy.EmittedNoAppenderWarning = true; - LogLog.Debug(declaringType, "No appenders could be found for logger [" + Name + "] repository [" + Repository.Name + "]"); - LogLog.Debug(declaringType, "Please initialize the log4net system properly."); - try - { - LogLog.Debug(declaringType, " Current AppDomain context information: "); - LogLog.Debug(declaringType, " BaseDirectory : " + SystemInfo.ApplicationBaseDirectory); -#if !NETCF - LogLog.Debug(declaringType, " FriendlyName : " + AppDomain.CurrentDomain.FriendlyName); - LogLog.Debug(declaringType, " DynamicDirectory: " + AppDomain.CurrentDomain.DynamicDirectory); -#endif - } - catch(System.Security.SecurityException) - { - // Insufficient permissions to display info from the AppDomain - } - } - } - - /// - /// Closes all attached appenders implementing the interface. - /// - /// - /// - /// Used to ensure that the appenders are correctly shutdown. - /// - /// - virtual public void CloseNestedAppenders() - { - m_appenderLock.AcquireWriterLock(); - try - { - if (m_appenderAttachedImpl != null) - { - AppenderCollection appenders = m_appenderAttachedImpl.Appenders; - foreach(IAppender appender in appenders) - { - if (appender is IAppenderAttachable) - { - appender.Close(); - } - } - } - } - finally - { - m_appenderLock.ReleaseWriterLock(); - } - } - - /// - /// This is the most generic printing method. This generic form is intended to be used by wrappers - /// - /// The level of the message to be logged. - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// Generate a logging event for the specified using - /// the . - /// - /// - virtual public void Log(Level level, object message, Exception exception) - { - if (IsEnabledFor(level)) - { - ForcedLog(declaringType, level, message, exception); - } - } - - /// - /// Creates a new logging event and logs the event without further checks. - /// - /// The declaring type of the method that is - /// the stack boundary into the logging system for this call. - /// The level of the message to be logged. - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// Generates a logging event and delivers it to the attached - /// appenders. - /// - /// - virtual protected void ForcedLog(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception) - { - CallAppenders(new LoggingEvent(callerStackBoundaryDeclaringType, this.Hierarchy, this.Name, level, message, exception)); - } - - /// - /// Creates a new logging event and logs the event without further checks. - /// - /// The event being logged. - /// - /// - /// Delivers the logging event to the attached appenders. - /// - /// - virtual protected void ForcedLog(LoggingEvent logEvent) - { - // The logging event may not have been created by this logger - // the Repository may not be correctly set on the event. This - // is required for the appenders to correctly lookup renderers etc... - logEvent.EnsureRepository(this.Hierarchy); - - CallAppenders(logEvent); - } - - #region Private Static Fields - - /// - /// The fully qualified type of the Logger class. - /// - private readonly static Type declaringType = typeof(Logger); - - #endregion Private Static Fields - - #region Private Instance Fields - - /// - /// The name of this logger. - /// - private readonly string m_name; - - /// - /// The assigned level of this logger. - /// - /// - /// - /// The level variable need not be - /// assigned a value in which case it is inherited - /// form the hierarchy. - /// - /// - private Level m_level; - - /// - /// The parent of this logger. - /// - /// - /// - /// The parent of this logger. - /// All loggers have at least one ancestor which is the root logger. - /// - /// - private Logger m_parent; - - /// - /// Loggers need to know what Hierarchy they are in. - /// - /// - /// - /// Loggers need to know what Hierarchy they are in. - /// The hierarchy that this logger is a member of is stored - /// here. - /// - /// - private Hierarchy m_hierarchy; - - /// - /// Helper implementation of the interface - /// - private log4net.Util.AppenderAttachedImpl m_appenderAttachedImpl; - - /// - /// Flag indicating if child loggers inherit their parents appenders - /// - /// - /// - /// Additivity is set to true by default, that is children inherit - /// the appenders of their ancestors by default. If this variable is - /// set to false then the appenders found in the - /// ancestors of this logger are not used. However, the children - /// of this logger will inherit its appenders, unless the children - /// have their additivity flag set to false too. See - /// the user manual for more details. - /// - /// - private bool m_additive = true; - - /// - /// Lock to protect AppenderAttachedImpl variable m_appenderAttachedImpl - /// - private readonly ReaderWriterLock m_appenderLock = new ReaderWriterLock(); - - #endregion - } -} diff --git a/src/log4net/Repository/Hierarchy/LoggerKey.cs b/src/log4net/Repository/Hierarchy/LoggerKey.cs deleted file mode 100644 index 1ea90048..00000000 --- a/src/log4net/Repository/Hierarchy/LoggerKey.cs +++ /dev/null @@ -1,138 +0,0 @@ -#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; - -namespace log4net.Repository.Hierarchy -{ - /// - /// Used internally to accelerate hash table searches. - /// - /// - /// - /// Internal class used to improve performance of - /// string keyed hashtables. - /// - /// - /// The hashcode of the string is cached for reuse. - /// The string is stored as an interned value. - /// When comparing two objects for equality - /// the reference equality of the interned strings is compared. - /// - /// - /// Nicko Cadell - /// Gert Driesen - internal sealed class LoggerKey - { - #region Internal Instance Constructors - - /// - /// Construct key with string name - /// - /// - /// - /// Initializes a new instance of the class - /// with the specified name. - /// - /// - /// Stores the hashcode of the string and interns - /// the string key to optimize comparisons. - /// - /// - /// The Compact Framework 1.0 the - /// method does not work. On the Compact Framework - /// the string keys are not interned nor are they - /// compared by reference. - /// - /// - /// The name of the logger. - internal LoggerKey(string name) - { -#if NETCF - // NETCF: String.Intern causes Native Exception - m_name = name; -#else - m_name = string.Intern(name); -#endif - m_hashCache = name.GetHashCode(); - } - - #endregion Internal Instance Constructors - - #region Override implementation of Object - - /// - /// Returns a hash code for the current instance. - /// - /// A hash code for the current instance. - /// - /// - /// Returns the cached hashcode. - /// - /// - override public int GetHashCode() - { - return m_hashCache; - } - - /// - /// Determines whether two instances - /// are equal. - /// - /// The to compare with the current . - /// - /// true if the specified is equal to the current ; otherwise, false. - /// - /// - /// - /// Compares the references of the interned strings. - /// - /// - override public bool Equals(object obj) - { - // Compare reference type of this against argument - if (((object)this) == obj) - { - return true; - } - - LoggerKey objKey = obj as LoggerKey; - if (objKey != null) - { -#if NETCF - return ( m_name == objKey.m_name ); -#else - // Compare reference types rather than string's overloaded == - return ( ((object)m_name) == ((object)objKey.m_name) ); -#endif - } - return false; - } - - #endregion - - #region Private Instance Fields - - private readonly string m_name; - private readonly int m_hashCache; - - #endregion Private Instance Fields - } -} - diff --git a/src/log4net/Repository/Hierarchy/ProvisionNode.cs b/src/log4net/Repository/Hierarchy/ProvisionNode.cs deleted file mode 100644 index 50f4e168..00000000 --- a/src/log4net/Repository/Hierarchy/ProvisionNode.cs +++ /dev/null @@ -1,58 +0,0 @@ -#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 System.Collections; - -namespace log4net.Repository.Hierarchy -{ - /// - /// Provision nodes are used where no logger instance has been specified - /// - /// - /// - /// instances are used in the - /// when there is no specified - /// for that node. - /// - /// - /// A provision node holds a list of child loggers on behalf of - /// a logger that does not exist. - /// - /// - /// Nicko Cadell - /// Gert Driesen - internal sealed class ProvisionNode : ArrayList - { - /// - /// Create a new provision node with child node - /// - /// A child logger to add to this node. - /// - /// - /// Initializes a new instance of the class - /// with the specified child logger. - /// - /// - internal ProvisionNode(Logger log) : base() - { - this.Add(log); - } - } -} diff --git a/src/log4net/Repository/Hierarchy/RootLogger.cs b/src/log4net/Repository/Hierarchy/RootLogger.cs deleted file mode 100644 index e178bb71..00000000 --- a/src/log4net/Repository/Hierarchy/RootLogger.cs +++ /dev/null @@ -1,133 +0,0 @@ -#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.Util; -using log4net.Core; - -namespace log4net.Repository.Hierarchy -{ - /// - /// The sits at the root of the logger hierarchy tree. - /// - /// - /// - /// The is a regular except - /// that it provides several guarantees. - /// - /// - /// First, it cannot be assigned a null - /// level. Second, since the root logger cannot have a parent, the - /// property always returns the value of the - /// level field without walking the hierarchy. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class RootLogger : Logger - { - #region Public Instance Constructors - - /// - /// Construct a - /// - /// The level to assign to the root logger. - /// - /// - /// Initializes a new instance of the class with - /// the specified logging level. - /// - /// - /// The root logger names itself as "root". However, the root - /// logger cannot be retrieved by name. - /// - /// - public RootLogger(Level level) : base("root") - { - this.Level = level; - } - - #endregion Public Instance Constructors - - #region Override implementation of Logger - - /// - /// Gets the assigned level value without walking the logger hierarchy. - /// - /// The assigned level value without walking the logger hierarchy. - /// - /// - /// Because the root logger cannot have a parent and its level - /// must not be null this property just returns the - /// value of . - /// - /// - override public Level EffectiveLevel - { - get - { - return base.Level; - } - } - - /// - /// Gets or sets the assigned for the root logger. - /// - /// - /// The of the root logger. - /// - /// - /// - /// Setting the level of the root logger to a null reference - /// may have catastrophic results. We prevent this here. - /// - /// - override public Level Level - { - get { return base.Level; } - set - { - if (value == null) - { - LogLog.Error(declaringType, "You have tried to set a null level to root.", new LogException()); - } - else - { - base.Level = value; - } - } - } - - #endregion Override implementation of Logger - - #region Private Static Fields - - /// - /// The fully qualified type of the RootLogger class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(RootLogger); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs b/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs deleted file mode 100644 index c483d0da..00000000 --- a/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs +++ /dev/null @@ -1,1118 +0,0 @@ -#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 System.Collections; -using System.Globalization; -using System.Reflection; -using System.Xml; - -using log4net.Appender; -using log4net.Util; -using log4net.Core; -using log4net.ObjectRenderer; - -namespace log4net.Repository.Hierarchy -{ - /// - /// Initializes the log4net environment using an XML DOM. - /// - /// - /// - /// Configures a using an XML DOM. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class XmlHierarchyConfigurator - { - private enum ConfigUpdateMode - { - Merge, - Overwrite - } - - #region Public Instance Constructors - - /// - /// Construct the configurator for a hierarchy - /// - /// The hierarchy to build. - /// - /// - /// Initializes a new instance of the class - /// with the specified . - /// - /// - public XmlHierarchyConfigurator(Hierarchy hierarchy) - { - m_hierarchy = hierarchy; - m_appenderBag = new Hashtable(); - } - - #endregion Public Instance Constructors - - #region Public Instance Methods - - /// - /// Configure the hierarchy by parsing a DOM tree of XML elements. - /// - /// The root element to parse. - /// - /// - /// Configure the hierarchy by parsing a DOM tree of XML elements. - /// - /// - public void Configure(XmlElement element) - { - if (element == null || m_hierarchy == null) - { - return; - } - - string rootElementName = element.LocalName; - - if (rootElementName != CONFIGURATION_TAG) - { - LogLog.Error(declaringType, "Xml element is - not a <" + CONFIGURATION_TAG + "> element."); - return; - } - - if (!LogLog.EmitInternalMessages) - { - // Look for a emitDebug attribute to enable internal debug - string emitDebugAttribute = element.GetAttribute(EMIT_INTERNAL_DEBUG_ATTR); - LogLog.Debug(declaringType, EMIT_INTERNAL_DEBUG_ATTR + " attribute [" + emitDebugAttribute + "]."); - - if (emitDebugAttribute.Length > 0 && emitDebugAttribute != "null") - { - LogLog.EmitInternalMessages = OptionConverter.ToBoolean(emitDebugAttribute, true); - } - else - { - LogLog.Debug(declaringType, "Ignoring " + EMIT_INTERNAL_DEBUG_ATTR + " attribute."); - } - } - - if (!LogLog.InternalDebugging) - { - // Look for a debug attribute to enable internal debug - string debugAttribute = element.GetAttribute(INTERNAL_DEBUG_ATTR); - LogLog.Debug(declaringType, INTERNAL_DEBUG_ATTR + " attribute [" + debugAttribute + "]."); - - if (debugAttribute.Length > 0 && debugAttribute != "null") - { - LogLog.InternalDebugging = OptionConverter.ToBoolean(debugAttribute, true); - } - else - { - LogLog.Debug(declaringType, "Ignoring " + INTERNAL_DEBUG_ATTR + " attribute."); - } - - string confDebug = element.GetAttribute(CONFIG_DEBUG_ATTR); - if (confDebug.Length > 0 && confDebug != "null") - { - LogLog.Warn(declaringType, "The \"" + CONFIG_DEBUG_ATTR + "\" attribute is deprecated."); - LogLog.Warn(declaringType, "Use the \"" + INTERNAL_DEBUG_ATTR + "\" attribute instead."); - LogLog.InternalDebugging = OptionConverter.ToBoolean(confDebug, true); - } - } - - // Default mode is merge - ConfigUpdateMode configUpdateMode = ConfigUpdateMode.Merge; - - // Look for the config update attribute - string configUpdateModeAttribute = element.GetAttribute(CONFIG_UPDATE_MODE_ATTR); - if (configUpdateModeAttribute != null && configUpdateModeAttribute.Length > 0) - { - // Parse the attribute - try - { - configUpdateMode = (ConfigUpdateMode)OptionConverter.ConvertStringTo(typeof(ConfigUpdateMode), configUpdateModeAttribute); - } - catch - { - LogLog.Error(declaringType, "Invalid " + CONFIG_UPDATE_MODE_ATTR + " attribute value [" + configUpdateModeAttribute + "]"); - } - } - - // IMPL: The IFormatProvider argument to Enum.ToString() is deprecated in .NET 2.0 - LogLog.Debug(declaringType, "Configuration update mode [" + configUpdateMode.ToString() + "]."); - - // Only reset configuration if overwrite flag specified - if (configUpdateMode == ConfigUpdateMode.Overwrite) - { - // Reset to original unset configuration - m_hierarchy.ResetConfiguration(); - LogLog.Debug(declaringType, "Configuration reset before reading config."); - } - - /* Building Appender objects, placing them in a local namespace - for future reference */ - - /* Process all the top level elements */ - - foreach (XmlNode currentNode in element.ChildNodes) - { - if (currentNode.NodeType == XmlNodeType.Element) - { - XmlElement currentElement = (XmlElement)currentNode; - - if (currentElement.LocalName == LOGGER_TAG) - { - ParseLogger(currentElement); - } - else if (currentElement.LocalName == CATEGORY_TAG) - { - // TODO: deprecated use of category - ParseLogger(currentElement); - } - else if (currentElement.LocalName == ROOT_TAG) - { - ParseRoot(currentElement); - } - else if (currentElement.LocalName == RENDERER_TAG) - { - ParseRenderer(currentElement); - } - else if (currentElement.LocalName == APPENDER_TAG) - { - // We ignore appenders in this pass. They will - // be found and loaded if they are referenced. - } - else - { - // Read the param tags and set properties on the hierarchy - SetParameter(currentElement, m_hierarchy); - } - } - } - - // Lastly set the hierarchy threshold - string thresholdStr = element.GetAttribute(THRESHOLD_ATTR); - LogLog.Debug(declaringType, "Hierarchy Threshold [" + thresholdStr + "]"); - if (thresholdStr.Length > 0 && thresholdStr != "null") - { - Level thresholdLevel = (Level)ConvertStringTo(typeof(Level), thresholdStr); - if (thresholdLevel != null) - { - m_hierarchy.Threshold = thresholdLevel; - } - else - { - LogLog.Warn(declaringType, "Unable to set hierarchy threshold using value [" + thresholdStr + "] (with acceptable conversion types)"); - } - } - - // Done reading config - } - - #endregion Public Instance Methods - - #region Protected Instance Methods - - /// - /// Parse appenders by IDREF. - /// - /// The appender ref element. - /// The instance of the appender that the ref refers to. - /// - /// - /// Parse an XML element that represents an appender and return - /// the appender. - /// - /// - protected IAppender FindAppenderByReference(XmlElement appenderRef) - { - string appenderName = appenderRef.GetAttribute(REF_ATTR); - - IAppender appender = (IAppender)m_appenderBag[appenderName]; - if (appender != null) - { - return appender; - } - else - { - // Find the element with that id - XmlElement element = null; - - if (appenderName != null && appenderName.Length > 0) - { - foreach (XmlElement curAppenderElement in appenderRef.OwnerDocument.GetElementsByTagName(APPENDER_TAG)) - { - if (curAppenderElement.GetAttribute("name") == appenderName) - { - element = curAppenderElement; - break; - } - } - } - - if (element == null) - { - LogLog.Error(declaringType, "XmlHierarchyConfigurator: No appender named [" + appenderName + "] could be found."); - return null; - } - else - { - appender = ParseAppender(element); - if (appender != null) - { - m_appenderBag[appenderName] = appender; - } - return appender; - } - } - } - - /// - /// Parses an appender element. - /// - /// The appender element. - /// The appender instance or null when parsing failed. - /// - /// - /// Parse an XML element that represents an appender and return - /// the appender instance. - /// - /// - protected IAppender ParseAppender(XmlElement appenderElement) - { - string appenderName = appenderElement.GetAttribute(NAME_ATTR); - string typeName = appenderElement.GetAttribute(TYPE_ATTR); - - LogLog.Debug(declaringType, "Loading Appender [" + appenderName + "] type: [" + typeName + "]"); - try - { - IAppender appender = (IAppender)Activator.CreateInstance(SystemInfo.GetTypeFromString(typeName, true, true)); - appender.Name = appenderName; - - foreach (XmlNode currentNode in appenderElement.ChildNodes) - { - /* We're only interested in Elements */ - if (currentNode.NodeType == XmlNodeType.Element) - { - XmlElement currentElement = (XmlElement)currentNode; - - // Look for the appender ref tag - if (currentElement.LocalName == APPENDER_REF_TAG) - { - string refName = currentElement.GetAttribute(REF_ATTR); - - IAppenderAttachable appenderContainer = appender as IAppenderAttachable; - if (appenderContainer != null) - { - LogLog.Debug(declaringType, "Attaching appender named [" + refName + "] to appender named [" + appender.Name + "]."); - - IAppender referencedAppender = FindAppenderByReference(currentElement); - if (referencedAppender != null) - { - appenderContainer.AddAppender(referencedAppender); - } - } - else - { - LogLog.Error(declaringType, "Requesting attachment of appender named [" + refName + "] to appender named [" + appender.Name + "] which does not implement log4net.Core.IAppenderAttachable."); - } - } - else - { - // For all other tags we use standard set param method - SetParameter(currentElement, appender); - } - } - } - - IOptionHandler optionHandler = appender as IOptionHandler; - if (optionHandler != null) - { - optionHandler.ActivateOptions(); - } - - LogLog.Debug(declaringType, "Created Appender [" + appenderName + "]"); - return appender; - } - catch (Exception ex) - { - // Yes, it's ugly. But all exceptions point to the same problem: we can't create an Appender - - LogLog.Error(declaringType, "Could not create Appender [" + appenderName + "] of type [" + typeName + "]. Reported error follows.", ex); - return null; - } - } - - /// - /// Parses a logger element. - /// - /// The logger element. - /// - /// - /// Parse an XML element that represents a logger. - /// - /// - protected void ParseLogger(XmlElement loggerElement) - { - // Create a new log4net.Logger object from the element. - string loggerName = loggerElement.GetAttribute(NAME_ATTR); - - LogLog.Debug(declaringType, "Retrieving an instance of log4net.Repository.Logger for logger [" + loggerName + "]."); - Logger log = m_hierarchy.GetLogger(loggerName) as Logger; - - // Setting up a logger needs to be an atomic operation, in order - // to protect potential log operations while logger - // configuration is in progress. - lock (log) - { - bool additivity = OptionConverter.ToBoolean(loggerElement.GetAttribute(ADDITIVITY_ATTR), true); - - LogLog.Debug(declaringType, "Setting [" + log.Name + "] additivity to [" + additivity + "]."); - log.Additivity = additivity; - ParseChildrenOfLoggerElement(loggerElement, log, false); - } - } - - /// - /// Parses the root logger element. - /// - /// The root element. - /// - /// - /// Parse an XML element that represents the root logger. - /// - /// - protected void ParseRoot(XmlElement rootElement) - { - Logger root = m_hierarchy.Root; - // logger configuration needs to be atomic - lock (root) - { - ParseChildrenOfLoggerElement(rootElement, root, true); - } - } - - /// - /// Parses the children of a logger element. - /// - /// The category element. - /// The logger instance. - /// Flag to indicate if the logger is the root logger. - /// - /// - /// Parse the child elements of a <logger> element. - /// - /// - protected void ParseChildrenOfLoggerElement(XmlElement catElement, Logger log, bool isRoot) - { - // Remove all existing appenders from log. They will be - // reconstructed if need be. - log.RemoveAllAppenders(); - - foreach (XmlNode currentNode in catElement.ChildNodes) - { - if (currentNode.NodeType == XmlNodeType.Element) - { - XmlElement currentElement = (XmlElement)currentNode; - - if (currentElement.LocalName == APPENDER_REF_TAG) - { - IAppender appender = FindAppenderByReference(currentElement); - string refName = currentElement.GetAttribute(REF_ATTR); - if (appender != null) - { - LogLog.Debug(declaringType, "Adding appender named [" + refName + "] to logger [" + log.Name + "]."); - log.AddAppender(appender); - } - else - { - LogLog.Error(declaringType, "Appender named [" + refName + "] not found."); - } - } - else if (currentElement.LocalName == LEVEL_TAG || currentElement.LocalName == PRIORITY_TAG) - { - ParseLevel(currentElement, log, isRoot); - } - else - { - SetParameter(currentElement, log); - } - } - } - - IOptionHandler optionHandler = log as IOptionHandler; - if (optionHandler != null) - { - optionHandler.ActivateOptions(); - } - } - - /// - /// Parses an object renderer. - /// - /// The renderer element. - /// - /// - /// Parse an XML element that represents a renderer. - /// - /// - protected void ParseRenderer(XmlElement element) - { - string renderingClassName = element.GetAttribute(RENDERING_TYPE_ATTR); - string renderedClassName = element.GetAttribute(RENDERED_TYPE_ATTR); - - LogLog.Debug(declaringType, "Rendering class [" + renderingClassName + "], Rendered class [" + renderedClassName + "]."); - IObjectRenderer renderer = (IObjectRenderer)OptionConverter.InstantiateByClassName(renderingClassName, typeof(IObjectRenderer), null); - if (renderer == null) - { - LogLog.Error(declaringType, "Could not instantiate renderer [" + renderingClassName + "]."); - return; - } - else - { - try - { - m_hierarchy.RendererMap.Put(SystemInfo.GetTypeFromString(renderedClassName, true, true), renderer); - } - catch (Exception e) - { - LogLog.Error(declaringType, "Could not find class [" + renderedClassName + "].", e); - } - } - } - - /// - /// Parses a level element. - /// - /// The level element. - /// The logger object to set the level on. - /// Flag to indicate if the logger is the root logger. - /// - /// - /// Parse an XML element that represents a level. - /// - /// - protected void ParseLevel(XmlElement element, Logger log, bool isRoot) - { - string loggerName = log.Name; - if (isRoot) - { - loggerName = "root"; - } - - string levelStr = element.GetAttribute(VALUE_ATTR); - LogLog.Debug(declaringType, "Logger [" + loggerName + "] Level string is [" + levelStr + "]."); - - if (INHERITED == levelStr) - { - if (isRoot) - { - LogLog.Error(declaringType, "Root level cannot be inherited. Ignoring directive."); - } - else - { - LogLog.Debug(declaringType, "Logger [" + loggerName + "] level set to inherit from parent."); - log.Level = null; - } - } - else - { - log.Level = log.Hierarchy.LevelMap[levelStr]; - if (log.Level == null) - { - LogLog.Error(declaringType, "Undefined level [" + levelStr + "] on Logger [" + loggerName + "]."); - } - else - { - LogLog.Debug(declaringType, "Logger [" + loggerName + "] level set to [name=\"" + log.Level.Name + "\",value=" + log.Level.Value + "]."); - } - } - } - - /// - /// Sets a parameter on an object. - /// - /// The parameter element. - /// The object to set the parameter on. - /// - /// The parameter name must correspond to a writable property - /// on the object. The value of the parameter is a string, - /// therefore this function will attempt to set a string - /// property first. If unable to set a string property it - /// will inspect the property and its argument type. It will - /// attempt to call a static method called Parse on the - /// type of the property. This method will take a single - /// string argument and return a value that can be used to - /// set the property. - /// - protected void SetParameter(XmlElement element, object target) - { - // Get the property name - string name = element.GetAttribute(NAME_ATTR); - - // If the name attribute does not exist then use the name of the element - if (element.LocalName != PARAM_TAG || name == null || name.Length == 0) - { - name = element.LocalName; - } - - // Look for the property on the target object - Type targetType = target.GetType(); - Type propertyType = null; - - PropertyInfo propInfo = null; - MethodInfo methInfo = null; - - // Try to find a writable property - propInfo = targetType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase); - if (propInfo != null && propInfo.CanWrite) - { - // found a property - propertyType = propInfo.PropertyType; - } - else - { - propInfo = null; - - // look for a method with the signature Add(type) - methInfo = FindMethodInfo(targetType, name); - - if (methInfo != null) - { - propertyType = methInfo.GetParameters()[0].ParameterType; - } - } - - if (propertyType == null) - { - LogLog.Error(declaringType, "XmlHierarchyConfigurator: Cannot find Property [" + name + "] to set object on [" + target.ToString() + "]"); - } - else - { - string propertyValue = null; - - if (element.GetAttributeNode(VALUE_ATTR) != null) - { - propertyValue = element.GetAttribute(VALUE_ATTR); - } - else if (element.HasChildNodes) - { - // Concatenate the CDATA and Text nodes together - foreach (XmlNode childNode in element.ChildNodes) - { - if (childNode.NodeType == XmlNodeType.CDATA || childNode.NodeType == XmlNodeType.Text) - { - if (propertyValue == null) - { - propertyValue = childNode.InnerText; - } - else - { - propertyValue += childNode.InnerText; - } - } - } - } - - if (propertyValue != null) - { -#if !NETCF - try - { - // Expand environment variables in the string. - IDictionary environmentVariables = Environment.GetEnvironmentVariables(); - if (HasCaseInsensitiveEnvironment) - { - environmentVariables = CreateCaseInsensitiveWrapper(environmentVariables); - } - propertyValue = OptionConverter.SubstituteVariables(propertyValue, environmentVariables); - } - catch (System.Security.SecurityException) - { - // This security exception will occur if the caller does not have - // unrestricted environment permission. If this occurs the expansion - // will be skipped with the following warning message. - LogLog.Debug(declaringType, "Security exception while trying to expand environment variables. Error Ignored. No Expansion."); - } -#endif - - Type parsedObjectConversionTargetType = null; - - // Check if a specific subtype is specified on the element using the 'type' attribute - string subTypeString = element.GetAttribute(TYPE_ATTR); - if (subTypeString != null && subTypeString.Length > 0) - { - // Read the explicit subtype - try - { - Type subType = SystemInfo.GetTypeFromString(subTypeString, true, true); - - LogLog.Debug(declaringType, "Parameter [" + name + "] specified subtype [" + subType.FullName + "]"); - - if (!propertyType.IsAssignableFrom(subType)) - { - // Check if there is an appropriate type converter - if (OptionConverter.CanConvertTypeTo(subType, propertyType)) - { - // Must re-convert to the real property type - parsedObjectConversionTargetType = propertyType; - - // Use sub type as intermediary type - propertyType = subType; - } - else - { - LogLog.Error(declaringType, "subtype [" + subType.FullName + "] set on [" + name + "] is not a subclass of property type [" + propertyType.FullName + "] and there are no acceptable type conversions."); - } - } - else - { - // The subtype specified is found and is actually a subtype of the property - // type, therefore we can switch to using this type. - propertyType = subType; - } - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Failed to find type [" + subTypeString + "] set on [" + name + "]", ex); - } - } - - // Now try to convert the string value to an acceptable type - // to pass to this property. - - object convertedValue = ConvertStringTo(propertyType, propertyValue); - - // Check if we need to do an additional conversion - if (convertedValue != null && parsedObjectConversionTargetType != null) - { - LogLog.Debug(declaringType, "Performing additional conversion of value from [" + convertedValue.GetType().Name + "] to [" + parsedObjectConversionTargetType.Name + "]"); - convertedValue = OptionConverter.ConvertTypeTo(convertedValue, parsedObjectConversionTargetType); - } - - if (convertedValue != null) - { - if (propInfo != null) - { - // Got a converted result - LogLog.Debug(declaringType, "Setting Property [" + propInfo.Name + "] to " + convertedValue.GetType().Name + " value [" + convertedValue.ToString() + "]"); - - try - { - // Pass to the property - propInfo.SetValue(target, convertedValue, BindingFlags.SetProperty, null, null, CultureInfo.InvariantCulture); - } - catch (TargetInvocationException targetInvocationEx) - { - LogLog.Error(declaringType, "Failed to set parameter [" + propInfo.Name + "] on object [" + target + "] using value [" + convertedValue + "]", targetInvocationEx.InnerException); - } - } - else if (methInfo != null) - { - // Got a converted result - LogLog.Debug(declaringType, "Setting Collection Property [" + methInfo.Name + "] to " + convertedValue.GetType().Name + " value [" + convertedValue.ToString() + "]"); - - try - { - // Pass to the property - methInfo.Invoke(target, BindingFlags.InvokeMethod, null, new object[] { convertedValue }, CultureInfo.InvariantCulture); - } - catch (TargetInvocationException targetInvocationEx) - { - LogLog.Error(declaringType, "Failed to set parameter [" + name + "] on object [" + target + "] using value [" + convertedValue + "]", targetInvocationEx.InnerException); - } - } - } - else - { - LogLog.Warn(declaringType, "Unable to set property [" + name + "] on object [" + target + "] using value [" + propertyValue + "] (with acceptable conversion types)"); - } - } - else - { - object createdObject = null; - - if (propertyType == typeof(string) && !HasAttributesOrElements(element)) - { - // If the property is a string and the element is empty (no attributes - // or child elements) then we special case the object value to an empty string. - // This is necessary because while the String is a class it does not have - // a default constructor that creates an empty string, which is the behavior - // we are trying to simulate and would be expected from CreateObjectFromXml - createdObject = ""; - } - else - { - // No value specified - Type defaultObjectType = null; - if (IsTypeConstructible(propertyType)) - { - defaultObjectType = propertyType; - } - - createdObject = CreateObjectFromXml(element, defaultObjectType, propertyType); - } - - if (createdObject == null) - { - LogLog.Error(declaringType, "Failed to create object to set param: " + name); - } - else - { - if (propInfo != null) - { - // Got a converted result - LogLog.Debug(declaringType, "Setting Property [" + propInfo.Name + "] to object [" + createdObject + "]"); - - try - { - // Pass to the property - propInfo.SetValue(target, createdObject, BindingFlags.SetProperty, null, null, CultureInfo.InvariantCulture); - } - catch (TargetInvocationException targetInvocationEx) - { - LogLog.Error(declaringType, "Failed to set parameter [" + propInfo.Name + "] on object [" + target + "] using value [" + createdObject + "]", targetInvocationEx.InnerException); - } - } - else if (methInfo != null) - { - // Got a converted result - LogLog.Debug(declaringType, "Setting Collection Property [" + methInfo.Name + "] to object [" + createdObject + "]"); - - try - { - // Pass to the property - methInfo.Invoke(target, BindingFlags.InvokeMethod, null, new object[] { createdObject }, CultureInfo.InvariantCulture); - } - catch (TargetInvocationException targetInvocationEx) - { - LogLog.Error(declaringType, "Failed to set parameter [" + methInfo.Name + "] on object [" + target + "] using value [" + createdObject + "]", targetInvocationEx.InnerException); - } - } - } - } - } - } - - /// - /// Test if an element has no attributes or child elements - /// - /// the element to inspect - /// true if the element has any attributes or child elements, false otherwise - private bool HasAttributesOrElements(XmlElement element) - { - foreach (XmlNode node in element.ChildNodes) - { - if (node.NodeType == XmlNodeType.Attribute || node.NodeType == XmlNodeType.Element) - { - return true; - } - } - return false; - } - - /// - /// Test if a is constructible with Activator.CreateInstance. - /// - /// the type to inspect - /// true if the type is creatable using a default constructor, false otherwise - private static bool IsTypeConstructible(Type type) - { - if (type.IsClass && !type.IsAbstract) - { - ConstructorInfo defaultConstructor = type.GetConstructor(new Type[0]); - if (defaultConstructor != null && !defaultConstructor.IsAbstract && !defaultConstructor.IsPrivate) - { - return true; - } - } - return false; - } - - /// - /// Look for a method on the that matches the supplied - /// - /// the type that has the method - /// the name of the method - /// the method info found - /// - /// - /// The method must be a public instance method on the . - /// The method must be named or "Add" followed by . - /// The method must take a single parameter. - /// - /// - private MethodInfo FindMethodInfo(Type targetType, string name) - { - string requiredMethodNameA = name; - string requiredMethodNameB = "Add" + name; - - MethodInfo[] methods = targetType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - - foreach (MethodInfo methInfo in methods) - { - if (!methInfo.IsStatic) - { - if (string.Compare(methInfo.Name, requiredMethodNameA, true, System.Globalization.CultureInfo.InvariantCulture) == 0 || - string.Compare(methInfo.Name, requiredMethodNameB, true, System.Globalization.CultureInfo.InvariantCulture) == 0) - { - // Found matching method name - - // Look for version with one arg only - System.Reflection.ParameterInfo[] methParams = methInfo.GetParameters(); - if (methParams.Length == 1) - { - return methInfo; - } - } - } - } - return null; - } - - /// - /// Converts a string value to a target type. - /// - /// The type of object to convert the string to. - /// The string value to use as the value of the object. - /// - /// - /// An object of type with value or - /// null when the conversion could not be performed. - /// - /// - protected object ConvertStringTo(Type type, string value) - { - // Hack to allow use of Level in property - if (typeof(Level) == type) - { - // Property wants a level - Level levelValue = m_hierarchy.LevelMap[value]; - - if (levelValue == null) - { - LogLog.Error(declaringType, "XmlHierarchyConfigurator: Unknown Level Specified [" + value + "]"); - } - - return levelValue; - } - return OptionConverter.ConvertStringTo(type, value); - } - - /// - /// Creates an object as specified in XML. - /// - /// The XML element that contains the definition of the object. - /// The object type to use if not explicitly specified. - /// The type that the returned object must be or must inherit from. - /// The object or null - /// - /// - /// Parse an XML element and create an object instance based on the configuration - /// data. - /// - /// - /// The type of the instance may be specified in the XML. If not - /// specified then the is used - /// as the type. However the type is specified it must support the - /// type. - /// - /// - protected object CreateObjectFromXml(XmlElement element, Type defaultTargetType, Type typeConstraint) - { - Type objectType = null; - - // Get the object type - string objectTypeString = element.GetAttribute(TYPE_ATTR); - if (objectTypeString == null || objectTypeString.Length == 0) - { - if (defaultTargetType == null) - { - LogLog.Error(declaringType, "Object type not specified. Cannot create object of type [" + typeConstraint.FullName + "]. Missing Value or Type."); - return null; - } - else - { - // Use the default object type - objectType = defaultTargetType; - } - } - else - { - // Read the explicit object type - try - { - objectType = SystemInfo.GetTypeFromString(objectTypeString, true, true); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Failed to find type [" + objectTypeString + "]", ex); - return null; - } - } - - bool requiresConversion = false; - - // Got the object type. Check that it meets the typeConstraint - if (typeConstraint != null) - { - if (!typeConstraint.IsAssignableFrom(objectType)) - { - // Check if there is an appropriate type converter - if (OptionConverter.CanConvertTypeTo(objectType, typeConstraint)) - { - requiresConversion = true; - } - else - { - LogLog.Error(declaringType, "Object type [" + objectType.FullName + "] is not assignable to type [" + typeConstraint.FullName + "]. There are no acceptable type conversions."); - return null; - } - } - } - - // Create using the default constructor - object createdObject = null; - try - { - createdObject = Activator.CreateInstance(objectType); - } - catch (Exception createInstanceEx) - { - LogLog.Error(declaringType, "XmlHierarchyConfigurator: Failed to construct object of type [" + objectType.FullName + "] Exception: " + createInstanceEx.ToString()); - } - - // Set any params on object - foreach (XmlNode currentNode in element.ChildNodes) - { - if (currentNode.NodeType == XmlNodeType.Element) - { - SetParameter((XmlElement)currentNode, createdObject); - } - } - - // Check if we need to call ActivateOptions - IOptionHandler optionHandler = createdObject as IOptionHandler; - if (optionHandler != null) - { - optionHandler.ActivateOptions(); - } - - // Ok object should be initialized - - if (requiresConversion) - { - // Convert the object type - return OptionConverter.ConvertTypeTo(createdObject, typeConstraint); - } - else - { - // The object is of the correct type - return createdObject; - } - } - - #endregion Protected Instance Methods - -#if !NETCF - private bool HasCaseInsensitiveEnvironment - { - get - { - PlatformID platform = Environment.OSVersion.Platform; - return platform != PlatformID.Unix && platform != PlatformID.MacOSX; - } - } - - private IDictionary CreateCaseInsensitiveWrapper(IDictionary dict) - { - if (dict == null) - { - return dict; - } - Hashtable hash = SystemInfo.CreateCaseInsensitiveHashtable(); - foreach (DictionaryEntry entry in dict) - { - hash[entry.Key] = entry.Value; - } - return hash; - } -#endif - - #region Private Constants - - // String constants used while parsing the XML data - private const string CONFIGURATION_TAG = "log4net"; - private const string RENDERER_TAG = "renderer"; - private const string APPENDER_TAG = "appender"; - private const string APPENDER_REF_TAG = "appender-ref"; - private const string PARAM_TAG = "param"; - - // TODO: Deprecate use of category tags - private const string CATEGORY_TAG = "category"; - // TODO: Deprecate use of priority tag - private const string PRIORITY_TAG = "priority"; - - private const string LOGGER_TAG = "logger"; - private const string NAME_ATTR = "name"; - private const string TYPE_ATTR = "type"; - private const string VALUE_ATTR = "value"; - private const string ROOT_TAG = "root"; - private const string LEVEL_TAG = "level"; - private const string REF_ATTR = "ref"; - private const string ADDITIVITY_ATTR = "additivity"; - private const string THRESHOLD_ATTR = "threshold"; - private const string CONFIG_DEBUG_ATTR = "configDebug"; - private const string INTERNAL_DEBUG_ATTR = "debug"; - private const string EMIT_INTERNAL_DEBUG_ATTR = "emitDebug"; - private const string CONFIG_UPDATE_MODE_ATTR = "update"; - private const string RENDERING_TYPE_ATTR = "renderingClass"; - private const string RENDERED_TYPE_ATTR = "renderedClass"; - - // flag used on the level element - private const string INHERITED = "inherited"; - - #endregion Private Constants - - #region Private Instance Fields - - /// - /// key: appenderName, value: appender. - /// - private Hashtable m_appenderBag; - - /// - /// The Hierarchy being configured. - /// - private readonly Hierarchy m_hierarchy; - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the XmlHierarchyConfigurator class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(XmlHierarchyConfigurator); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Repository/IBasicRepositoryConfigurator.cs b/src/log4net/Repository/IBasicRepositoryConfigurator.cs deleted file mode 100644 index 7fdbb70c..00000000 --- a/src/log4net/Repository/IBasicRepositoryConfigurator.cs +++ /dev/null @@ -1,63 +0,0 @@ -#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 - -namespace log4net.Repository -{ - /// - /// Basic Configurator interface for repositories - /// - /// - /// - /// Interface used by basic configurator to configure a - /// with a default . - /// - /// - /// A should implement this interface to support - /// configuration by the . - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IBasicRepositoryConfigurator - { - /// - /// Initialize the repository using the specified appender - /// - /// the appender to use to log all logging events - /// - /// - /// Configure the repository to route all logging events to the - /// specified appender. - /// - /// - void Configure(Appender.IAppender appender); - - /// - /// Initialize the repository using the specified appenders - /// - /// the appenders to use to log all logging events - /// - /// - /// Configure the repository to route all logging events to the - /// specified appenders. - /// - /// - void Configure(params Appender.IAppender[] appenders); - } -} diff --git a/src/log4net/Repository/ILoggerRepository.cs b/src/log4net/Repository/ILoggerRepository.cs deleted file mode 100644 index 30ef5b33..00000000 --- a/src/log4net/Repository/ILoggerRepository.cs +++ /dev/null @@ -1,349 +0,0 @@ -#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 System.Collections; -using log4net; -using log4net.ObjectRenderer; -using log4net.Core; -using log4net.Plugin; -using log4net.Repository.Hierarchy; -using log4net.Util; - -namespace log4net.Repository -{ - #region LoggerRepositoryShutdownEvent - - /// - /// Delegate used to handle logger repository shutdown event notifications - /// - /// The that is shutting down. - /// Empty event args - /// - /// - /// Delegate used to handle logger repository shutdown event notifications. - /// - /// - public delegate void LoggerRepositoryShutdownEventHandler(object sender, EventArgs e); - - #endregion - - #region LoggerRepositoryConfigurationResetEventHandler - - /// - /// Delegate used to handle logger repository configuration reset event notifications - /// - /// The that has had its configuration reset. - /// Empty event args - /// - /// - /// Delegate used to handle logger repository configuration reset event notifications. - /// - /// - public delegate void LoggerRepositoryConfigurationResetEventHandler(object sender, EventArgs e); - - #endregion - - #region LoggerRepositoryConfigurationChangedEventHandler - - /// - /// Delegate used to handle event notifications for logger repository configuration changes. - /// - /// The that has had its configuration changed. - /// Empty event arguments. - /// - /// - /// Delegate used to handle event notifications for logger repository configuration changes. - /// - /// - public delegate void LoggerRepositoryConfigurationChangedEventHandler(object sender, EventArgs e); - - #endregion - - /// - /// Interface implemented by logger repositories. - /// - /// - /// - /// This interface is implemented by logger repositories. e.g. - /// . - /// - /// - /// This interface is used by the - /// to obtain interfaces. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface ILoggerRepository - { - /// - /// The name of the repository - /// - /// - /// The name of the repository - /// - /// - /// - /// The name of the repository. - /// - /// - string Name { get; set; } - - /// - /// RendererMap accesses the object renderer map for this repository. - /// - /// - /// RendererMap accesses the object renderer map for this repository. - /// - /// - /// - /// RendererMap accesses the object renderer map for this repository. - /// - /// - /// The RendererMap holds a mapping between types and - /// objects. - /// - /// - RendererMap RendererMap { get; } - - /// - /// The plugin map for this repository. - /// - /// - /// The plugin map for this repository. - /// - /// - /// - /// The plugin map holds the instances - /// that have been attached to this repository. - /// - /// - PluginMap PluginMap { get; } - - /// - /// Get the level map for the Repository. - /// - /// - /// - /// Get the level map for the Repository. - /// - /// - /// The level map defines the mappings between - /// level names and objects in - /// this repository. - /// - /// - LevelMap LevelMap { get; } - - /// - /// The threshold for all events in this repository - /// - /// - /// The threshold for all events in this repository - /// - /// - /// - /// The threshold for all events in this repository. - /// - /// - Level Threshold { get; set; } - - /// - /// Check if the named logger exists in the repository. If so return - /// its reference, otherwise returns null. - /// - /// The name of the logger to lookup - /// The Logger object with the name specified - /// - /// - /// If the names logger exists it is returned, otherwise - /// null is returned. - /// - /// - ILogger Exists(string name); - - /// - /// Returns all the currently defined loggers as an Array. - /// - /// All the defined loggers - /// - /// - /// Returns all the currently defined loggers as an Array. - /// - /// - ILogger[] GetCurrentLoggers(); - - /// - /// Returns a named logger instance - /// - /// The name of the logger to retrieve - /// The logger object with the name specified - /// - /// - /// Returns a named logger instance. - /// - /// - /// If a logger of that name already exists, then it will be - /// returned. Otherwise, a new logger will be instantiated and - /// then linked with its existing ancestors as well as children. - /// - /// - ILogger GetLogger(string name); - - /// Shutdown the repository - /// - /// - /// Shutting down a repository will safely close and remove - /// all appenders in all loggers including the root logger. - /// - /// - /// Some appenders need to be closed before the - /// application exists. Otherwise, pending logging events might be - /// lost. - /// - /// - /// The method is careful to close nested - /// appenders before closing regular appenders. This is allows - /// configurations where a regular appender is attached to a logger - /// and again to a nested appender. - /// - /// - void Shutdown(); - - /// - /// Reset the repositories configuration to a default state - /// - /// - /// - /// Reset all values contained in this instance to their - /// default state. - /// - /// - /// Existing loggers are not removed. They are just reset. - /// - /// - /// This method should be used sparingly and with care as it will - /// block all logging until it is completed. - /// - /// - void ResetConfiguration(); - - /// - /// Log the through this repository. - /// - /// the event to log - /// - /// - /// This method should not normally be used to log. - /// The interface should be used - /// for routine logging. This interface can be obtained - /// using the method. - /// - /// - /// The logEvent is delivered to the appropriate logger and - /// that logger is then responsible for logging the event. - /// - /// - void Log(LoggingEvent logEvent); - - /// - /// Flag indicates if this repository has been configured. - /// - /// - /// Flag indicates if this repository has been configured. - /// - /// - /// - /// Flag indicates if this repository has been configured. - /// - /// - bool Configured { get; set; } - - /// - /// Collection of internal messages captured during the most - /// recent configuration process. - /// - ICollection ConfigurationMessages { get; set; } - - /// - /// Event to notify that the repository has been shutdown. - /// - /// - /// Event to notify that the repository has been shutdown. - /// - /// - /// - /// Event raised when the repository has been shutdown. - /// - /// - event LoggerRepositoryShutdownEventHandler ShutdownEvent; - - /// - /// Event to notify that the repository has had its configuration reset. - /// - /// - /// Event to notify that the repository has had its configuration reset. - /// - /// - /// - /// Event raised when the repository's configuration has been - /// reset to default. - /// - /// - event LoggerRepositoryConfigurationResetEventHandler ConfigurationReset; - - /// - /// Event to notify that the repository has had its configuration changed. - /// - /// - /// Event to notify that the repository has had its configuration changed. - /// - /// - /// - /// Event raised when the repository's configuration has been changed. - /// - /// - event LoggerRepositoryConfigurationChangedEventHandler ConfigurationChanged; - - /// - /// Repository specific properties - /// - /// - /// Repository specific properties - /// - /// - /// - /// These properties can be specified on a repository specific basis. - /// - /// - PropertiesDictionary Properties { get; } - - /// - /// Returns all the Appenders that are configured as an Array. - /// - /// All the Appenders - /// - /// - /// Returns all the Appenders that are configured as an Array. - /// - /// - log4net.Appender.IAppender[] GetAppenders(); - } -} diff --git a/src/log4net/Repository/IXmlRepositoryConfigurator.cs b/src/log4net/Repository/IXmlRepositoryConfigurator.cs deleted file mode 100644 index 6fd657c0..00000000 --- a/src/log4net/Repository/IXmlRepositoryConfigurator.cs +++ /dev/null @@ -1,54 +0,0 @@ -#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 System.Collections; -using log4net.Util; - -namespace log4net.Repository -{ - /// - /// Configure repository using XML - /// - /// - /// - /// Interface used by Xml configurator to configure a . - /// - /// - /// A should implement this interface to support - /// configuration by the . - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IXmlRepositoryConfigurator - { - /// - /// Initialize the repository using the specified config - /// - /// the element containing the root of the config - /// - /// - /// The schema for the XML configuration data is defined by - /// the implementation. - /// - /// - void Configure(System.Xml.XmlElement element); - } -} diff --git a/src/log4net/Repository/LoggerRepositorySkeleton.cs b/src/log4net/Repository/LoggerRepositorySkeleton.cs deleted file mode 100644 index d5663315..00000000 --- a/src/log4net/Repository/LoggerRepositorySkeleton.cs +++ /dev/null @@ -1,577 +0,0 @@ -#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 System.Collections; -using log4net.ObjectRenderer; -using log4net.Core; -using log4net.Util; -using log4net.Plugin; - -namespace log4net.Repository -{ - /// - /// Base implementation of - /// - /// - /// - /// Default abstract implementation of the interface. - /// - /// - /// Skeleton implementation of the interface. - /// All types can extend this type. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public abstract class LoggerRepositorySkeleton : ILoggerRepository - { - #region Member Variables - - private string m_name; - private RendererMap m_rendererMap; - private PluginMap m_pluginMap; - private LevelMap m_levelMap; - private Level m_threshold; - private bool m_configured; - private ICollection m_configurationMessages; - private event LoggerRepositoryShutdownEventHandler m_shutdownEvent; - private event LoggerRepositoryConfigurationResetEventHandler m_configurationResetEvent; - private event LoggerRepositoryConfigurationChangedEventHandler m_configurationChangedEvent; - private PropertiesDictionary m_properties; - - #endregion - - #region Constructors - - /// - /// Default Constructor - /// - /// - /// - /// Initializes the repository with default (empty) properties. - /// - /// - protected LoggerRepositorySkeleton() : this(new PropertiesDictionary()) - { - } - - /// - /// Construct the repository using specific properties - /// - /// the properties to set for this repository - /// - /// - /// Initializes the repository with specified properties. - /// - /// - protected LoggerRepositorySkeleton(PropertiesDictionary properties) - { - m_properties = properties; - m_rendererMap = new RendererMap(); - m_pluginMap = new PluginMap(this); - m_levelMap = new LevelMap(); - m_configurationMessages = EmptyCollection.Instance; - m_configured = false; - - AddBuiltinLevels(); - - // Don't disable any levels by default. - m_threshold = Level.All; - } - - #endregion - - #region Implementation of ILoggerRepository - - /// - /// The name of the repository - /// - /// - /// The string name of the repository - /// - /// - /// - /// The name of this repository. The name is - /// used to store and lookup the repositories - /// stored by the . - /// - /// - virtual public string Name - { - get { return m_name; } - set { m_name = value; } - } - - /// - /// The threshold for all events in this repository - /// - /// - /// The threshold for all events in this repository - /// - /// - /// - /// The threshold for all events in this repository - /// - /// - virtual public Level Threshold - { - get { return m_threshold; } - set - { - if (value != null) - { - m_threshold = value; - } - else - { - // Must not set threshold to null - LogLog.Warn(declaringType, "LoggerRepositorySkeleton: Threshold cannot be set to null. Setting to ALL"); - m_threshold = Level.All; - } - } - } - - /// - /// RendererMap accesses the object renderer map for this repository. - /// - /// - /// RendererMap accesses the object renderer map for this repository. - /// - /// - /// - /// RendererMap accesses the object renderer map for this repository. - /// - /// - /// The RendererMap holds a mapping between types and - /// objects. - /// - /// - virtual public RendererMap RendererMap - { - get { return m_rendererMap; } - } - - /// - /// The plugin map for this repository. - /// - /// - /// The plugin map for this repository. - /// - /// - /// - /// The plugin map holds the instances - /// that have been attached to this repository. - /// - /// - virtual public PluginMap PluginMap - { - get { return m_pluginMap; } - } - - /// - /// Get the level map for the Repository. - /// - /// - /// - /// Get the level map for the Repository. - /// - /// - /// The level map defines the mappings between - /// level names and objects in - /// this repository. - /// - /// - virtual public LevelMap LevelMap - { - get { return m_levelMap; } - } - - /// - /// Test if logger exists - /// - /// The name of the logger to lookup - /// The Logger object with the name specified - /// - /// - /// Check if the named logger exists in the repository. If so return - /// its reference, otherwise returns null. - /// - /// - abstract public ILogger Exists(string name); - - /// - /// Returns all the currently defined loggers in the repository - /// - /// All the defined loggers - /// - /// - /// Returns all the currently defined loggers in the repository as an Array. - /// - /// - abstract public ILogger[] GetCurrentLoggers(); - - /// - /// Return a new logger instance - /// - /// The name of the logger to retrieve - /// The logger object with the name specified - /// - /// - /// Return a new logger instance. - /// - /// - /// If a logger of that name already exists, then it will be - /// returned. Otherwise, a new logger will be instantiated and - /// then linked with its existing ancestors as well as children. - /// - /// - abstract public ILogger GetLogger(string name); - - /// - /// Shutdown the repository - /// - /// - /// - /// Shutdown the repository. Can be overridden in a subclass. - /// This base class implementation notifies the - /// listeners and all attached plugins of the shutdown event. - /// - /// - virtual public void Shutdown() - { - // Shutdown attached plugins - foreach(IPlugin plugin in PluginMap.AllPlugins) - { - plugin.Shutdown(); - } - - // Notify listeners - OnShutdown(null); - } - - /// - /// Reset the repositories configuration to a default state - /// - /// - /// - /// Reset all values contained in this instance to their - /// default state. - /// - /// - /// Existing loggers are not removed. They are just reset. - /// - /// - /// This method should be used sparingly and with care as it will - /// block all logging until it is completed. - /// - /// - virtual public void ResetConfiguration() - { - // Clear internal data structures - m_rendererMap.Clear(); - m_levelMap.Clear(); - m_configurationMessages = EmptyCollection.Instance; - - // Add the predefined levels to the map - AddBuiltinLevels(); - - Configured = false; - - // Notify listeners - OnConfigurationReset(null); - } - - /// - /// Log the logEvent through this repository. - /// - /// the event to log - /// - /// - /// This method should not normally be used to log. - /// The interface should be used - /// for routine logging. This interface can be obtained - /// using the method. - /// - /// - /// The logEvent is delivered to the appropriate logger and - /// that logger is then responsible for logging the event. - /// - /// - abstract public void Log(LoggingEvent logEvent); - - /// - /// Flag indicates if this repository has been configured. - /// - /// - /// Flag indicates if this repository has been configured. - /// - /// - /// - /// Flag indicates if this repository has been configured. - /// - /// - virtual public bool Configured - { - get { return m_configured; } - set { m_configured = value; } - } - - /// - /// Contains a list of internal messages captures during the - /// last configuration. - /// - virtual public ICollection ConfigurationMessages - { - get { return m_configurationMessages; } - set { m_configurationMessages = value; } - } - - /// - /// Event to notify that the repository has been shutdown. - /// - /// - /// Event to notify that the repository has been shutdown. - /// - /// - /// - /// Event raised when the repository has been shutdown. - /// - /// - public event LoggerRepositoryShutdownEventHandler ShutdownEvent - { - add { m_shutdownEvent += value; } - remove { m_shutdownEvent -= value; } - } - - /// - /// Event to notify that the repository has had its configuration reset. - /// - /// - /// Event to notify that the repository has had its configuration reset. - /// - /// - /// - /// Event raised when the repository's configuration has been - /// reset to default. - /// - /// - public event LoggerRepositoryConfigurationResetEventHandler ConfigurationReset - { - add { m_configurationResetEvent += value; } - remove { m_configurationResetEvent -= value; } - } - - /// - /// Event to notify that the repository has had its configuration changed. - /// - /// - /// Event to notify that the repository has had its configuration changed. - /// - /// - /// - /// Event raised when the repository's configuration has been changed. - /// - /// - public event LoggerRepositoryConfigurationChangedEventHandler ConfigurationChanged - { - add { m_configurationChangedEvent += value; } - remove { m_configurationChangedEvent -= value; } - } - - /// - /// Repository specific properties - /// - /// - /// Repository specific properties - /// - /// - /// These properties can be specified on a repository specific basis - /// - public PropertiesDictionary Properties - { - get { return m_properties; } - } - - /// - /// Returns all the Appenders that are configured as an Array. - /// - /// All the Appenders - /// - /// - /// Returns all the Appenders that are configured as an Array. - /// - /// - abstract public log4net.Appender.IAppender[] GetAppenders(); - - #endregion - - #region Private Static Fields - - /// - /// The fully qualified type of the LoggerRepositorySkeleton class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(LoggerRepositorySkeleton); - - #endregion Private Static Fields - - private void AddBuiltinLevels() - { - // Add the predefined levels to the map - m_levelMap.Add(Level.Off); - - // Unrecoverable errors - m_levelMap.Add(Level.Emergency); - m_levelMap.Add(Level.Fatal); - m_levelMap.Add(Level.Alert); - - // Recoverable errors - m_levelMap.Add(Level.Critical); - m_levelMap.Add(Level.Severe); - m_levelMap.Add(Level.Error); - m_levelMap.Add(Level.Warn); - - // Information - m_levelMap.Add(Level.Notice); - m_levelMap.Add(Level.Info); - - // Debug - m_levelMap.Add(Level.Debug); - m_levelMap.Add(Level.Fine); - m_levelMap.Add(Level.Trace); - m_levelMap.Add(Level.Finer); - m_levelMap.Add(Level.Verbose); - m_levelMap.Add(Level.Finest); - - m_levelMap.Add(Level.All); - } - - /// - /// Adds an object renderer for a specific class. - /// - /// The type that will be rendered by the renderer supplied. - /// The object renderer used to render the object. - /// - /// - /// Adds an object renderer for a specific class. - /// - /// - virtual public void AddRenderer(Type typeToRender, IObjectRenderer rendererInstance) - { - if (typeToRender == null) - { - throw new ArgumentNullException("typeToRender"); - } - if (rendererInstance == null) - { - throw new ArgumentNullException("rendererInstance"); - } - - m_rendererMap.Put(typeToRender, rendererInstance); - } - - /// - /// Notify the registered listeners that the repository is shutting down - /// - /// Empty EventArgs - /// - /// - /// Notify any listeners that this repository is shutting down. - /// - /// - protected virtual void OnShutdown(EventArgs e) - { - if (e == null) - { - e = EventArgs.Empty; - } - - LoggerRepositoryShutdownEventHandler handler = m_shutdownEvent; - if (handler != null) - { - handler(this, e); - } - } - - /// - /// Notify the registered listeners that the repository has had its configuration reset - /// - /// Empty EventArgs - /// - /// - /// Notify any listeners that this repository's configuration has been reset. - /// - /// - protected virtual void OnConfigurationReset(EventArgs e) - { - if (e == null) - { - e = EventArgs.Empty; - } - - LoggerRepositoryConfigurationResetEventHandler handler = m_configurationResetEvent; - if (handler != null) - { - handler(this, e); - } - } - - /// - /// Notify the registered listeners that the repository has had its configuration changed - /// - /// Empty EventArgs - /// - /// - /// Notify any listeners that this repository's configuration has changed. - /// - /// - protected virtual void OnConfigurationChanged(EventArgs e) - { - if (e == null) - { - e = EventArgs.Empty; - } - - LoggerRepositoryConfigurationChangedEventHandler handler = m_configurationChangedEvent; - if (handler != null) - { - handler(this, e); - } - } - - /// - /// Raise a configuration changed event on this repository - /// - /// EventArgs.Empty - /// - /// - /// Applications that programmatically change the configuration of the repository should - /// raise this event notification to notify listeners. - /// - /// - public void RaiseConfigurationChanged(EventArgs e) - { - OnConfigurationChanged(e); - } - } -} diff --git a/src/log4net/ThreadContext.cs b/src/log4net/ThreadContext.cs deleted file mode 100644 index 9d668f7f..00000000 --- a/src/log4net/ThreadContext.cs +++ /dev/null @@ -1,139 +0,0 @@ -#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 System.Collections; - -using log4net.Util; - -namespace log4net -{ - /// - /// The log4net Thread Context. - /// - /// - /// - /// The ThreadContext provides a location for thread specific debugging - /// information to be stored. - /// The ThreadContext properties override any - /// properties with the same name. - /// - /// - /// The thread context has a properties map and a stack. - /// The properties and stack can - /// be included in the output of log messages. The - /// supports selecting and outputting these properties. - /// - /// - /// The Thread Context provides a diagnostic context for the current thread. - /// This is an instrument for distinguishing interleaved log - /// output from different sources. Log output is typically interleaved - /// when a server handles multiple clients near-simultaneously. - /// - /// - /// The Thread Context is managed on a per thread basis. - /// - /// - /// Example of using the thread context properties to store a username. - /// - /// ThreadContext.Properties["user"] = userName; - /// log.Info("This log message has a ThreadContext Property called 'user'"); - /// - /// - /// Example of how to push a message into the context stack - /// - /// using(ThreadContext.Stacks["NDC"].Push("my context message")) - /// { - /// log.Info("This log message has a ThreadContext Stack message that includes 'my context message'"); - /// - /// } // at the end of the using block the message is automatically popped - /// - /// - /// - /// Nicko Cadell - public sealed class ThreadContext - { - #region Private Instance Constructors - - /// - /// Private Constructor. - /// - /// - /// - /// Uses a private access modifier to prevent instantiation of this class. - /// - /// - private ThreadContext() - { - } - - #endregion Private Instance Constructors - - #region Public Static Properties - - /// - /// The thread properties map - /// - /// - /// The thread properties map - /// - /// - /// - /// The ThreadContext properties override any - /// properties with the same name. - /// - /// - public static ThreadContextProperties Properties - { - get { return s_properties; } - } - - /// - /// The thread stacks - /// - /// - /// stack map - /// - /// - /// - /// The thread local stacks. - /// - /// - public static ThreadContextStacks Stacks - { - get { return s_stacks; } - } - - #endregion Public Static Properties - - #region Private Static Fields - - /// - /// The thread context properties instance - /// - private readonly static ThreadContextProperties s_properties = new ThreadContextProperties(); - - /// - /// The thread context stacks instance - /// - private readonly static ThreadContextStacks s_stacks = new ThreadContextStacks(s_properties); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/AppenderAttachedImpl.cs b/src/log4net/Util/AppenderAttachedImpl.cs deleted file mode 100644 index fafb0b8f..00000000 --- a/src/log4net/Util/AppenderAttachedImpl.cs +++ /dev/null @@ -1,376 +0,0 @@ -#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 -{ - /// - /// A straightforward implementation of the interface. - /// - /// - /// - /// This is the default implementation of the - /// interface. Implementors of the interface - /// should aggregate an instance of this type. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class AppenderAttachedImpl : IAppenderAttachable - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public AppenderAttachedImpl() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Methods - - /// - /// Append on on all attached appenders. - /// - /// The event being logged. - /// The number of appenders called. - /// - /// - /// Calls the method on all - /// attached appenders. - /// - /// - 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; - } - - /// - /// Append on on all attached appenders. - /// - /// The array of events being logged. - /// The number of appenders called. - /// - /// - /// Calls the method on all - /// attached appenders. - /// - /// - 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 - - /// - /// Calls the DoAppende method on the with - /// the objects supplied. - /// - /// The appender - /// The events - /// - /// - /// If the supports the - /// interface then the will be passed - /// through using that interface. Otherwise the - /// objects in the array will be passed one at a time. - /// - /// - 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 - - /// - /// Attaches an appender. - /// - /// The appender to add. - /// - /// - /// If the appender is already in the list it won't be added again. - /// - /// - 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); - } - } - - /// - /// Gets all attached appenders. - /// - /// - /// A collection of attached appenders, or null if there - /// are no attached appenders. - /// - /// - /// - /// The read only collection of all currently attached appenders. - /// - /// - public AppenderCollection Appenders - { - get - { - if (m_appenderList == null) - { - // We must always return a valid collection - return AppenderCollection.EmptyCollection; - } - else - { - return AppenderCollection.ReadOnly(m_appenderList); - } - } - } - - /// - /// Gets an attached appender with the specified name. - /// - /// The name of the appender to get. - /// - /// The appender with the name specified, or null if no appender with the - /// specified name is found. - /// - /// - /// - /// Lookup an attached appender by name. - /// - /// - 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; - } - - /// - /// Removes all attached appenders. - /// - /// - /// - /// Removes and closes all attached appenders - /// - /// - 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; - } - } - - /// - /// Removes the specified appender from the list of attached appenders. - /// - /// The appender to remove. - /// The appender removed from the list - /// - /// - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - /// - 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; - } - - /// - /// Removes the appender with the specified name from the list of appenders. - /// - /// The name of the appender to remove. - /// The appender removed from the list - /// - /// - /// The appender removed is not closed. - /// If you are discarding the appender you must call - /// on the appender removed. - /// - /// - public IAppender RemoveAppender(string name) - { - return RemoveAppender(GetAppender(name)); - } - - #endregion - - #region Private Instance Fields - - /// - /// List of appenders - /// - private AppenderCollection m_appenderList; - - /// - /// Array of appenders, used to cache the m_appenderList - /// - private IAppender[] m_appenderArray; - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the AppenderAttachedImpl class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(AppenderAttachedImpl); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/CompositeProperties.cs b/src/log4net/Util/CompositeProperties.cs deleted file mode 100644 index b4911970..00000000 --- a/src/log4net/Util/CompositeProperties.cs +++ /dev/null @@ -1,155 +0,0 @@ -#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 System.Collections; - -namespace log4net.Util -{ - /// - /// This class aggregates several PropertiesDictionary collections together. - /// - /// - /// - /// Provides a dictionary style lookup over an ordered list of - /// collections. - /// - /// - /// Nicko Cadell - public sealed class CompositeProperties - { - #region Private Instance Fields - - private PropertiesDictionary m_flattened = null; - private ArrayList m_nestedProperties = new ArrayList(); - - #endregion Private Instance Fields - - #region Public Instance Constructors - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - internal CompositeProperties() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the value of a property - /// - /// - /// The value for the property with the specified key - /// - /// - /// - /// Looks up the value for the specified. - /// The collections are searched - /// in the order in which they were added to this collection. The value - /// returned is the value held by the first collection that contains - /// the specified key. - /// - /// - /// If none of the collections contain the specified key then - /// null is returned. - /// - /// - public object this[string key] - { - get - { - // Look in the flattened properties first - if (m_flattened != null) - { - return m_flattened[key]; - } - - // Look for the key in all the nested properties - foreach(ReadOnlyPropertiesDictionary cur in m_nestedProperties) - { - if (cur.Contains(key)) - { - return cur[key]; - } - } - return null; - } - } - - #endregion Public Instance Properties - - #region Public Instance Methods - - /// - /// Add a Properties Dictionary to this composite collection - /// - /// the properties to add - /// - /// - /// Properties dictionaries added first take precedence over dictionaries added - /// later. - /// - /// - public void Add(ReadOnlyPropertiesDictionary properties) - { - m_flattened = null; - m_nestedProperties.Add(properties); - } - - /// - /// Flatten this composite collection into a single properties dictionary - /// - /// the flattened dictionary - /// - /// - /// Reduces the collection of ordered dictionaries to a single dictionary - /// containing the resultant values for the keys. - /// - /// - public PropertiesDictionary Flatten() - { - if (m_flattened == null) - { - m_flattened = new PropertiesDictionary(); - - for(int i=m_nestedProperties.Count; --i>=0; ) - { - ReadOnlyPropertiesDictionary cur = (ReadOnlyPropertiesDictionary)m_nestedProperties[i]; - - foreach(DictionaryEntry entry in cur) - { - m_flattened[(string)entry.Key] = entry.Value; - } - } - } - return m_flattened; - } - - #endregion Public Instance Methods - } -} - diff --git a/src/log4net/Util/ContextPropertiesBase.cs b/src/log4net/Util/ContextPropertiesBase.cs deleted file mode 100644 index 9d79fee2..00000000 --- a/src/log4net/Util/ContextPropertiesBase.cs +++ /dev/null @@ -1,50 +0,0 @@ -#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 System.Collections; - -namespace log4net.Util -{ - /// - /// Base class for Context Properties implementations - /// - /// - /// - /// This class defines a basic property get set accessor - /// - /// - /// Nicko Cadell - public abstract class ContextPropertiesBase - { - /// - /// Gets or sets the value of a property - /// - /// - /// The value for the property with the specified key - /// - /// - /// - /// Gets or sets the value of a property - /// - /// - public abstract object this[string key] { get; set; } - } -} - diff --git a/src/log4net/Util/ConverterInfo.cs b/src/log4net/Util/ConverterInfo.cs deleted file mode 100644 index b64edc9d..00000000 --- a/src/log4net/Util/ConverterInfo.cs +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * 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; - -namespace log4net.Util -{ - /// - /// Wrapper class used to map converter names to converter types - /// - /// - /// - /// Pattern converter info class used during configuration by custom - /// PatternString and PatternLayer converters. - /// - /// - public sealed class ConverterInfo - { - private string m_name; - private Type m_type; - private readonly PropertiesDictionary properties = new PropertiesDictionary(); - - /// - /// default constructor - /// - public ConverterInfo() - { - } - - /// - /// Gets or sets the name of the conversion pattern - /// - /// - /// - /// The name of the pattern in the format string - /// - /// - public string Name - { - get { return m_name; } - set { m_name = value; } - } - - /// - /// Gets or sets the type of the converter - /// - /// - /// - /// The value specified must extend the - /// type. - /// - /// - public Type Type - { - get { return m_type; } - set { m_type = value; } - } - - /// - /// - /// - /// - public void AddProperty(PropertyEntry entry) - { - properties[entry.Key] = entry.Value; - } - - /// - /// - /// - public PropertiesDictionary Properties - { - get { return properties; } - } - } -} diff --git a/src/log4net/Util/CountingQuietTextWriter.cs b/src/log4net/Util/CountingQuietTextWriter.cs deleted file mode 100644 index aa2947ab..00000000 --- a/src/log4net/Util/CountingQuietTextWriter.cs +++ /dev/null @@ -1,180 +0,0 @@ -#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 System.IO; - -using log4net.Core; - -namespace log4net.Util -{ - /// - /// Subclass of that maintains a count of - /// the number of bytes written. - /// - /// - /// - /// This writer counts the number of bytes written. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class CountingQuietTextWriter : QuietTextWriter - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// The to actually write to. - /// The to report errors to. - /// - /// - /// Creates a new instance of the class - /// with the specified and . - /// - /// - public CountingQuietTextWriter(TextWriter writer, IErrorHandler errorHandler) : base(writer, errorHandler) - { - m_countBytes = 0; - } - - #endregion Public Instance Constructors - - #region Override implementation of QuietTextWriter - - /// - /// Writes a character to the underlying writer and counts the number of bytes written. - /// - /// the char to write - /// - /// - /// Overrides implementation of . Counts - /// the number of bytes written. - /// - /// - public override void Write(char value) - { - try - { - base.Write(value); - - // get the number of bytes needed to represent the - // char using the supplied encoding. - m_countBytes += this.Encoding.GetByteCount(new char[] { value }); - } - catch(Exception e) - { - this.ErrorHandler.Error("Failed to write [" + value + "].", e, ErrorCode.WriteFailure); - } - } - - /// - /// Writes a buffer to the underlying writer and counts the number of bytes written. - /// - /// the buffer to write - /// the start index to write from - /// the number of characters to write - /// - /// - /// Overrides implementation of . Counts - /// the number of bytes written. - /// - /// - public override void Write(char[] buffer, int index, int count) - { - if (count > 0) - { - try - { - base.Write(buffer, index, count); - - // get the number of bytes needed to represent the - // char array using the supplied encoding. - m_countBytes += this.Encoding.GetByteCount(buffer, index, count); - } - catch(Exception e) - { - this.ErrorHandler.Error("Failed to write buffer.", e, ErrorCode.WriteFailure); - } - } - } - - /// - /// Writes a string to the output and counts the number of bytes written. - /// - /// The string data to write to the output. - /// - /// - /// Overrides implementation of . Counts - /// the number of bytes written. - /// - /// - override public void Write(string str) - { - if (str != null && str.Length > 0) - { - try - { - base.Write(str); - - // get the number of bytes needed to represent the - // string using the supplied encoding. - m_countBytes += this.Encoding.GetByteCount(str); - } - catch(Exception e) - { - this.ErrorHandler.Error("Failed to write [" + str + "].", e, ErrorCode.WriteFailure); - } - } - } - - #endregion Override implementation of QuietTextWriter - - #region Public Instance Properties - - /// - /// Gets or sets the total number of bytes written. - /// - /// - /// The total number of bytes written. - /// - /// - /// - /// Gets or sets the total number of bytes written. - /// - /// - public long Count - { - get { return m_countBytes; } - set { m_countBytes = value; } - } - - #endregion Public Instance Properties - - #region Private Instance Fields - - /// - /// Total number of bytes written. - /// - private long m_countBytes; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Util/CyclicBuffer.cs b/src/log4net/Util/CyclicBuffer.cs deleted file mode 100644 index bc8c9024..00000000 --- a/src/log4net/Util/CyclicBuffer.cs +++ /dev/null @@ -1,355 +0,0 @@ -#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; - -namespace log4net.Util -{ - /// - /// A fixed size rolling buffer of logging events. - /// - /// - /// - /// An array backed fixed size leaky bucket. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class CyclicBuffer - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// The maximum number of logging events in the buffer. - /// - /// - /// Initializes a new instance of the class with - /// the specified maximum number of buffered logging events. - /// - /// - /// The argument is not a positive integer. - public CyclicBuffer(int maxSize) - { - if (maxSize < 1) - { - throw SystemInfo.CreateArgumentOutOfRangeException("maxSize", (object)maxSize, "Parameter: maxSize, Value: [" + maxSize + "] out of range. Non zero positive integer required"); - } - - m_maxSize = maxSize; - m_events = new LoggingEvent[maxSize]; - m_first = 0; - m_last = 0; - m_numElems = 0; - } - - #endregion Public Instance Constructors - - #region Public Instance Methods - - /// - /// Appends a to the buffer. - /// - /// The event to append to the buffer. - /// The event discarded from the buffer, if the buffer is full, otherwise null. - /// - /// - /// Append an event to the buffer. If the buffer still contains free space then - /// null is returned. If the buffer is full then an event will be dropped - /// to make space for the new event, the event dropped is returned. - /// - /// - public LoggingEvent Append(LoggingEvent loggingEvent) - { - if (loggingEvent == null) - { - throw new ArgumentNullException("loggingEvent"); - } - - lock(this) - { - // save the discarded event - LoggingEvent discardedLoggingEvent = m_events[m_last]; - - // overwrite the last event position - m_events[m_last] = loggingEvent; - if (++m_last == m_maxSize) - { - m_last = 0; - } - - if (m_numElems < m_maxSize) - { - m_numElems++; - } - else if (++m_first == m_maxSize) - { - m_first = 0; - } - - if (m_numElems < m_maxSize) - { - // Space remaining - return null; - } - else - { - // Buffer is full and discarding an event - return discardedLoggingEvent; - } - } - } - - /// - /// Get and remove the oldest event in the buffer. - /// - /// The oldest logging event in the buffer - /// - /// - /// Gets the oldest (first) logging event in the buffer and removes it - /// from the buffer. - /// - /// - public LoggingEvent PopOldest() - { - lock(this) - { - LoggingEvent ret = null; - if (m_numElems > 0) - { - m_numElems--; - ret = m_events[m_first]; - m_events[m_first] = null; - if (++m_first == m_maxSize) - { - m_first = 0; - } - } - return ret; - } - } - - /// - /// Pops all the logging events from the buffer into an array. - /// - /// An array of all the logging events in the buffer. - /// - /// - /// Get all the events in the buffer and clear the buffer. - /// - /// - public LoggingEvent[] PopAll() - { - lock(this) - { - LoggingEvent[] ret = new LoggingEvent[m_numElems]; - - if (m_numElems > 0) - { - if (m_first < m_last) - { - Array.Copy(m_events, m_first, ret, 0, m_numElems); - } - else - { - Array.Copy(m_events, m_first, ret, 0, m_maxSize - m_first); - Array.Copy(m_events, 0, ret, m_maxSize - m_first, m_last); - } - } - - Clear(); - - return ret; - } - } - - /// - /// Clear the buffer - /// - /// - /// - /// Clear the buffer of all events. The events in the buffer are lost. - /// - /// - public void Clear() - { - lock(this) - { - // Set all the elements to null - Array.Clear(m_events, 0, m_events.Length); - - m_first = 0; - m_last = 0; - m_numElems = 0; - } - } - -#if RESIZABLE_CYCLIC_BUFFER - /// - /// Resizes the cyclic buffer to . - /// - /// The new size of the buffer. - /// - /// - /// Resize the cyclic buffer. Events in the buffer are copied into - /// the newly sized buffer. If the buffer is shrunk and there are - /// more events currently in the buffer than the new size of the - /// buffer then the newest events will be dropped from the buffer. - /// - /// - /// The argument is not a positive integer. - public void Resize(int newSize) - { - lock(this) - { - if (newSize < 0) - { - throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("newSize", (object)newSize, "Parameter: newSize, Value: [" + newSize + "] out of range. Non zero positive integer required"); - } - if (newSize == m_numElems) - { - return; // nothing to do - } - - LoggingEvent[] temp = new LoggingEvent[newSize]; - - int loopLen = (newSize < m_numElems) ? newSize : m_numElems; - - for(int i = 0; i < loopLen; i++) - { - temp[i] = m_events[m_first]; - m_events[m_first] = null; - - if (++m_first == m_numElems) - { - m_first = 0; - } - } - - m_events = temp; - m_first = 0; - m_numElems = loopLen; - m_maxSize = newSize; - - if (loopLen == newSize) - { - m_last = 0; - } - else - { - m_last = loopLen; - } - } - } -#endif - - #endregion Public Instance Methods - - #region Public Instance Properties - - /// - /// Gets the th oldest event currently in the buffer. - /// - /// The th oldest event currently in the buffer. - /// - /// - /// If is outside the range 0 to the number of events - /// currently in the buffer, then null is returned. - /// - /// - public LoggingEvent this[int i] - { - get - { - lock(this) - { - if (i < 0 || i >= m_numElems) - { - return null; - } - - return m_events[(m_first + i) % m_maxSize]; - } - } - } - - /// - /// Gets the maximum size of the buffer. - /// - /// The maximum size of the buffer. - /// - /// - /// Gets the maximum size of the buffer - /// - /// - public int MaxSize - { - get - { - lock(this) - { - return m_maxSize; - } - } -#if RESIZABLE_CYCLIC_BUFFER - set - { - /// Setting the MaxSize will cause the buffer to resize. - Resize(value); - } -#endif - } - - /// - /// Gets the number of logging events in the buffer. - /// - /// The number of logging events in the buffer. - /// - /// - /// This number is guaranteed to be in the range 0 to - /// (inclusive). - /// - /// - public int Length - { - get - { - lock(this) - { - return m_numElems; - } - } - } - - #endregion Public Instance Properties - - #region Private Instance Fields - - private LoggingEvent[] m_events; - private int m_first; - private int m_last; - private int m_numElems; - private int m_maxSize; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Util/EmptyCollection.cs b/src/log4net/Util/EmptyCollection.cs deleted file mode 100644 index ad5f1d87..00000000 --- a/src/log4net/Util/EmptyCollection.cs +++ /dev/null @@ -1,178 +0,0 @@ -#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 System.Collections; - -namespace log4net.Util -{ - /// - /// An always empty . - /// - /// - /// - /// A singleton implementation of the - /// interface that always represents an empty collection. - /// - /// - /// Nicko Cadell - /// Gert Driesen -#if !NETCF - [Serializable] -#endif - public sealed class EmptyCollection : ICollection - { - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Uses a private access modifier to enforce the singleton pattern. - /// - /// - private EmptyCollection() - { - } - - #endregion Private Instance Constructors - - #region Public Static Properties - - /// - /// Gets the singleton instance of the empty collection. - /// - /// The singleton instance of the empty collection. - /// - /// - /// Gets the singleton instance of the empty collection. - /// - /// - public static EmptyCollection Instance - { - get { return s_instance; } - } - - #endregion Public Static Properties - - #region Implementation of ICollection - - /// - /// Copies the elements of the to an - /// , starting at a particular Array index. - /// - /// The one-dimensional - /// that is the destination of the elements copied from - /// . The Array must have zero-based - /// indexing. - /// The zero-based index in array at which - /// copying begins. - /// - /// - /// As the collection is empty no values are copied into the array. - /// - /// - public void CopyTo(System.Array array, int index) - { - // copy nothing - } - - /// - /// Gets a value indicating if access to the is synchronized (thread-safe). - /// - /// - /// true if access to the is synchronized (thread-safe); otherwise, false. - /// - /// - /// - /// For the this property is always true. - /// - /// - public bool IsSynchronized - { - get { return true; } - } - - /// - /// Gets the number of elements contained in the . - /// - /// - /// The number of elements contained in the . - /// - /// - /// - /// As the collection is empty the is always 0. - /// - /// - public int Count - { - get { return 0; } - } - - /// - /// Gets an object that can be used to synchronize access to the . - /// - /// - /// An object that can be used to synchronize access to the . - /// - /// - /// - /// As the collection is empty and thread safe and synchronized this instance is also - /// the object. - /// - /// - public object SyncRoot - { - get { return this; } - } - - #endregion Implementation of ICollection - - #region Implementation of IEnumerable - - /// - /// Returns an enumerator that can iterate through a collection. - /// - /// - /// An that can be used to - /// iterate through the collection. - /// - /// - /// - /// As the collection is empty a is returned. - /// - /// - public IEnumerator GetEnumerator() - { - return NullEnumerator.Instance; - } - - #endregion Implementation of IEnumerable - - #region Private Static Fields - - /// - /// The singleton instance of the empty collection. - /// - private readonly static EmptyCollection s_instance = new EmptyCollection(); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/EmptyDictionary.cs b/src/log4net/Util/EmptyDictionary.cs deleted file mode 100644 index 2c9192da..00000000 --- a/src/log4net/Util/EmptyDictionary.cs +++ /dev/null @@ -1,339 +0,0 @@ -#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 System.Collections; - -namespace log4net.Util -{ - /// - /// An always empty . - /// - /// - /// - /// A singleton implementation of the - /// interface that always represents an empty collection. - /// - /// - /// Nicko Cadell - /// Gert Driesen -#if !NETCF - [Serializable] -#endif - public sealed class EmptyDictionary : IDictionary - { - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Uses a private access modifier to enforce the singleton pattern. - /// - /// - private EmptyDictionary() - { - } - - #endregion Private Instance Constructors - - #region Public Static Properties - - /// - /// Gets the singleton instance of the . - /// - /// The singleton instance of the . - /// - /// - /// Gets the singleton instance of the . - /// - /// - public static EmptyDictionary Instance - { - get { return s_instance; } - } - - #endregion Public Static Properties - - #region Implementation of ICollection - - /// - /// Copies the elements of the to an - /// , starting at a particular Array index. - /// - /// The one-dimensional - /// that is the destination of the elements copied from - /// . The Array must have zero-based - /// indexing. - /// The zero-based index in array at which - /// copying begins. - /// - /// - /// As the collection is empty no values are copied into the array. - /// - /// - public void CopyTo(System.Array array, int index) - { - // copy nothing - } - - /// - /// Gets a value indicating if access to the is synchronized (thread-safe). - /// - /// - /// true if access to the is synchronized (thread-safe); otherwise, false. - /// - /// - /// - /// For the this property is always true. - /// - /// - public bool IsSynchronized - { - get { return true; } - } - - /// - /// Gets the number of elements contained in the - /// - /// - /// The number of elements contained in the . - /// - /// - /// - /// As the collection is empty the is always 0. - /// - /// - public int Count - { - get { return 0; } - } - - /// - /// Gets an object that can be used to synchronize access to the . - /// - /// - /// An object that can be used to synchronize access to the . - /// - /// - /// - /// As the collection is empty and thread safe and synchronized this instance is also - /// the object. - /// - /// - public object SyncRoot - { - get { return this; } - } - - #endregion Implementation of ICollection - - #region Implementation of IEnumerable - - /// - /// Returns an enumerator that can iterate through a collection. - /// - /// - /// An that can be used to - /// iterate through the collection. - /// - /// - /// - /// As the collection is empty a is returned. - /// - /// - IEnumerator IEnumerable.GetEnumerator() - { - return NullEnumerator.Instance; - } - - #endregion Implementation of IEnumerable - - #region Implementation of IDictionary - - /// - /// Adds an element with the provided key and value to the - /// . - /// - /// The to use as the key of the element to add. - /// The to use as the value of the element to add. - /// - /// - /// As the collection is empty no new values can be added. A - /// is thrown if this method is called. - /// - /// - /// This dictionary is always empty and cannot be modified. - public void Add(object key, object value) - { - throw new InvalidOperationException(); - } - - /// - /// Removes all elements from the . - /// - /// - /// - /// As the collection is empty no values can be removed. A - /// is thrown if this method is called. - /// - /// - /// This dictionary is always empty and cannot be modified. - public void Clear() - { - throw new InvalidOperationException(); - } - - /// - /// Determines whether the contains an element - /// with the specified key. - /// - /// The key to locate in the . - /// false - /// - /// - /// As the collection is empty the method always returns false. - /// - /// - public bool Contains(object key) - { - return false; - } - - /// - /// Returns an enumerator that can iterate through a collection. - /// - /// - /// An that can be used to - /// iterate through the collection. - /// - /// - /// - /// As the collection is empty a is returned. - /// - /// - public IDictionaryEnumerator GetEnumerator() - { - return NullDictionaryEnumerator.Instance; - } - - /// - /// Removes the element with the specified key from the . - /// - /// The key of the element to remove. - /// - /// - /// As the collection is empty no values can be removed. A - /// is thrown if this method is called. - /// - /// - /// This dictionary is always empty and cannot be modified. - public void Remove(object key) - { - throw new InvalidOperationException(); - } - - /// - /// Gets a value indicating whether the has a fixed size. - /// - /// true - /// - /// - /// As the collection is empty always returns true. - /// - /// - public bool IsFixedSize - { - get { return true; } - } - - /// - /// Gets a value indicating whether the is read-only. - /// - /// true - /// - /// - /// As the collection is empty always returns true. - /// - /// - public bool IsReadOnly - { - get { return true; } - } - - /// - /// Gets an containing the keys of the . - /// - /// An containing the keys of the . - /// - /// - /// As the collection is empty a is returned. - /// - /// - public System.Collections.ICollection Keys - { - get { return EmptyCollection.Instance; } - } - - /// - /// Gets an containing the values of the . - /// - /// An containing the values of the . - /// - /// - /// As the collection is empty a is returned. - /// - /// - public System.Collections.ICollection Values - { - get { return EmptyCollection.Instance; } - } - - /// - /// Gets or sets the element with the specified key. - /// - /// The key of the element to get or set. - /// null - /// - /// - /// As the collection is empty no values can be looked up or stored. - /// If the index getter is called then null is returned. - /// A is thrown if the setter is called. - /// - /// - /// This dictionary is always empty and cannot be modified. - public object this[object key] - { - get { return null; } - set { throw new InvalidOperationException(); } - } - - #endregion Implementation of IDictionary - - #region Private Static Fields - - /// - /// The singleton instance of the empty dictionary. - /// - private readonly static EmptyDictionary s_instance = new EmptyDictionary(); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/FormattingInfo.cs b/src/log4net/Util/FormattingInfo.cs deleted file mode 100644 index 4a6c9bb9..00000000 --- a/src/log4net/Util/FormattingInfo.cs +++ /dev/null @@ -1,136 +0,0 @@ -#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.Util; - -namespace log4net.Util -{ - /// - /// Contain the information obtained when parsing formatting modifiers - /// in conversion modifiers. - /// - /// - /// - /// Holds the formatting information extracted from the format string by - /// the . This is used by the - /// objects when rendering the output. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class FormattingInfo - { - #region Public Instance Constructors - - /// - /// Defaut Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public FormattingInfo() - { - } - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class - /// with the specified parameters. - /// - /// - public FormattingInfo(int min, int max, bool leftAlign) - { - m_min = min; - m_max = max; - m_leftAlign = leftAlign; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the minimum value. - /// - /// - /// The minimum value. - /// - /// - /// - /// Gets or sets the minimum value. - /// - /// - public int Min - { - get { return m_min; } - set { m_min = value; } - } - - /// - /// Gets or sets the maximum value. - /// - /// - /// The maximum value. - /// - /// - /// - /// Gets or sets the maximum value. - /// - /// - public int Max - { - get { return m_max; } - set { m_max = value; } - } - - /// - /// Gets or sets a flag indicating whether left align is enabled - /// or not. - /// - /// - /// A flag indicating whether left align is enabled or not. - /// - /// - /// - /// Gets or sets a flag indicating whether left align is enabled or not. - /// - /// - public bool LeftAlign - { - get { return m_leftAlign; } - set { m_leftAlign = value; } - } - - #endregion Public Instance Properties - - #region Private Instance Fields - - private int m_min = -1; - private int m_max = int.MaxValue; - private bool m_leftAlign = false; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Util/GlobalContextProperties.cs b/src/log4net/Util/GlobalContextProperties.cs deleted file mode 100644 index b6431077..00000000 --- a/src/log4net/Util/GlobalContextProperties.cs +++ /dev/null @@ -1,177 +0,0 @@ -#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 System.Collections; - -namespace log4net.Util -{ - /// - /// Implementation of Properties collection for the - /// - /// - /// - /// This class implements a properties collection that is thread safe and supports both - /// storing properties and capturing a read only copy of the current propertied. - /// - /// - /// This class is optimized to the scenario where the properties are read frequently - /// and are modified infrequently. - /// - /// - /// Nicko Cadell - public sealed class GlobalContextProperties : ContextPropertiesBase - { - #region Private Instance Fields - - /// - /// The read only copy of the properties. - /// - /// - /// - /// This variable is declared volatile to prevent the compiler and JIT from - /// reordering reads and writes of this thread performed on different threads. - /// - /// -#if NETCF - private ReadOnlyPropertiesDictionary m_readOnlyProperties = new ReadOnlyPropertiesDictionary(); -#else - private volatile ReadOnlyPropertiesDictionary m_readOnlyProperties = new ReadOnlyPropertiesDictionary(); -#endif - - /// - /// Lock object used to synchronize updates within this instance - /// - private readonly object m_syncRoot = new object(); - - #endregion Private Instance Fields - - #region Public Instance Constructors - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - internal GlobalContextProperties() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the value of a property - /// - /// - /// The value for the property with the specified key - /// - /// - /// - /// Reading the value for a key is faster than setting the value. - /// When the value is written a new read only copy of - /// the properties is created. - /// - /// - override public object this[string key] - { - get - { - return m_readOnlyProperties[key]; - } - set - { - lock(m_syncRoot) - { - PropertiesDictionary mutableProps = new PropertiesDictionary(m_readOnlyProperties); - - mutableProps[key] = value; - - m_readOnlyProperties = new ReadOnlyPropertiesDictionary(mutableProps); - } - } - } - - #endregion Public Instance Properties - - #region Public Instance Methods - - /// - /// Remove a property from the global context - /// - /// the key for the entry to remove - /// - /// - /// Removing an entry from the global context properties is relatively expensive compared - /// with reading a value. - /// - /// - public void Remove(string key) - { - lock(m_syncRoot) - { - if (m_readOnlyProperties.Contains(key)) - { - PropertiesDictionary mutableProps = new PropertiesDictionary(m_readOnlyProperties); - - mutableProps.Remove(key); - - m_readOnlyProperties = new ReadOnlyPropertiesDictionary(mutableProps); - } - } - } - - /// - /// Clear the global context properties - /// - public void Clear() - { - lock(m_syncRoot) - { - m_readOnlyProperties = new ReadOnlyPropertiesDictionary(); - } - } - - #endregion Public Instance Methods - - #region Internal Instance Methods - - /// - /// Get a readonly immutable copy of the properties - /// - /// the current global context properties - /// - /// - /// This implementation is fast because the GlobalContextProperties class - /// stores a readonly copy of the properties. - /// - /// - internal ReadOnlyPropertiesDictionary GetReadOnlyProperties() - { - return m_readOnlyProperties; - } - - #endregion Internal Instance Methods - } -} - diff --git a/src/log4net/Util/ILogExtensions.cs b/src/log4net/Util/ILogExtensions.cs deleted file mode 100644 index b48b01f9..00000000 --- a/src/log4net/Util/ILogExtensions.cs +++ /dev/null @@ -1,2077 +0,0 @@ -#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 - -#if FRAMEWORK_3_5_OR_ABOVE - -using System; - -using log4net.Core; - -namespace log4net.Util -{ - /// - /// The static class ILogExtensions contains a set of widely used - /// methods that ease the interaction with the ILog interface implementations. - /// - /// - /// - /// This class contains methods for logging at different levels and checks the - /// properties for determining if those logging levels are enabled in the current - /// configuration. - /// - /// - /// Simple example of logging messages - /// - /// using log4net.Util; - /// - /// ILog log = LogManager.GetLogger("application-log"); - /// - /// log.InfoExt("Application Start"); - /// log.DebugExt("This is a debug message"); - /// - /// - public static class ILogExtensions - { - #region Private Static Fields - - /// - /// The fully qualified type of the Logger class. - /// - private readonly static Type declaringType = typeof(ILogExtensions); - - #endregion //Private Static Fields - - #region trace extensions - - #region trace extensions that uses log message lambda expression - - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// - /// - /// This method first checks if this logger is TRACE - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is TRACE enabled, then it converts - /// the message object (retrieved by invocation of the provided callback) to a - /// string by invoking the appropriate . - /// It then proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void TraceExt(this ILog logger, Func callback) - { - try - { - if (!logger.IsTraceEnabled) - return; - - logger.Trace(callback()); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void TraceExt(this ILog logger, Func callback, Exception exception) - { - try - { - if (!logger.IsTraceEnabled) - return; - - logger.Trace(callback(), exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region trace extension that use the formatter - - /// Log a message object with the level. //TODO - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// - /// - /// This method first checks if this logger is TRACE - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is TRACE enabled, then it converts - /// the message object (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void TraceExt(this ILog logger, object message) - { - try - { - if (!logger.IsTraceEnabled) - return; - - logger.Trace(message); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void TraceExt(this ILog logger, object message, Exception exception) - { - try - { - if (!logger.IsTraceEnabled) - return; - - logger.Trace(message, exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region trace extension that use string format - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void TraceFormatExt(this ILog logger, string format, object arg0) - { - try - { - if (!logger.IsTraceEnabled) - return; - - logger.TraceFormat(format, arg0); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void TraceFormatExt(this ILog logger, string format, params object[] args) - { - try - { - if (!logger.IsTraceEnabled) - return; - - logger.TraceFormat(format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void TraceFormatExt(this ILog logger, IFormatProvider provider, string format, params object[] args) - { - try - { - if (!logger.IsTraceEnabled) - return; - - logger.TraceFormat(provider, format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void TraceFormatExt(this ILog logger, string format, object arg0, object arg1) - { - try - { - if (!logger.IsTraceEnabled) - return; - - logger.TraceFormat(format, arg0, arg1); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void TraceFormatExt(this ILog logger, string format, object arg0, object arg1, object arg2) - { - try - { - if (!logger.IsTraceEnabled) - return; - - logger.TraceFormat(format, arg0, arg1, arg2); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #endregion - - #region debug extensions - - #region debug extensions that uses log message lambda expression - - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// - /// - /// This method first checks if this logger is INFO - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is INFO enabled, then it converts - /// the message object (retrieved by invocation of the provided callback) to a - /// string by invoking the appropriate . - /// It then proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void DebugExt(this ILog logger, Func callback) - { - try - { - if (!logger.IsDebugEnabled) - return; - - logger.Debug(callback()); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void DebugExt(this ILog logger, Func callback, Exception exception) - { - try - { - if (!logger.IsDebugEnabled) - return; - - logger.Debug(callback(), exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region debug extension that use the formatter - - /// Log a message object with the level. //TODO - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// - /// - /// This method first checks if this logger is INFO - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is INFO enabled, then it converts - /// the message object (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void DebugExt(this ILog logger, object message) - { - try - { - if (!logger.IsDebugEnabled) - return; - - logger.Debug(message); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void DebugExt(this ILog logger, object message, Exception exception) - { - try - { - if (!logger.IsDebugEnabled) - return; - - logger.Debug(message, exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region debug extension that use string format - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void DebugFormatExt(this ILog logger, string format, object arg0) - { - try - { - if (!logger.IsDebugEnabled) - return; - - logger.DebugFormat(format, arg0); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void DebugFormatExt(this ILog logger, string format, params object[] args) - { - try - { - if (!logger.IsDebugEnabled) - return; - - logger.DebugFormat(format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void DebugFormatExt(this ILog logger, IFormatProvider provider, string format, params object[] args) - { - try - { - if (!logger.IsDebugEnabled) - return; - - logger.DebugFormat(provider, format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void DebugFormatExt(this ILog logger, string format, object arg0, object arg1) - { - try - { - if (!logger.IsDebugEnabled) - return; - - logger.DebugFormat(format, arg0, arg1); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void DebugFormatExt(this ILog logger, string format, object arg0, object arg1, object arg2) - { - try - { - if (!logger.IsDebugEnabled) - return; - - logger.DebugFormat(format, arg0, arg1, arg2); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #endregion - - #region info extensions - - #region info extensions that uses log message lambda expression - - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// - /// - /// This method first checks if this logger is INFO - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is INFO enabled, then it converts - /// the message object (retrieved by invocation of the provided callback) to a - /// string by invoking the appropriate . - /// It then proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void InfoExt(this ILog logger, Func callback) - { - try - { - if (!logger.IsInfoEnabled) - return; - - logger.Info(callback()); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void InfoExt(this ILog logger, Func callback, Exception exception) - { - try - { - if (!logger.IsInfoEnabled) - return; - - logger.Info(callback(), exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region info extension that use the formatter - - /// Log a message object with the level. //TODO - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// - /// - /// This method first checks if this logger is INFO - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is INFO enabled, then it converts - /// the message object (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void InfoExt(this ILog logger, object message) - { - try - { - if (!logger.IsInfoEnabled) - return; - - logger.Info(message); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void InfoExt(this ILog logger, object message, Exception exception) - { - try - { - if (!logger.IsInfoEnabled) - return; - - logger.Info(message, exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region info extension that use string format - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void InfoFormatExt(this ILog logger, string format, object arg0) - { - try - { - if (!logger.IsInfoEnabled) - return; - - logger.InfoFormat(format, arg0); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void InfoFormatExt(this ILog logger, string format, params object[] args) - { - try - { - if (!logger.IsInfoEnabled) - return; - - logger.InfoFormat(format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void InfoFormatExt(this ILog logger, IFormatProvider provider, string format, params object[] args) - { - try - { - if (!logger.IsInfoEnabled) - return; - - logger.InfoFormat(provider, format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void InfoFormatExt(this ILog logger, string format, object arg0, object arg1) - { - try - { - if (!logger.IsInfoEnabled) - return; - - logger.InfoFormat(format, arg0, arg1); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void InfoFormatExt(this ILog logger, string format, object arg0, object arg1, object arg2) - { - try - { - if (!logger.IsInfoEnabled) - return; - - logger.InfoFormat(format, arg0, arg1, arg2); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #endregion - - #region warn extensions - - #region warn extensions that uses log message lambda expression - - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// - /// - /// This method first checks if this logger is WARN - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is WARN enabled, then it converts - /// the message object (retrieved by invocation of the provided callback) to a - /// string by invoking the appropriate . - /// It then proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void WarnExt(this ILog logger, Func callback) - { - try - { - if (!logger.IsWarnEnabled) - return; - - logger.Warn(callback()); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void WarnExt(this ILog logger, Func callback, Exception exception) - { - try - { - if (!logger.IsWarnEnabled) - return; - - logger.Warn(callback(), exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region warn extension that use the formatter - - /// Log a message object with the level. //TODO - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// - /// - /// This method first checks if this logger is WARN - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is WARN enabled, then it converts - /// the message object (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void WarnExt(this ILog logger, object message) - { - try - { - if (!logger.IsWarnEnabled) - return; - - logger.Warn(message); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void WarnExt(this ILog logger, object message, Exception exception) - { - try - { - if (!logger.IsWarnEnabled) - return; - - logger.Warn(message, exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region warn extension that use string format - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void WarnFormatExt(this ILog logger, string format, object arg0) - { - try - { - if (!logger.IsWarnEnabled) - return; - - logger.WarnFormat(format, arg0); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void WarnFormatExt(this ILog logger, string format, params object[] args) - { - try - { - if (!logger.IsWarnEnabled) - return; - - logger.WarnFormat(format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void WarnFormatExt(this ILog logger, IFormatProvider provider, string format, params object[] args) - { - try - { - if (!logger.IsWarnEnabled) - return; - - logger.WarnFormat(provider, format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void WarnFormatExt(this ILog logger, string format, object arg0, object arg1) - { - try - { - if (!logger.IsWarnEnabled) - return; - - logger.WarnFormat(format, arg0, arg1); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void WarnFormatExt(this ILog logger, string format, object arg0, object arg1, object arg2) - { - try - { - if (!logger.IsWarnEnabled) - return; - - logger.WarnFormat(format, arg0, arg1, arg2); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #endregion - - #region error extensions - - #region error extensions that uses log message lambda expression - - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// - /// - /// This method first checks if this logger is ERROR - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is ERROR enabled, then it converts - /// the message object (retrieved by invocation of the provided callback) to a - /// string by invoking the appropriate . - /// It then proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void ErrorExt(this ILog logger, Func callback) - { - try - { - if (!logger.IsErrorEnabled) - return; - - logger.Error(callback()); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void ErrorExt(this ILog logger, Func callback, Exception exception) - { - try - { - if (!logger.IsErrorEnabled) - return; - - logger.Error(callback(), exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region error extension that use the formatter - - /// Log a message object with the level. //TODO - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// - /// - /// This method first checks if this logger is ERROR - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is ERROR enabled, then it converts - /// the message object (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void ErrorExt(this ILog logger, object message) - { - try - { - if (!logger.IsErrorEnabled) - return; - - logger.Error(message); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void ErrorExt(this ILog logger, object message, Exception exception) - { - try - { - if (!logger.IsErrorEnabled) - return; - - logger.Error(message, exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region error extension that use string format - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void ErrorFormatExt(this ILog logger, string format, object arg0) - { - try - { - if (!logger.IsErrorEnabled) - return; - - logger.ErrorFormat(format, arg0); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void ErrorFormatExt(this ILog logger, string format, params object[] args) - { - try - { - if (!logger.IsErrorEnabled) - return; - - logger.ErrorFormat(format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void ErrorFormatExt(this ILog logger, IFormatProvider provider, string format, params object[] args) - { - try - { - if (!logger.IsErrorEnabled) - return; - - logger.ErrorFormat(provider, format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void ErrorFormatExt(this ILog logger, string format, object arg0, object arg1) - { - try - { - if (!logger.IsErrorEnabled) - return; - - logger.ErrorFormat(format, arg0, arg1); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void ErrorFormatExt(this ILog logger, string format, object arg0, object arg1, object arg2) - { - try - { - if (!logger.IsErrorEnabled) - return; - - logger.ErrorFormat(format, arg0, arg1, arg2); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #endregion - - #region fatal extensions - - #region fatal extensions that uses log message lambda expression - - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// - /// - /// This method first checks if this logger is FATAL - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is FATAL enabled, then it converts - /// the message object (retrieved by invocation of the provided callback) to a - /// string by invoking the appropriate . - /// It then proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void FatalExt(this ILog logger, Func callback) - { - try - { - if (!logger.IsFatalEnabled) - return; - - logger.Fatal(callback()); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The lambda expression that gets the object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void FatalExt(this ILog logger, Func callback, Exception exception) - { - try - { - if (!logger.IsFatalEnabled) - return; - - logger.Fatal(callback(), exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region fatal extension that use the formatter - - /// Log a message object with the level. //TODO - /// - /// Log a message object with the level. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// - /// - /// This method first checks if this logger is FATAL - /// enabled by reading the value property. - /// This check happens always and does not depend on the - /// implementation. If this logger is FATAL enabled, then it converts - /// the message object (passed as parameter) to a string by invoking the appropriate - /// . It then - /// proceeds to call all the registered appenders in this logger - /// and also higher in the hierarchy depending on the value of - /// the additivity flag. - /// - /// WARNING Note that passing an - /// to this method will print the name of the - /// but no stack trace. To print a stack trace use the - /// form instead. - /// - /// - /// - /// - public static void FatalExt(this ILog logger, object message) - { - try - { - if (!logger.IsFatalEnabled) - return; - - logger.Fatal(message); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Log a message object with the level including - /// the stack trace of the passed - /// as a parameter. - /// - /// The logger on which the message is logged. - /// The message object to log. - /// The exception to log, including its stack trace. - /// - /// - /// See the form for more detailed information. - /// - /// - /// - /// - public static void FatalExt(this ILog logger, object message, Exception exception) - { - try - { - if (!logger.IsFatalEnabled) - return; - - logger.Fatal(message, exception); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #region fatal extension that use string format - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void FatalFormatExt(this ILog logger, string format, object arg0) - { - try - { - if (!logger.IsFatalEnabled) - return; - - logger.FatalFormat(format, arg0); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void FatalFormatExt(this ILog logger, string format, params object[] args) - { - try - { - if (!logger.IsFatalEnabled) - return; - - logger.FatalFormat(format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// An that supplies culture-specific formatting information - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object array containing zero or more objects to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void FatalFormatExt(this ILog logger, IFormatProvider provider, string format, params object[] args) - { - try - { - if (!logger.IsFatalEnabled) - return; - - logger.FatalFormat(provider, format, args); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void FatalFormatExt(this ILog logger, string format, object arg0, object arg1) - { - try - { - if (!logger.IsFatalEnabled) - return; - - logger.FatalFormat(format, arg0, arg1); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - /// - /// Logs a formatted message string with the level. - /// - /// The logger on which the message is logged. - /// A String containing zero or more format items - /// An Object to format - /// An Object to format - /// An Object to format - /// - /// - /// The message is formatted using the String.Format method. See - /// for details of the syntax of the format string and the behavior - /// of the formatting. - /// - /// - /// This method does not take an object to include in the - /// log event. To pass an use one of the - /// methods instead. - /// - /// - /// - /// - public static void FatalFormatExt(this ILog logger, string format, object arg0, object arg1, object arg2) - { - try - { - if (!logger.IsFatalEnabled) - return; - - logger.FatalFormat(format, arg0, arg1, arg2); - } - catch (Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex); - } - } - - #endregion - - #endregion - } -} -#endif diff --git a/src/log4net/Util/LevelMapping.cs b/src/log4net/Util/LevelMapping.cs deleted file mode 100644 index a2d4afff..00000000 --- a/src/log4net/Util/LevelMapping.cs +++ /dev/null @@ -1,150 +0,0 @@ -#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 System.Collections; - -using log4net.Core; - -namespace log4net.Util -{ - /// - /// Manages a mapping from levels to - /// - /// - /// - /// Manages an ordered mapping from instances - /// to subclasses. - /// - /// - /// Nicko Cadell - public sealed class LevelMapping : IOptionHandler - { - #region Public Instance Constructors - - /// - /// Default constructor - /// - /// - /// - /// Initialise a new instance of . - /// - /// - public LevelMapping() - { - } - - #endregion // Public Instance Constructors - - #region Public Instance Methods - - /// - /// Add a to this mapping - /// - /// the entry to add - /// - /// - /// If a has previously been added - /// for the same then that entry will be - /// overwritten. - /// - /// - public void Add(LevelMappingEntry entry) - { - if (m_entriesMap.ContainsKey(entry.Level)) - { - m_entriesMap.Remove(entry.Level); - } - m_entriesMap.Add(entry.Level, entry); - } - - /// - /// Lookup the mapping for the specified level - /// - /// the level to lookup - /// the for the level or null if no mapping found - /// - /// - /// Lookup the value for the specified level. Finds the nearest - /// mapping value for the level that is equal to or less than the - /// specified. - /// - /// - /// If no mapping could be found then null is returned. - /// - /// - public LevelMappingEntry Lookup(Level level) - { - if (m_entries != null) - { - foreach(LevelMappingEntry entry in m_entries) - { - if (level >= entry.Level) - { - return entry; - } - } - } - return null; - } - - #endregion // Public Instance Methods - - #region IOptionHandler Members - - /// - /// Initialize options - /// - /// - /// - /// Caches the sorted list of in an array - /// - /// - public void ActivateOptions() - { - Level[] sortKeys = new Level[m_entriesMap.Count]; - LevelMappingEntry[] sortValues = new LevelMappingEntry[m_entriesMap.Count]; - - m_entriesMap.Keys.CopyTo(sortKeys, 0); - m_entriesMap.Values.CopyTo(sortValues, 0); - - // Sort in level order - Array.Sort(sortKeys, sortValues, 0, sortKeys.Length, null); - - // Reverse list so that highest level is first - Array.Reverse(sortValues, 0, sortValues.Length); - - foreach(LevelMappingEntry entry in sortValues) - { - entry.ActivateOptions(); - } - - m_entries = sortValues; - } - - #endregion // IOptionHandler Members - - #region Private Instance Fields - - private Hashtable m_entriesMap = new Hashtable(); - private LevelMappingEntry[] m_entries = null; - - #endregion // Private Instance Fields - } -} diff --git a/src/log4net/Util/LevelMappingEntry.cs b/src/log4net/Util/LevelMappingEntry.cs deleted file mode 100644 index bfed35b9..00000000 --- a/src/log4net/Util/LevelMappingEntry.cs +++ /dev/null @@ -1,100 +0,0 @@ -#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 System.Collections; - -using log4net.Core; - -namespace log4net.Util -{ - /// - /// An entry in the - /// - /// - /// - /// This is an abstract base class for types that are stored in the - /// object. - /// - /// - /// Nicko Cadell - public abstract class LevelMappingEntry : IOptionHandler - { - #region Public Instance Constructors - - /// - /// Default protected constructor - /// - /// - /// - /// Default protected constructor - /// - /// - protected LevelMappingEntry() - { - } - - #endregion // Public Instance Constructors - - #region Public Instance Properties - - /// - /// The level that is the key for this mapping - /// - /// - /// The that is the key for this mapping - /// - /// - /// - /// Get or set the that is the key for this - /// mapping subclass. - /// - /// - public Level Level - { - get { return m_level; } - set { m_level = value; } - } - - #endregion // Public Instance Properties - - #region IOptionHandler Members - - /// - /// Initialize any options defined on this entry - /// - /// - /// - /// Should be overridden by any classes that need to initialise based on their options - /// - /// - virtual public void ActivateOptions() - { - // default implementation is to do nothing - } - - #endregion // IOptionHandler Members - - #region Private Instance Fields - - private Level m_level; - - #endregion // Private Instance Fields - } -} diff --git a/src/log4net/Util/LogLog.cs b/src/log4net/Util/LogLog.cs deleted file mode 100644 index 4d6b1dd9..00000000 --- a/src/log4net/Util/LogLog.cs +++ /dev/null @@ -1,668 +0,0 @@ -#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 System.Collections; -using System.Configuration; -using System.Diagnostics; - -namespace log4net.Util -{ - /// - /// - /// - /// - /// - public delegate void LogReceivedEventHandler(object source, LogReceivedEventArgs e); - - /// - /// Outputs log statements from within the log4net assembly. - /// - /// - /// - /// Log4net components cannot make log4net logging calls. However, it is - /// sometimes useful for the user to learn about what log4net is - /// doing. - /// - /// - /// All log4net internal debug calls go to the standard output stream - /// whereas internal error messages are sent to the standard error output - /// stream. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class LogLog - { - /// - /// The event raised when an internal message has been received. - /// - public static event LogReceivedEventHandler LogReceived; - - private readonly Type source; - private readonly DateTime timeStamp; - private readonly string prefix; - private readonly string message; - private readonly Exception exception; - - /// - /// The Type that generated the internal message. - /// - public Type Source - { - get { return source; } - } - - /// - /// The DateTime stamp of when the internal message was received. - /// - public DateTime TimeStamp - { - get { return timeStamp; } - } - - /// - /// A string indicating the severity of the internal message. - /// - /// - /// "log4net: ", - /// "log4net:ERROR ", - /// "log4net:WARN " - /// - public string Prefix - { - get { return prefix; } - } - - /// - /// The internal log message. - /// - public string Message - { - get { return message; } - } - - /// - /// The Exception related to the message. - /// - /// - /// Optional. Will be null if no Exception was passed. - /// - public Exception Exception - { - get { return exception; } - } - - /// - /// Formats Prefix, Source, and Message in the same format as the value - /// sent to Console.Out and Trace.Write. - /// - /// - public override string ToString() - { - return Prefix + Source.Name + ": " + Message; - } - - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// - /// - public LogLog(Type source, string prefix, string message, Exception exception) - { - timeStamp = DateTime.Now; - - this.source = source; - this.prefix = prefix; - this.message = message; - this.exception = exception; - } - - #endregion Private Instance Constructors - - #region Static Constructor - - /// - /// Static constructor that initializes logging by reading - /// settings from the application configuration file. - /// - /// - /// - /// The log4net.Internal.Debug application setting - /// controls internal debugging. This setting should be set - /// to true to enable debugging. - /// - /// - /// The log4net.Internal.Quiet application setting - /// suppresses all internal logging including error messages. - /// This setting should be set to true to enable message - /// suppression. - /// - /// - static LogLog() - { -#if !NETCF - try - { - InternalDebugging = OptionConverter.ToBoolean(SystemInfo.GetAppSetting("log4net.Internal.Debug"), false); - QuietMode = OptionConverter.ToBoolean(SystemInfo.GetAppSetting("log4net.Internal.Quiet"), false); - EmitInternalMessages = OptionConverter.ToBoolean(SystemInfo.GetAppSetting("log4net.Internal.Emit"), true); - } - catch(Exception ex) - { - // If an exception is thrown here then it looks like the config file does not - // parse correctly. - // - // We will leave debug OFF and print an Error message - Error(typeof(LogLog), "Exception while reading ConfigurationSettings. Check your .config file is well formed XML.", ex); - } -#endif - } - - #endregion Static Constructor - - #region Public Static Properties - - /// - /// Gets or sets a value indicating whether log4net internal logging - /// is enabled or disabled. - /// - /// - /// true if log4net internal logging is enabled, otherwise - /// false. - /// - /// - /// - /// When set to true, internal debug level logging will be - /// displayed. - /// - /// - /// This value can be set by setting the application setting - /// log4net.Internal.Debug in the application configuration - /// file. - /// - /// - /// The default value is false, i.e. debugging is - /// disabled. - /// - /// - /// - /// - /// The following example enables internal debugging using the - /// application configuration file : - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static bool InternalDebugging - { - get { return s_debugEnabled; } - set { s_debugEnabled = value; } - } - - /// - /// Gets or sets a value indicating whether log4net should generate no output - /// from internal logging, not even for errors. - /// - /// - /// true if log4net should generate no output at all from internal - /// logging, otherwise false. - /// - /// - /// - /// When set to true will cause internal logging at all levels to be - /// suppressed. This means that no warning or error reports will be logged. - /// This option overrides the setting and - /// disables all debug also. - /// - /// This value can be set by setting the application setting - /// log4net.Internal.Quiet in the application configuration file. - /// - /// - /// The default value is false, i.e. internal logging is not - /// disabled. - /// - /// - /// - /// The following example disables internal logging using the - /// application configuration file : - /// - /// - /// - /// - /// - /// - /// - /// - public static bool QuietMode - { - get { return s_quietMode; } - set { s_quietMode = value; } - } - - /// - /// - /// - public static bool EmitInternalMessages - { - get { return s_emitInternalMessages; } - set { s_emitInternalMessages = value; } - } - - #endregion Public Static Properties - - #region Public Static Methods - - /// - /// Raises the LogReceived event when an internal messages is received. - /// - /// - /// - /// - /// - public static void OnLogReceived(Type source, string prefix, string message, Exception exception) - { - if (LogReceived != null) - { - LogReceived(null, new LogReceivedEventArgs(new LogLog(source, prefix, message, exception))); - } - } - - /// - /// Test if LogLog.Debug is enabled for output. - /// - /// - /// true if Debug is enabled - /// - /// - /// - /// Test if LogLog.Debug is enabled for output. - /// - /// - public static bool IsDebugEnabled - { - get { return s_debugEnabled && !s_quietMode; } - } - - /// - /// Writes log4net internal debug messages to the - /// standard output stream. - /// - /// - /// The message to log. - /// - /// - /// All internal debug messages are prepended with - /// the string "log4net: ". - /// - /// - public static void Debug(Type source, string message) - { - if (IsDebugEnabled) - { - if (EmitInternalMessages) - { - EmitOutLine(PREFIX + message); - } - - OnLogReceived(source, PREFIX, message, null); - } - } - - /// - /// Writes log4net internal debug messages to the - /// standard output stream. - /// - /// The Type that generated this message. - /// The message to log. - /// An exception to log. - /// - /// - /// All internal debug messages are prepended with - /// the string "log4net: ". - /// - /// - public static void Debug(Type source, string message, Exception exception) - { - if (IsDebugEnabled) - { - if (EmitInternalMessages) - { - EmitOutLine(PREFIX + message); - if (exception != null) - { - EmitOutLine(exception.ToString()); - } - } - - OnLogReceived(source, PREFIX, message, exception); - } - } - - /// - /// Test if LogLog.Warn is enabled for output. - /// - /// - /// true if Warn is enabled - /// - /// - /// - /// Test if LogLog.Warn is enabled for output. - /// - /// - public static bool IsWarnEnabled - { - get { return !s_quietMode; } - } - - /// - /// Writes log4net internal warning messages to the - /// standard error stream. - /// - /// The Type that generated this message. - /// The message to log. - /// - /// - /// All internal warning messages are prepended with - /// the string "log4net:WARN ". - /// - /// - public static void Warn(Type source, string message) - { - if (IsWarnEnabled) - { - if (EmitInternalMessages) - { - EmitErrorLine(WARN_PREFIX + message); - } - - OnLogReceived(source, WARN_PREFIX, message, null); - } - } - - /// - /// Writes log4net internal warning messages to the - /// standard error stream. - /// - /// The Type that generated this message. - /// The message to log. - /// An exception to log. - /// - /// - /// All internal warning messages are prepended with - /// the string "log4net:WARN ". - /// - /// - public static void Warn(Type source, string message, Exception exception) - { - if (IsWarnEnabled) - { - if (EmitInternalMessages) - { - EmitErrorLine(WARN_PREFIX + message); - if (exception != null) - { - EmitErrorLine(exception.ToString()); - } - } - - OnLogReceived(source, WARN_PREFIX, message, exception); - } - } - - /// - /// Test if LogLog.Error is enabled for output. - /// - /// - /// true if Error is enabled - /// - /// - /// - /// Test if LogLog.Error is enabled for output. - /// - /// - public static bool IsErrorEnabled - { - get { return !s_quietMode; } - } - - /// - /// Writes log4net internal error messages to the - /// standard error stream. - /// - /// The Type that generated this message. - /// The message to log. - /// - /// - /// All internal error messages are prepended with - /// the string "log4net:ERROR ". - /// - /// - public static void Error(Type source, string message) - { - if (IsErrorEnabled) - { - if (EmitInternalMessages) - { - EmitErrorLine(ERR_PREFIX + message); - } - - OnLogReceived(source, ERR_PREFIX, message, null); - } - } - - /// - /// Writes log4net internal error messages to the - /// standard error stream. - /// - /// The Type that generated this message. - /// The message to log. - /// An exception to log. - /// - /// - /// All internal debug messages are prepended with - /// the string "log4net:ERROR ". - /// - /// - public static void Error(Type source, string message, Exception exception) - { - if (IsErrorEnabled) - { - if (EmitInternalMessages) - { - EmitErrorLine(ERR_PREFIX + message); - if (exception != null) - { - EmitErrorLine(exception.ToString()); - } - } - - OnLogReceived(source, ERR_PREFIX, message, exception); - } - } - - #endregion Public Static Methods - - /// - /// Writes output to the standard output stream. - /// - /// The message to log. - /// - /// - /// Writes to both Console.Out and System.Diagnostics.Trace. - /// Note that the System.Diagnostics.Trace is not supported - /// on the Compact Framework. - /// - /// - /// If the AppDomain is not configured with a config file then - /// the call to System.Diagnostics.Trace may fail. This is only - /// an issue if you are programmatically creating your own AppDomains. - /// - /// - private static void EmitOutLine(string message) - { - try - { -#if NETCF - Console.WriteLine(message); - //System.Diagnostics.Debug.WriteLine(message); -#else - Console.Out.WriteLine(message); - Trace.WriteLine(message); -#endif - } - catch - { - // Ignore exception, what else can we do? Not really a good idea to propagate back to the caller - } - } - - /// - /// Writes output to the standard error stream. - /// - /// The message to log. - /// - /// - /// Writes to both Console.Error and System.Diagnostics.Trace. - /// Note that the System.Diagnostics.Trace is not supported - /// on the Compact Framework. - /// - /// - /// If the AppDomain is not configured with a config file then - /// the call to System.Diagnostics.Trace may fail. This is only - /// an issue if you are programmatically creating your own AppDomains. - /// - /// - private static void EmitErrorLine(string message) - { - try - { -#if NETCF - Console.WriteLine(message); - //System.Diagnostics.Debug.WriteLine(message); -#else - Console.Error.WriteLine(message); - Trace.WriteLine(message); -#endif - } - catch - { - // Ignore exception, what else can we do? Not really a good idea to propagate back to the caller - } - } - - #region Private Static Fields - - /// - /// Default debug level - /// - private static bool s_debugEnabled = false; - - /// - /// In quietMode not even errors generate any output. - /// - private static bool s_quietMode = false; - - private static bool s_emitInternalMessages = true; - - private const string PREFIX = "log4net: "; - private const string ERR_PREFIX = "log4net:ERROR "; - private const string WARN_PREFIX = "log4net:WARN "; - - #endregion Private Static Fields - - /// - /// Subscribes to the LogLog.LogReceived event and stores messages - /// to the supplied IList instance. - /// - public class LogReceivedAdapter : IDisposable - { - private readonly IList items; - private readonly LogReceivedEventHandler handler; - - /// - /// - /// - /// - public LogReceivedAdapter(IList items) - { - this.items = items; - - handler = new LogReceivedEventHandler(LogLog_LogReceived); - - LogReceived += handler; - } - - void LogLog_LogReceived(object source, LogReceivedEventArgs e) - { - items.Add(e.LogLog); - } - - /// - /// - /// - public IList Items - { - get { return items; } - } - - /// - /// - /// - public void Dispose() - { - LogReceived -= handler; - } - } - } - - /// - /// - /// - public class LogReceivedEventArgs : EventArgs - { - private readonly LogLog loglog; - - /// - /// - /// - /// - public LogReceivedEventArgs(LogLog loglog) - { - this.loglog = loglog; - } - - /// - /// - /// - public LogLog LogLog - { - get { return loglog; } - } - } -} diff --git a/src/log4net/Util/LogicalThreadContextProperties.cs b/src/log4net/Util/LogicalThreadContextProperties.cs deleted file mode 100644 index bc9e92f5..00000000 --- a/src/log4net/Util/LogicalThreadContextProperties.cs +++ /dev/null @@ -1,264 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for System.Runtime.Remoting.Messaging.CallContext -#if !NETCF - -using System; -using System.Runtime.Remoting.Messaging; -using System.Security; - -namespace log4net.Util -{ - /// - /// Implementation of Properties collection for the - /// - /// - /// - /// Class implements a collection of properties that is specific to each thread. - /// The class is not synchronized as each thread has its own . - /// - /// - /// This class stores its properties in a slot on the named - /// log4net.Util.LogicalThreadContextProperties. - /// - /// - /// The requires a link time - /// for the - /// . - /// If the calling code does not have this permission then this context will be disabled. - /// It will not store any property values set on it. - /// - /// - /// Nicko Cadell - public sealed class LogicalThreadContextProperties : ContextPropertiesBase - { - private const string c_SlotName = "log4net.Util.LogicalThreadContextProperties"; - - /// - /// Flag used to disable this context if we don't have permission to access the CallContext. - /// - private bool m_disabled = false; - - #region Public Instance Constructors - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - internal LogicalThreadContextProperties() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the value of a property - /// - /// - /// The value for the property with the specified key - /// - /// - /// - /// Get or set the property value for the specified. - /// - /// - override public object this[string key] - { - get - { - // Don't create the dictionary if it does not already exist - PropertiesDictionary dictionary = GetProperties(false); - if (dictionary != null) - { - return dictionary[key]; - } - return null; - } - set - { - // Force the dictionary to be created - PropertiesDictionary props = GetProperties(true); - // Reason for cloning the dictionary below: object instances set on the CallContext - // need to be immutable to correctly flow through async/await - PropertiesDictionary immutableProps = new PropertiesDictionary(props); - immutableProps[key] = value; - SetCallContextData(immutableProps); - } - } - - #endregion Public Instance Properties - - #region Public Instance Methods - - /// - /// Remove a property - /// - /// the key for the entry to remove - /// - /// - /// Remove the value for the specified from the context. - /// - /// - public void Remove(string key) - { - PropertiesDictionary dictionary = GetProperties(false); - if (dictionary != null) - { - PropertiesDictionary immutableProps = new PropertiesDictionary(dictionary); - immutableProps.Remove(key); - SetCallContextData(immutableProps); - } - } - - /// - /// Clear all the context properties - /// - /// - /// - /// Clear all the context properties - /// - /// - public void Clear() - { - PropertiesDictionary dictionary = GetProperties(false); - if (dictionary != null) - { - PropertiesDictionary immutableProps = new PropertiesDictionary(); - SetCallContextData(immutableProps); - } - } - - #endregion Public Instance Methods - - #region Internal Instance Methods - - /// - /// Get the PropertiesDictionary stored in the LocalDataStoreSlot for this thread. - /// - /// create the dictionary if it does not exist, otherwise return null if is does not exist - /// the properties for this thread - /// - /// - /// The collection returned is only to be used on the calling thread. If the - /// caller needs to share the collection between different threads then the - /// caller must clone the collection before doings so. - /// - /// - internal PropertiesDictionary GetProperties(bool create) - { - if (!m_disabled) - { - try - { - PropertiesDictionary properties = GetCallContextData(); - if (properties == null && create) - { - properties = new PropertiesDictionary(); - SetCallContextData(properties); - } - return properties; - } - catch (SecurityException secEx) - { - m_disabled = true; - - // Thrown if we don't have permission to read or write the CallContext - LogLog.Warn(declaringType, "SecurityException while accessing CallContext. Disabling LogicalThreadContextProperties", secEx); - } - } - - // Only get here is we are disabled because of a security exception - if (create) - { - return new PropertiesDictionary(); - } - return null; - } - - #endregion Internal Instance Methods - - #region Private Static Methods - - /// - /// Gets the call context get data. - /// - /// The peroperties dictionary stored in the call context - /// - /// The method has a - /// security link demand, therfore we must put the method call in a seperate method - /// that we can wrap in an exception handler. - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - private static PropertiesDictionary GetCallContextData() - { -#if !NETCF - return CallContext.LogicalGetData(c_SlotName) as PropertiesDictionary; -#else - return CallContext.GetData(c_SlotName) as PropertiesDictionary; -#endif - } - - /// - /// Sets the call context data. - /// - /// The properties. - /// - /// The method has a - /// security link demand, therfore we must put the method call in a seperate method - /// that we can wrap in an exception handler. - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - private static void SetCallContextData(PropertiesDictionary properties) - { -#if !NETCF - CallContext.LogicalSetData(c_SlotName, properties); -#else - CallContext.SetData(c_SlotName, properties); -#endif - } - - #endregion - - #region Private Static Fields - - /// - /// The fully qualified type of the LogicalThreadContextProperties class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(LogicalThreadContextProperties); - - #endregion Private Static Fields - } -} - -#endif diff --git a/src/log4net/Util/LogicalThreadContextStack.cs b/src/log4net/Util/LogicalThreadContextStack.cs deleted file mode 100644 index 16d74fd5..00000000 --- a/src/log4net/Util/LogicalThreadContextStack.cs +++ /dev/null @@ -1,415 +0,0 @@ -#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 System.Collections; - -using log4net.Core; - -namespace log4net.Util -{ - - /// - /// Delegate type used for LogicalThreadContextStack's callbacks. - /// - public delegate void TwoArgAction(T1 t1, T2 t2); - - /// - /// Implementation of Stack for the - /// - /// - /// - /// Implementation of Stack for the - /// - /// - /// Nicko Cadell - public sealed class LogicalThreadContextStack : IFixingRequired - { - #region Private Instance Fields - - /// - /// The stack store. - /// - private Stack m_stack = new Stack(); - - /// - /// The name of this within the - /// . - /// - private string m_propertyKey; - - /// - /// The callback used to let the register a - /// new instance of a . - /// - private TwoArgAction m_registerNew; - - #endregion Private Instance Fields - - #region Public Instance Constructors - - /// - /// Internal constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - internal LogicalThreadContextStack(string propertyKey, TwoArgAction registerNew) - { - m_propertyKey = propertyKey; - m_registerNew = registerNew; - } - - #endregion Public Instance Constructors - - #region Public Properties - - /// - /// The number of messages in the stack - /// - /// - /// The current number of messages in the stack - /// - /// - /// - /// The current number of messages in the stack. That is - /// the number of times has been called - /// minus the number of times has been called. - /// - /// - public int Count - { - get { return m_stack.Count; } - } - - #endregion // Public Properties - - #region Public Methods - - /// - /// Clears all the contextual information held in this stack. - /// - /// - /// - /// Clears all the contextual information held in this stack. - /// Only call this if you think that this thread is being reused after - /// a previous call execution which may not have completed correctly. - /// You do not need to use this method if you always guarantee to call - /// the method of the - /// returned from even in exceptional circumstances, - /// for example by using the using(log4net.LogicalThreadContext.Stacks["NDC"].Push("Stack_Message")) - /// syntax. - /// - /// - public void Clear() - { - m_registerNew(m_propertyKey, new LogicalThreadContextStack(m_propertyKey, m_registerNew)); - } - - /// - /// Removes the top context from this stack. - /// - /// The message in the context that was removed from the top of this stack. - /// - /// - /// Remove the top context from this stack, and return - /// it to the caller. If this stack is empty then an - /// empty string (not ) is returned. - /// - /// - public string Pop() - { - // copy current stack - Stack stack = new Stack(new Stack(m_stack)); - string result = ""; - if (stack.Count > 0) - { - result = ((StackFrame)(stack.Pop())).Message; - } - LogicalThreadContextStack ltcs = new LogicalThreadContextStack(m_propertyKey, m_registerNew); - ltcs.m_stack = stack; - m_registerNew(m_propertyKey, ltcs); - return result; - } - - /// - /// Pushes a new context message into this stack. - /// - /// The new context message. - /// - /// An that can be used to clean up the context stack. - /// - /// - /// - /// Pushes a new context onto this stack. An - /// is returned that can be used to clean up this stack. This - /// can be easily combined with the using keyword to scope the - /// context. - /// - /// - /// Simple example of using the Push method with the using keyword. - /// - /// using(log4net.LogicalThreadContext.Stacks["NDC"].Push("Stack_Message")) - /// { - /// log.Warn("This should have an ThreadContext Stack message"); - /// } - /// - /// - public IDisposable Push(string message) - { - // do modifications on a copy - Stack stack = new Stack(new Stack(m_stack)); - stack.Push(new StackFrame(message, (stack.Count > 0) ? (StackFrame)stack.Peek() : null)); - - LogicalThreadContextStack contextStack = new LogicalThreadContextStack(m_propertyKey, m_registerNew); - contextStack.m_stack = stack; - m_registerNew(m_propertyKey, contextStack); - return new AutoPopStackFrame(contextStack, stack.Count - 1); - } - - #endregion Public Methods - - #region Internal Methods - - /// - /// Gets the current context information for this stack. - /// - /// The current context information. - internal string GetFullMessage() - { - Stack stack = m_stack; - if (stack.Count > 0) - { - return ((StackFrame)(stack.Peek())).FullMessage; - } - return null; - } - - /// - /// Gets and sets the internal stack used by this - /// - /// The internal storage stack - /// - /// - /// This property is provided only to support backward compatability - /// of the . Tytpically the internal stack should not - /// be modified. - /// - /// - internal Stack InternalStack - { - get { return m_stack; } - set { m_stack = value; } - } - - #endregion Internal Methods - - /// - /// Gets the current context information for this stack. - /// - /// Gets the current context information - /// - /// - /// Gets the current context information for this stack. - /// - /// - public override string ToString() - { - return GetFullMessage(); - } - - /// - /// Get a portable version of this object - /// - /// the portable instance of this object - /// - /// - /// Get a cross thread portable version of this object - /// - /// - object IFixingRequired.GetFixedObject() - { - return GetFullMessage(); - } - - /// - /// Inner class used to represent a single context frame in the stack. - /// - /// - /// - /// Inner class used to represent a single context frame in the stack. - /// - /// - private sealed class StackFrame - { - #region Private Instance Fields - - private readonly string m_message; - private readonly StackFrame m_parent; - private string m_fullMessage = null; - - #endregion - - #region Internal Instance Constructors - - /// - /// Constructor - /// - /// The message for this context. - /// The parent context in the chain. - /// - /// - /// Initializes a new instance of the class - /// with the specified message and parent context. - /// - /// - internal StackFrame(string message, StackFrame parent) - { - m_message = message; - m_parent = parent; - - if (parent == null) - { - m_fullMessage = message; - } - } - - #endregion Internal Instance Constructors - - #region Internal Instance Properties - - /// - /// Get the message. - /// - /// The message. - /// - /// - /// Get the message. - /// - /// - internal string Message - { - get { return m_message; } - } - - /// - /// Gets the full text of the context down to the root level. - /// - /// - /// The full text of the context down to the root level. - /// - /// - /// - /// Gets the full text of the context down to the root level. - /// - /// - internal string FullMessage - { - get - { - if (m_fullMessage == null && m_parent != null) - { - m_fullMessage = string.Concat(m_parent.FullMessage, " ", m_message); - } - return m_fullMessage; - } - } - - #endregion Internal Instance Properties - } - - /// - /// Struct returned from the method. - /// - /// - /// - /// This struct implements the and is designed to be used - /// with the pattern to remove the stack frame at the end of the scope. - /// - /// - private struct AutoPopStackFrame : IDisposable - { - #region Private Instance Fields - - /// - /// The depth to trim the stack to when this instance is disposed - /// - private int m_frameDepth; - - /// - /// The outer LogicalThreadContextStack. - /// - private LogicalThreadContextStack m_logicalThreadContextStack; - - #endregion Private Instance Fields - - #region Internal Instance Constructors - - /// - /// Constructor - /// - /// The internal stack used by the ThreadContextStack. - /// The depth to return the stack to when this object is disposed. - /// - /// - /// Initializes a new instance of the class with - /// the specified stack and return depth. - /// - /// - internal AutoPopStackFrame(LogicalThreadContextStack logicalThreadContextStack, int frameDepth) - { - m_frameDepth = frameDepth; - m_logicalThreadContextStack = logicalThreadContextStack; - } - - #endregion Internal Instance Constructors - - #region Implementation of IDisposable - - /// - /// Returns the stack to the correct depth. - /// - /// - /// - /// Returns the stack to the correct depth. - /// - /// - public void Dispose() - { - if (m_frameDepth >= 0 && m_logicalThreadContextStack.m_stack != null) - { - Stack stack = new Stack(new Stack(m_logicalThreadContextStack.m_stack)); - while (stack.Count > m_frameDepth) - { - stack.Pop(); - } - LogicalThreadContextStack ltcs = new LogicalThreadContextStack(m_logicalThreadContextStack.m_propertyKey, m_logicalThreadContextStack.m_registerNew); - ltcs.m_stack = stack; - m_logicalThreadContextStack.m_registerNew(m_logicalThreadContextStack.m_propertyKey, - ltcs); - } - } - - #endregion Implementation of IDisposable - } - - } -} diff --git a/src/log4net/Util/LogicalThreadContextStacks.cs b/src/log4net/Util/LogicalThreadContextStacks.cs deleted file mode 100644 index 73f5e544..00000000 --- a/src/log4net/Util/LogicalThreadContextStacks.cs +++ /dev/null @@ -1,133 +0,0 @@ -#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 System.Collections; - -namespace log4net.Util -{ - /// - /// Implementation of Stacks collection for the - /// - /// - /// - /// Implementation of Stacks collection for the - /// - /// - /// Nicko Cadell - public sealed class LogicalThreadContextStacks - { - private readonly LogicalThreadContextProperties m_properties; - - #region Public Instance Constructors - - /// - /// Internal constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - internal LogicalThreadContextStacks(LogicalThreadContextProperties properties) - { - m_properties = properties; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the named thread context stack - /// - /// - /// The named stack - /// - /// - /// - /// Gets the named thread context stack - /// - /// - public LogicalThreadContextStack this[string key] - { - get - { - LogicalThreadContextStack stack = null; - - object propertyValue = m_properties[key]; - if (propertyValue == null) - { - // Stack does not exist, create - stack = new LogicalThreadContextStack(key, registerNew); - m_properties[key] = stack; - } - else - { - // Look for existing stack - stack = propertyValue as LogicalThreadContextStack; - if (stack == null) - { - // Property is not set to a stack! - string propertyValueString = SystemInfo.NullText; - - try - { - propertyValueString = propertyValue.ToString(); - } - catch - { - } - - LogLog.Error(declaringType, "ThreadContextStacks: Request for stack named [" + key + "] failed because a property with the same name exists which is a [" + propertyValue.GetType().Name + "] with value [" + propertyValueString + "]"); - - stack = new LogicalThreadContextStack(key, registerNew); - } - } - - return stack; - } - } - - #endregion Public Instance Properties - - #region Private Instance Fields - - private void registerNew(string stackName, LogicalThreadContextStack stack) - { - m_properties[stackName] = stack; - } - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the ThreadContextStacks class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(LogicalThreadContextStacks); - - #endregion Private Static Fields - } -} - diff --git a/src/log4net/Util/NativeError.cs b/src/log4net/Util/NativeError.cs deleted file mode 100644 index 7af305ec..00000000 --- a/src/log4net/Util/NativeError.cs +++ /dev/null @@ -1,279 +0,0 @@ -#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 System.Globalization; -using System.Runtime.InteropServices; - -namespace log4net.Util -{ - /// - /// Represents a native error code and message. - /// - /// - /// - /// Represents a Win32 platform native error. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class NativeError - { - #region Protected Instance Constructors - - /// - /// Create an instance of the class with the specified - /// error number and message. - /// - /// The number of the native error. - /// The message of the native error. - /// - /// - /// Create an instance of the class with the specified - /// error number and message. - /// - /// - private NativeError(int number, string message) - { - m_number = number; - m_message = message; - } - - #endregion // Protected Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the number of the native error. - /// - /// - /// The number of the native error. - /// - /// - /// - /// Gets the number of the native error. - /// - /// - public int Number - { - get { return m_number; } - } - - /// - /// Gets the message of the native error. - /// - /// - /// The message of the native error. - /// - /// - /// - /// - /// Gets the message of the native error. - /// - public string Message - { - get { return m_message; } - } - - #endregion // Public Instance Properties - - #region Public Static Methods - - /// - /// Create a new instance of the class for the last Windows error. - /// - /// - /// An instance of the class for the last windows error. - /// - /// - /// - /// The message for the error number is lookup up using the - /// native Win32 FormatMessage function. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#elif !NETCF - [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode=true)] -#endif - public static NativeError GetLastError() - { - int number = Marshal.GetLastWin32Error(); - return new NativeError(number, NativeError.GetErrorMessage(number)); - } - - /// - /// Create a new instance of the class. - /// - /// the error number for the native error - /// - /// An instance of the class for the specified - /// error number. - /// - /// - /// - /// The message for the specified error number is lookup up using the - /// native Win32 FormatMessage function. - /// - /// - public static NativeError GetError(int number) - { - return new NativeError(number, NativeError.GetErrorMessage(number)); - } - - /// - /// Retrieves the message corresponding with a Win32 message identifier. - /// - /// Message identifier for the requested message. - /// - /// The message corresponding with the specified message identifier. - /// - /// - /// - /// The message will be searched for in system message-table resource(s) - /// using the native FormatMessage function. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#elif !NETCF - [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] -#endif - public static string GetErrorMessage(int messageId) - { - // Win32 constants - int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; // The function should allocates a buffer large enough to hold the formatted message - int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; // Insert sequences in the message definition are to be ignored - int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; // The function should search the system message-table resource(s) for the requested message - - string msgBuf = ""; // buffer that will receive the message - IntPtr sourcePtr = new IntPtr(); // Location of the message definition, will be ignored - IntPtr argumentsPtr = new IntPtr(); // Pointer to array of values to insert, not supported as it requires unsafe code - - if (messageId != 0) - { - // If the function succeeds, the return value is the number of TCHARs stored in the output buffer, excluding the terminating null character - int messageSize = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - ref sourcePtr, - messageId, - 0, - ref msgBuf, - 255, - argumentsPtr); - - if (messageSize > 0) - { - // Remove trailing null-terminating characters (\r\n) from the message - msgBuf = msgBuf.TrimEnd(new char[] {'\r', '\n'}); - } - else - { - // A message could not be located. - msgBuf = null; - } - } - else - { - msgBuf = null; - } - - return msgBuf; - } - - #endregion // Public Static Methods - - #region Override Object Implementation - - /// - /// Return error information string - /// - /// error information string - /// - /// - /// Return error information string - /// - /// - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "0x{0:x8}", this.Number) + (this.Message != null ? ": " + this.Message : ""); - } - - #endregion // Override Object Implementation - - #region Stubs For Native Function Calls - - /// - /// Formats a message string. - /// - /// Formatting options, and how to interpret the parameter. - /// Location of the message definition. - /// Message identifier for the requested message. - /// Language identifier for the requested message. - /// If includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer using the LocalAlloc function, and places the pointer to the buffer at the address specified in . - /// If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the maximum number of TCHARs that can be stored in the output buffer. If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of TCHARs to allocate for an output buffer. - /// Pointer to an array of values that are used as insert values in the formatted message. - /// - /// - /// The function requires a message definition as input. The message definition can come from a - /// buffer passed into the function. It can come from a message table resource in an - /// already-loaded module. Or the caller can ask the function to search the system's message - /// table resource(s) for the message definition. The function finds the message definition - /// in a message table resource based on a message identifier and a language identifier. - /// The function copies the formatted message text to an output buffer, processing any embedded - /// insert sequences if requested. - /// - /// - /// To prevent the usage of unsafe code, this stub does not support inserting values in the formatted message. - /// - /// - /// - /// - /// If the function succeeds, the return value is the number of TCHARs stored in the output - /// buffer, excluding the terminating null character. - /// - /// - /// If the function fails, the return value is zero. To get extended error information, - /// call . - /// - /// -#if NETCF - [DllImport("CoreDll.dll", SetLastError=true, CharSet=CharSet.Unicode)] -#else - [DllImport("Kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] -#endif - private static extern int FormatMessage( - int dwFlags, - ref IntPtr lpSource, - int dwMessageId, - int dwLanguageId, - ref String lpBuffer, - int nSize, - IntPtr Arguments); - - #endregion // Stubs For Native Function Calls - - #region Private Instance Fields - - private int m_number; - private string m_message; - - #endregion - } -} diff --git a/src/log4net/Util/NullDictionaryEnumerator.cs b/src/log4net/Util/NullDictionaryEnumerator.cs deleted file mode 100644 index e4564c8a..00000000 --- a/src/log4net/Util/NullDictionaryEnumerator.cs +++ /dev/null @@ -1,202 +0,0 @@ -#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 System.Collections; - -namespace log4net.Util -{ - /// - /// An always empty . - /// - /// - /// - /// A singleton implementation of the over a collection - /// that is empty and not modifiable. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class NullDictionaryEnumerator : IDictionaryEnumerator - { - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Uses a private access modifier to enforce the singleton pattern. - /// - /// - private NullDictionaryEnumerator() - { - } - - #endregion Private Instance Constructors - - #region Public Static Properties - - /// - /// Gets the singleton instance of the . - /// - /// The singleton instance of the . - /// - /// - /// Gets the singleton instance of the . - /// - /// - public static NullDictionaryEnumerator Instance - { - get { return s_instance; } - } - - #endregion Public Static Properties - - #region Implementation of IEnumerator - - /// - /// Gets the current object from the enumerator. - /// - /// - /// Throws an because the - /// never has a current value. - /// - /// - /// - /// As the enumerator is over an empty collection its - /// value cannot be moved over a valid position, therefore - /// will throw an . - /// - /// - /// The collection is empty and - /// cannot be positioned over a valid location. - public object Current - { - get { throw new InvalidOperationException(); } - } - - /// - /// Test if the enumerator can advance, if so advance. - /// - /// false as the cannot advance. - /// - /// - /// As the enumerator is over an empty collection its - /// value cannot be moved over a valid position, therefore - /// will always return false. - /// - /// - public bool MoveNext() - { - return false; - } - - /// - /// Resets the enumerator back to the start. - /// - /// - /// - /// As the enumerator is over an empty collection does nothing. - /// - /// - public void Reset() - { - } - - #endregion Implementation of IEnumerator - - #region Implementation of IDictionaryEnumerator - - /// - /// Gets the current key from the enumerator. - /// - /// - /// Throws an exception because the - /// never has a current value. - /// - /// - /// - /// As the enumerator is over an empty collection its - /// value cannot be moved over a valid position, therefore - /// will throw an . - /// - /// - /// The collection is empty and - /// cannot be positioned over a valid location. - public object Key - { - get { throw new InvalidOperationException(); } - } - - /// - /// Gets the current value from the enumerator. - /// - /// The current value from the enumerator. - /// - /// Throws an because the - /// never has a current value. - /// - /// - /// - /// As the enumerator is over an empty collection its - /// value cannot be moved over a valid position, therefore - /// will throw an . - /// - /// - /// The collection is empty and - /// cannot be positioned over a valid location. - public object Value - { - get { throw new InvalidOperationException(); } - } - - /// - /// Gets the current entry from the enumerator. - /// - /// - /// Throws an because the - /// never has a current entry. - /// - /// - /// - /// As the enumerator is over an empty collection its - /// value cannot be moved over a valid position, therefore - /// will throw an . - /// - /// - /// The collection is empty and - /// cannot be positioned over a valid location. - public DictionaryEntry Entry - { - get { throw new InvalidOperationException(); } - } - - #endregion Implementation of IDictionaryEnumerator - - #region Private Static Fields - - /// - /// The singleton instance of the . - /// - private readonly static NullDictionaryEnumerator s_instance = new NullDictionaryEnumerator(); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/NullEnumerator.cs b/src/log4net/Util/NullEnumerator.cs deleted file mode 100644 index 614d616b..00000000 --- a/src/log4net/Util/NullEnumerator.cs +++ /dev/null @@ -1,134 +0,0 @@ -#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 System.Collections; - -namespace log4net.Util -{ - /// - /// An always empty . - /// - /// - /// - /// A singleton implementation of the over a collection - /// that is empty and not modifiable. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class NullEnumerator : IEnumerator - { - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Uses a private access modifier to enforce the singleton pattern. - /// - /// - private NullEnumerator() - { - } - - #endregion Private Instance Constructors - - #region Public Static Properties - - /// - /// Get the singleton instance of the . - /// - /// The singleton instance of the . - /// - /// - /// Gets the singleton instance of the . - /// - /// - public static NullEnumerator Instance - { - get { return s_instance; } - } - - #endregion Public Static Properties - - #region Implementation of IEnumerator - - /// - /// Gets the current object from the enumerator. - /// - /// - /// Throws an because the - /// never has a current value. - /// - /// - /// - /// As the enumerator is over an empty collection its - /// value cannot be moved over a valid position, therefore - /// will throw an . - /// - /// - /// The collection is empty and - /// cannot be positioned over a valid location. - public object Current - { - get { throw new InvalidOperationException(); } - } - - /// - /// Test if the enumerator can advance, if so advance - /// - /// false as the cannot advance. - /// - /// - /// As the enumerator is over an empty collection its - /// value cannot be moved over a valid position, therefore - /// will always return false. - /// - /// - public bool MoveNext() - { - return false; - } - - /// - /// Resets the enumerator back to the start. - /// - /// - /// - /// As the enumerator is over an empty collection does nothing. - /// - /// - public void Reset() - { - } - - #endregion Implementation of IEnumerator - - #region Private Static Fields - - /// - /// The singleton instance of the . - /// - private readonly static NullEnumerator s_instance = new NullEnumerator(); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/NullSecurityContext.cs b/src/log4net/Util/NullSecurityContext.cs deleted file mode 100644 index 3196d1de..00000000 --- a/src/log4net/Util/NullSecurityContext.cs +++ /dev/null @@ -1,76 +0,0 @@ -#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; - -namespace log4net.Util -{ - /// - /// A SecurityContext used when a SecurityContext is not required - /// - /// - /// - /// The is a no-op implementation of the - /// base class. It is used where a - /// is required but one has not been provided. - /// - /// - /// Nicko Cadell - public sealed class NullSecurityContext : SecurityContext - { - /// - /// Singleton instance of - /// - /// - /// - /// Singleton instance of - /// - /// - public static readonly NullSecurityContext Instance = new NullSecurityContext(); - - /// - /// Private constructor - /// - /// - /// - /// Private constructor for singleton pattern. - /// - /// - private NullSecurityContext() - { - } - - /// - /// Impersonate this SecurityContext - /// - /// State supplied by the caller - /// null - /// - /// - /// No impersonation is done and null is always returned. - /// - /// - public override IDisposable Impersonate(object state) - { - return null; - } - } -} diff --git a/src/log4net/Util/OnlyOnceErrorHandler.cs b/src/log4net/Util/OnlyOnceErrorHandler.cs deleted file mode 100644 index fb9d858b..00000000 --- a/src/log4net/Util/OnlyOnceErrorHandler.cs +++ /dev/null @@ -1,271 +0,0 @@ -#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; - -namespace log4net.Util -{ - /// - /// Implements log4net's default error handling policy which consists - /// of emitting a message for the first error in an appender and - /// ignoring all subsequent errors. - /// - /// - /// - /// The error message is processed using the LogLog sub-system by default. - /// - /// - /// This policy aims at protecting an otherwise working application - /// from being flooded with error messages when logging fails. - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Ron Grabowski - public class OnlyOnceErrorHandler : IErrorHandler - { - #region Public Instance Constructors - - /// - /// Default Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public OnlyOnceErrorHandler() - { - m_prefix = ""; - } - - /// - /// Constructor - /// - /// The prefix to use for each message. - /// - /// - /// Initializes a new instance of the class - /// with the specified prefix. - /// - /// - public OnlyOnceErrorHandler(string prefix) - { - m_prefix = prefix; - } - - #endregion Public Instance Constructors - - #region Public Instance Methods - - /// - /// Reset the error handler back to its initial disabled state. - /// - public void Reset() - { - m_enabledDate = DateTime.MinValue; - m_errorCode = ErrorCode.GenericFailure; - m_exception = null; - m_message = null; - m_firstTime = true; - } - - #region Implementation of IErrorHandler - - /// - /// Log an Error - /// - /// The error message. - /// The exception. - /// The internal error code. - /// - /// - /// Invokes if and only if this is the first error or the first error after has been called. - /// - /// - public void Error(string message, Exception e, ErrorCode errorCode) - { - if (m_firstTime) - { - FirstError(message, e, errorCode); - } - } - - /// - /// Log the very first error - /// - /// The error message. - /// The exception. - /// The internal error code. - /// - /// - /// Sends the error information to 's Error method. - /// - /// - public virtual void FirstError(string message, Exception e, ErrorCode errorCode) { - m_enabledDate = DateTime.Now; - m_errorCode = errorCode; - m_exception = e; - m_message = message; - m_firstTime = false; - - if (LogLog.InternalDebugging && !LogLog.QuietMode) { - LogLog.Error(declaringType, "[" + m_prefix + "] ErrorCode: " + errorCode.ToString() + ". " + message, e); - } - } - - /// - /// Log an Error - /// - /// The error message. - /// The exception. - /// - /// - /// Invokes if and only if this is the first error or the first error after has been called. - /// - /// - public void Error(string message, Exception e) - { - Error(message, e, ErrorCode.GenericFailure); - } - - /// - /// Log an error - /// - /// The error message. - /// - /// - /// Invokes if and only if this is the first error or the first error after has been called. - /// - /// - public void Error(string message) - { - Error(message, null, ErrorCode.GenericFailure); - } - - #endregion Implementation of IErrorHandler - - #endregion - - #region Public Instance Properties - - /// - /// Is error logging enabled - /// - /// - /// - /// Is error logging enabled. Logging is only enabled for the - /// first error delivered to the . - /// - /// - public bool IsEnabled - { - get { return m_firstTime; } - } - - /// - /// The date the first error that trigged this error handler occured. - /// - public DateTime EnabledDate - { - get { return m_enabledDate; } - } - - /// - /// The message from the first error that trigged this error handler. - /// - public string ErrorMessage - { - get { return m_message; } - } - - /// - /// The exception from the first error that trigged this error handler. - /// - /// - /// May be . - /// - public Exception Exception - { - get { return m_exception; } - } - - /// - /// The error code from the first error that trigged this error handler. - /// - /// - /// Defaults to - /// - public ErrorCode ErrorCode - { - get { return m_errorCode; } - } - - #endregion - - #region Private Instance Fields - - /// - /// The date the error was recorded. - /// - private DateTime m_enabledDate; - - /// - /// Flag to indicate if it is the first error - /// - private bool m_firstTime = true; - - /// - /// The message recorded during the first error. - /// - private string m_message = null; - - /// - /// The exception recorded during the first error. - /// - private Exception m_exception = null; - - /// - /// The error code recorded during the first error. - /// - private ErrorCode m_errorCode = ErrorCode.GenericFailure; - - /// - /// String to prefix each message with - /// - private readonly string m_prefix; - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the OnlyOnceErrorHandler class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(OnlyOnceErrorHandler); - - #endregion - } -} diff --git a/src/log4net/Util/OptionConverter.cs b/src/log4net/Util/OptionConverter.cs deleted file mode 100644 index 616cf1bc..00000000 --- a/src/log4net/Util/OptionConverter.cs +++ /dev/null @@ -1,659 +0,0 @@ -#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 System.Collections; -using System.Globalization; -using System.Reflection; -using System.Text; - -using log4net.Core; -using log4net.Util.TypeConverters; - -namespace log4net.Util -{ - /// - /// A convenience class to convert property values to specific types. - /// - /// - /// - /// Utility functions for converting types and parsing values. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class OptionConverter - { - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Uses a private access modifier to prevent instantiation of this class. - /// - /// - private OptionConverter() - { - } - - #endregion Private Instance Constructors - - #region Public Static Methods - -// /// -// /// Concatenates two string arrays. -// /// -// /// Left array. -// /// Right array. -// /// Array containing both left and right arrays. -// public static string[] ConcatenateArrays(string[] l, string[] r) -// { -// return (string[])ConcatenateArrays(l, r); -// } - -// /// -// /// Concatenates two arrays. -// /// -// /// Left array -// /// Right array -// /// Array containing both left and right arrays. -// public static Array ConcatenateArrays(Array l, Array r) -// { -// if (l == null) -// { -// throw new ArgumentNullException("l"); -// } -// if (r == null) -// { -// throw new ArgumentNullException("r"); -// } -// -// int len = l.Length + r.Length; -// Array a = Array.CreateInstance(l.GetType(), len); -// -// Array.Copy(l, 0, a, 0, l.Length); -// Array.Copy(r, 0, a, l.Length, r.Length); -// -// return a; -// } - -// /// -// /// Converts string escape characters back to their correct values. -// /// -// /// String to convert. -// /// Converted result. -// public static string ConvertSpecialChars(string s) -// { -// if (s == null) -// { -// throw new ArgumentNullException("s"); -// } -// char c; -// int len = s.Length; -// StringBuilder buf = new StringBuilder(len); -// -// int i = 0; -// while(i < len) -// { -// c = s[i++]; -// if (c == '\\') -// { -// c = s[i++]; -// if (c == 'n') c = '\n'; -// else if (c == 'r') c = '\r'; -// else if (c == 't') c = '\t'; -// else if (c == 'f') c = '\f'; -// else if (c == '\b') c = '\b'; -// else if (c == '\"') c = '\"'; -// else if (c == '\'') c = '\''; -// else if (c == '\\') c = '\\'; -// } -// buf.Append(c); -// } -// return buf.ToString(); -// } - - /// - /// Converts a string to a value. - /// - /// String to convert. - /// The default value. - /// The value of . - /// - /// - /// If is "true", then true is returned. - /// If is "false", then false is returned. - /// Otherwise, is returned. - /// - /// - public static bool ToBoolean(string argValue, bool defaultValue) - { - if (argValue != null && argValue.Length > 0) - { - try - { - return bool.Parse(argValue); - } - catch(Exception e) - { - LogLog.Error(declaringType, "[" + argValue + "] is not in proper bool form.", e); - } - } - return defaultValue; - } - -// /// -// /// Converts a string to an integer. -// /// -// /// String to convert. -// /// The default value. -// /// The value of . -// /// -// /// -// /// is returned when -// /// cannot be converted to a value. -// /// -// /// -// public static int ToInt(string argValue, int defaultValue) -// { -// if (argValue != null) -// { -// string s = argValue.Trim(); -// try -// { -// return int.Parse(s, NumberFormatInfo.InvariantInfo); -// } -// catch (Exception e) -// { -// LogLog.Error(declaringType, "OptionConverter: [" + s + "] is not in proper int form.", e); -// } -// } -// return defaultValue; -// } - - /// - /// Parses a file size into a number. - /// - /// String to parse. - /// The default value. - /// The value of . - /// - /// - /// Parses a file size of the form: number[KB|MB|GB] into a - /// long value. It is scaled with the appropriate multiplier. - /// - /// - /// is returned when - /// cannot be converted to a value. - /// - /// - public static long ToFileSize(string argValue, long defaultValue) - { - if (argValue == null) - { - return defaultValue; - } - - string s = argValue.Trim().ToUpper(CultureInfo.InvariantCulture); - long multiplier = 1; - int index; - - if ((index = s.IndexOf("KB")) != -1) - { - multiplier = 1024; - s = s.Substring(0, index); - } - else if ((index = s.IndexOf("MB")) != -1) - { - multiplier = 1024 * 1024; - s = s.Substring(0, index); - } - else if ((index = s.IndexOf("GB")) != -1) - { - multiplier = 1024 * 1024 * 1024; - s = s.Substring(0, index); - } - if (s != null) - { - // Try again to remove whitespace between the number and the size specifier - s = s.Trim(); - - long longVal; - if (SystemInfo.TryParse(s, out longVal)) - { - return longVal * multiplier; - } - else - { - LogLog.Error(declaringType, "OptionConverter: ["+ s +"] is not in the correct file size syntax."); - } - } - return defaultValue; - } - - /// - /// Converts a string to an object. - /// - /// The target type to convert to. - /// The string to convert to an object. - /// - /// The object converted from a string or null when the - /// conversion failed. - /// - /// - /// - /// Converts a string to an object. Uses the converter registry to try - /// to convert the string value into the specified target type. - /// - /// - public static object ConvertStringTo(Type target, string txt) - { - if (target == null) - { - throw new ArgumentNullException("target"); - } - - // If we want a string we already have the correct type - if (typeof(string) == target || typeof(object) == target) - { - return txt; - } - - // First lets try to find a type converter - IConvertFrom typeConverter = ConverterRegistry.GetConvertFrom(target); - if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string))) - { - // Found appropriate converter - return typeConverter.ConvertFrom(txt); - } - else - { - if (target.IsEnum) - { - // Target type is an enum. - - // Use the Enum.Parse(EnumType, string) method to get the enum value - return ParseEnum(target, txt, true); - } - else - { - // We essentially make a guess that to convert from a string - // to an arbitrary type T there will be a static method defined on type T called Parse - // that will take an argument of type string. i.e. T.Parse(string)->T we call this - // method to convert the string to the type required by the property. - System.Reflection.MethodInfo meth = target.GetMethod("Parse", new Type[] {typeof(string)}); - if (meth != null) - { - // Call the Parse method - return meth.Invoke(null, BindingFlags.InvokeMethod, null, new object[] {txt}, CultureInfo.InvariantCulture); - } - else - { - // No Parse() method found. - } - } - } - return null; - } - -// /// -// /// Looks up the for the target type. -// /// -// /// The type to lookup the converter for. -// /// The converter for the specified type. -// public static IConvertFrom GetTypeConverter(Type target) -// { -// IConvertFrom converter = ConverterRegistry.GetConverter(target); -// if (converter == null) -// { -// throw new InvalidOperationException("No type converter defined for [" + target + "]"); -// } -// return converter; -// } - - /// - /// Checks if there is an appropriate type conversion from the source type to the target type. - /// - /// The type to convert from. - /// The type to convert to. - /// true if there is a conversion from the source type to the target type. - /// - /// Checks if there is an appropriate type conversion from the source type to the target type. - /// - /// - /// - public static bool CanConvertTypeTo(Type sourceType, Type targetType) - { - if (sourceType == null || targetType == null) - { - return false; - } - - // Check if we can assign directly from the source type to the target type - if (targetType.IsAssignableFrom(sourceType)) - { - return true; - } - - // Look for a To converter - IConvertTo tcSource = ConverterRegistry.GetConvertTo(sourceType, targetType); - if (tcSource != null) - { - if (tcSource.CanConvertTo(targetType)) - { - return true; - } - } - - // Look for a From converter - IConvertFrom tcTarget = ConverterRegistry.GetConvertFrom(targetType); - if (tcTarget != null) - { - if (tcTarget.CanConvertFrom(sourceType)) - { - return true; - } - } - - return false; - } - - /// - /// Converts an object to the target type. - /// - /// The object to convert to the target type. - /// The type to convert to. - /// The converted object. - /// - /// - /// Converts an object to the target type. - /// - /// - public static object ConvertTypeTo(object sourceInstance, Type targetType) - { - Type sourceType = sourceInstance.GetType(); - - // Check if we can assign directly from the source type to the target type - if (targetType.IsAssignableFrom(sourceType)) - { - return sourceInstance; - } - - // Look for a TO converter - IConvertTo tcSource = ConverterRegistry.GetConvertTo(sourceType, targetType); - if (tcSource != null) - { - if (tcSource.CanConvertTo(targetType)) - { - return tcSource.ConvertTo(sourceInstance, targetType); - } - } - - // Look for a FROM converter - IConvertFrom tcTarget = ConverterRegistry.GetConvertFrom(targetType); - if (tcTarget != null) - { - if (tcTarget.CanConvertFrom(sourceType)) - { - return tcTarget.ConvertFrom(sourceInstance); - } - } - - throw new ArgumentException("Cannot convert source object [" + sourceInstance.ToString() + "] to target type [" + targetType.Name + "]", "sourceInstance"); - } - -// /// -// /// Finds the value corresponding to in -// /// and then perform variable substitution -// /// on the found value. -// /// -// /// The key to lookup. -// /// The association to use for lookups. -// /// The substituted result. -// public static string FindAndSubst(string key, System.Collections.IDictionary props) -// { -// if (props == null) -// { -// throw new ArgumentNullException("props"); -// } -// -// string v = props[key] as string; -// if (v == null) -// { -// return null; -// } -// -// try -// { -// return SubstituteVariables(v, props); -// } -// catch(Exception e) -// { -// LogLog.Error(declaringType, "OptionConverter: Bad option value [" + v + "].", e); -// return v; -// } -// } - - /// - /// Instantiates an object given a class name. - /// - /// The fully qualified class name of the object to instantiate. - /// The class to which the new object should belong. - /// The object to return in case of non-fulfillment. - /// - /// An instance of the or - /// if the object could not be instantiated. - /// - /// - /// - /// Checks that the is a subclass of - /// . If that test fails or the object could - /// not be instantiated, then is returned. - /// - /// - public static object InstantiateByClassName(string className, Type superClass, object defaultValue) - { - if (className != null) - { - try - { - Type classObj = SystemInfo.GetTypeFromString(className, true, true); - if (!superClass.IsAssignableFrom(classObj)) - { - LogLog.Error(declaringType, "OptionConverter: A [" + className + "] object is not assignable to a [" + superClass.FullName + "] variable."); - return defaultValue; - } - return Activator.CreateInstance(classObj); - } - catch (Exception e) - { - LogLog.Error(declaringType, "Could not instantiate class [" + className + "].", e); - } - } - return defaultValue; - } - - /// - /// Performs variable substitution in string from the - /// values of keys found in . - /// - /// The string on which variable substitution is performed. - /// The dictionary to use to lookup variables. - /// The result of the substitutions. - /// - /// - /// The variable substitution delimiters are ${ and }. - /// - /// - /// For example, if props contains key=value, then the call - /// - /// - /// - /// string s = OptionConverter.SubstituteVariables("Value of key is ${key}."); - /// - /// - /// - /// will set the variable s to "Value of key is value.". - /// - /// - /// If no value could be found for the specified key, then substitution - /// defaults to an empty string. - /// - /// - /// For example, if system properties contains no value for the key - /// "nonExistentKey", then the call - /// - /// - /// - /// string s = OptionConverter.SubstituteVariables("Value of nonExistentKey is [${nonExistentKey}]"); - /// - /// - /// - /// will set s to "Value of nonExistentKey is []". - /// - /// - /// An Exception is thrown if contains a start - /// delimiter "${" which is not balanced by a stop delimiter "}". - /// - /// - public static string SubstituteVariables(string value, System.Collections.IDictionary props) - { - StringBuilder buf = new StringBuilder(); - - int i = 0; - int j, k; - - while(true) - { - j = value.IndexOf(DELIM_START, i); - if (j == -1) - { - if (i == 0) - { - return value; - } - else - { - buf.Append(value.Substring(i, value.Length - i)); - return buf.ToString(); - } - } - else - { - buf.Append(value.Substring(i, j - i)); - k = value.IndexOf(DELIM_STOP, j); - if (k == -1) - { - throw new LogException("[" + value + "] has no closing brace. Opening brace at position [" + j + "]"); - } - else - { - j += DELIM_START_LEN; - string key = value.Substring(j, k - j); - - string replacement = props[key] as string; - - if (replacement != null) - { - buf.Append(replacement); - } - i = k + DELIM_STOP_LEN; - } - } - } - } - - #endregion Public Static Methods - - #region Private Static Methods - - /// - /// Converts the string representation of the name or numeric value of one or - /// more enumerated constants to an equivalent enumerated object. - /// - /// The type to convert to. - /// The enum string value. - /// If true, ignore case; otherwise, regard case. - /// An object of type whose value is represented by . - private static object ParseEnum(System.Type enumType, string value, bool ignoreCase) - { -#if !NETCF - return Enum.Parse(enumType, value, ignoreCase); -#else - FieldInfo[] fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); - - string[] names = value.Split(new char[] {','}); - for (int i = 0; i < names.Length; ++i) - { - names[i] = names [i].Trim(); - } - - long retVal = 0; - - try - { - // Attempt to convert to numeric type - return Enum.ToObject(enumType, Convert.ChangeType(value, typeof(long), CultureInfo.InvariantCulture)); - } - catch {} - - foreach (string name in names) - { - bool found = false; - foreach(FieldInfo field in fields) - { - if (String.Compare(name, field.Name, ignoreCase) == 0) - { - retVal |= ((IConvertible) field.GetValue(null)).ToInt64(CultureInfo.InvariantCulture); - found = true; - break; - } - } - if (!found) - { - throw new ArgumentException("Failed to lookup member [" + name + "] from Enum type [" + enumType.Name + "]"); - } - } - return Enum.ToObject(enumType, retVal); -#endif - } - - #endregion Private Static Methods - - #region Private Static Fields - - /// - /// The fully qualified type of the OptionConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(OptionConverter); - - private const string DELIM_START = "${"; - private const char DELIM_STOP = '}'; - private const int DELIM_START_LEN = 2; - private const int DELIM_STOP_LEN = 1; - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/PatternConverter.cs b/src/log4net/Util/PatternConverter.cs deleted file mode 100644 index 7b333957..00000000 --- a/src/log4net/Util/PatternConverter.cs +++ /dev/null @@ -1,397 +0,0 @@ -#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.Text; -using System.IO; -using System.Collections; - -using log4net.Util; -using log4net.Repository; - -namespace log4net.Util -{ - /// - /// Abstract class that provides the formatting functionality that - /// derived classes need. - /// - /// - /// - /// Conversion specifiers in a conversion patterns are parsed to - /// individual PatternConverters. Each of which is responsible for - /// converting a logging event in a converter specific manner. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public abstract class PatternConverter - { - #region Protected Instance Constructors - - /// - /// Protected constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - protected PatternConverter() - { - } - - #endregion Protected Instance Constructors - - #region Public Instance Properties - - /// - /// Get the next pattern converter in the chain - /// - /// - /// the next pattern converter in the chain - /// - /// - /// - /// Get the next pattern converter in the chain - /// - /// - public virtual PatternConverter Next - { - get { return m_next; } - } - - /// - /// Gets or sets the formatting info for this converter - /// - /// - /// The formatting info for this converter - /// - /// - /// - /// Gets or sets the formatting info for this converter - /// - /// - public virtual FormattingInfo FormattingInfo - { - get { return new FormattingInfo(m_min, m_max, m_leftAlign); } - set - { - m_min = value.Min; - m_max = value.Max; - m_leftAlign = value.LeftAlign; - } - } - - /// - /// Gets or sets the option value for this converter - /// - /// - /// The option for this converter - /// - /// - /// - /// Gets or sets the option value for this converter - /// - /// - public virtual string Option - { - get { return m_option; } - set { m_option = value; } - } - - #endregion Public Instance Properties - - #region Protected Abstract Methods - - /// - /// Evaluate this pattern converter and write the output to a writer. - /// - /// that will receive the formatted result. - /// The state object on which the pattern converter should be executed. - /// - /// - /// Derived pattern converters must override this method in order to - /// convert conversion specifiers in the appropriate way. - /// - /// - abstract protected void Convert(TextWriter writer, object state); - - #endregion Protected Abstract Methods - - #region Public Instance Methods - - /// - /// Set the next pattern converter in the chains - /// - /// the pattern converter that should follow this converter in the chain - /// the next converter - /// - /// - /// The PatternConverter can merge with its neighbor during this method (or a sub class). - /// Therefore the return value may or may not be the value of the argument passed in. - /// - /// - public virtual PatternConverter SetNext(PatternConverter patternConverter) - { - m_next = patternConverter; - return m_next; - } - - /// - /// Write the pattern converter to the writer with appropriate formatting - /// - /// that will receive the formatted result. - /// The state object on which the pattern converter should be executed. - /// - /// - /// This method calls to allow the subclass to perform - /// appropriate conversion of the pattern converter. If formatting options have - /// been specified via the then this method will - /// apply those formattings before writing the output. - /// - /// - virtual public void Format(TextWriter writer, object state) - { - if (m_min < 0 && m_max == int.MaxValue) - { - // Formatting options are not in use - Convert(writer, state); - } - else - { - string msg = null; - int len; - lock (m_formatWriter) - { - m_formatWriter.Reset(c_renderBufferMaxCapacity, c_renderBufferSize); - - Convert(m_formatWriter, state); - - StringBuilder buf = m_formatWriter.GetStringBuilder(); - len = buf.Length; - if (len > m_max) - { - msg = buf.ToString(len - m_max, m_max); - len = m_max; - } - else - { - msg = buf.ToString(); - } - } - - if (len < m_min) - { - if (m_leftAlign) - { - writer.Write(msg); - SpacePad(writer, m_min - len); - } - else - { - SpacePad(writer, m_min - len); - writer.Write(msg); - } - } - else - { - writer.Write(msg); - } - } - } - - private static readonly string[] SPACES = { " ", " ", " ", " ", // 1,2,4,8 spaces - " ", // 16 spaces - " " }; // 32 spaces - - /// - /// Fast space padding method. - /// - /// to which the spaces will be appended. - /// The number of spaces to be padded. - /// - /// - /// Fast space padding method. - /// - /// - protected static void SpacePad(TextWriter writer, int length) - { - while(length >= 32) - { - writer.Write(SPACES[5]); - length -= 32; - } - - for(int i = 4; i >= 0; i--) - { - if ((length & (1< - /// The option string to the converter - /// - private string m_option = null; - - private ReusableStringWriter m_formatWriter = new ReusableStringWriter(System.Globalization.CultureInfo.InvariantCulture); - - #endregion Private Instance Fields - - #region Constants - - /// - /// Initial buffer size - /// - private const int c_renderBufferSize = 256; - - /// - /// Maximum buffer size before it is recycled - /// - private const int c_renderBufferMaxCapacity = 1024; - - #endregion - - #region Static Methods - - /// - /// Write an dictionary to a - /// - /// the writer to write to - /// a to use for object conversion - /// the value to write to the writer - /// - /// - /// Writes the to a writer in the form: - /// - /// - /// {key1=value1, key2=value2, key3=value3} - /// - /// - /// If the specified - /// is not null then it is used to render the key and value to text, otherwise - /// the object's ToString method is called. - /// - /// - protected static void WriteDictionary(TextWriter writer, ILoggerRepository repository, IDictionary value) - { - WriteDictionary(writer, repository, value.GetEnumerator()); - } - - /// - /// Write an dictionary to a - /// - /// the writer to write to - /// a to use for object conversion - /// the value to write to the writer - /// - /// - /// Writes the to a writer in the form: - /// - /// - /// {key1=value1, key2=value2, key3=value3} - /// - /// - /// If the specified - /// is not null then it is used to render the key and value to text, otherwise - /// the object's ToString method is called. - /// - /// - protected static void WriteDictionary(TextWriter writer, ILoggerRepository repository, IDictionaryEnumerator value) - { - writer.Write("{"); - - bool first = true; - - // Write out all the dictionary key value pairs - while (value.MoveNext()) - { - if (first) - { - first = false; - } - else - { - writer.Write(", "); - } - WriteObject(writer, repository, value.Key); - writer.Write("="); - WriteObject(writer, repository, value.Value); - } - - writer.Write("}"); - } - - /// - /// Write an object to a - /// - /// the writer to write to - /// a to use for object conversion - /// the value to write to the writer - /// - /// - /// Writes the Object to a writer. If the specified - /// is not null then it is used to render the object to text, otherwise - /// the object's ToString method is called. - /// - /// - protected static void WriteObject(TextWriter writer, ILoggerRepository repository, object value) - { - if (repository != null) - { - repository.RendererMap.FindAndRender(value, writer); - } - else - { - // Don't have a repository to render with so just have to rely on ToString - if (value == null) - { - writer.Write( SystemInfo.NullText ); - } - else - { - writer.Write( value.ToString() ); - } - } - } - - #endregion - - private PropertiesDictionary properties; - - /// - /// - /// - public PropertiesDictionary Properties - { - get { return properties; } - set { properties = value; } - } - } -} diff --git a/src/log4net/Util/PatternParser.cs b/src/log4net/Util/PatternParser.cs deleted file mode 100644 index 863f5572..00000000 --- a/src/log4net/Util/PatternParser.cs +++ /dev/null @@ -1,435 +0,0 @@ -#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 System.Collections; -using System.Globalization; -using System.IO; -using System.Reflection; -using System.Text; - -using log4net.Layout; -using log4net.Core; -using log4net.DateFormatter; -using log4net.Layout.Pattern; -using log4net.Util; - -namespace log4net.Util -{ - /// - /// Most of the work of the class - /// is delegated to the PatternParser class. - /// - /// - /// - /// The PatternParser processes a pattern string and - /// returns a chain of objects. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class PatternParser - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// The pattern to parse. - /// - /// - /// Initializes a new instance of the class - /// with the specified pattern string. - /// - /// - public PatternParser(string pattern) - { - m_pattern = pattern; - } - - #endregion Public Instance Constructors - - #region Public Instance Methods - - /// - /// Parses the pattern into a chain of pattern converters. - /// - /// The head of a chain of pattern converters. - /// - /// - /// Parses the pattern into a chain of pattern converters. - /// - /// - public PatternConverter Parse() - { - string[] converterNamesCache = BuildCache(); - - ParseInternal(m_pattern, converterNamesCache); - - return m_head; - } - - #endregion Public Instance Methods - - #region Public Instance Properties - - /// - /// Get the converter registry used by this parser - /// - /// - /// The converter registry used by this parser - /// - /// - /// - /// Get the converter registry used by this parser - /// - /// - public Hashtable PatternConverters - { - get { return m_patternConverters; } - } - - #endregion Public Instance Properties - - #region Private Instance Methods - - /// - /// Build the unified cache of converters from the static and instance maps - /// - /// the list of all the converter names - /// - /// - /// Build the unified cache of converters from the static and instance maps - /// - /// - private string[] BuildCache() - { - string[] converterNamesCache = new string[m_patternConverters.Keys.Count]; - m_patternConverters.Keys.CopyTo(converterNamesCache, 0); - - // sort array so that longer strings come first - Array.Sort(converterNamesCache, 0, converterNamesCache.Length, StringLengthComparer.Instance); - - return converterNamesCache; - } - - #region StringLengthComparer - - /// - /// Sort strings by length - /// - /// - /// - /// that orders strings by string length. - /// The longest strings are placed first - /// - /// - private sealed class StringLengthComparer : IComparer - { - public static readonly StringLengthComparer Instance = new StringLengthComparer(); - - private StringLengthComparer() - { - } - - #region Implementation of IComparer - - public int Compare(object x, object y) - { - string s1 = x as string; - string s2 = y as string; - - if (s1 == null && s2 == null) - { - return 0; - } - if (s1 == null) - { - return 1; - } - if (s2 == null) - { - return -1; - } - - return s2.Length.CompareTo(s1.Length); - } - - #endregion - } - - #endregion // StringLengthComparer - - /// - /// Internal method to parse the specified pattern to find specified matches - /// - /// the pattern to parse - /// the converter names to match in the pattern - /// - /// - /// The matches param must be sorted such that longer strings come before shorter ones. - /// - /// - private void ParseInternal(string pattern, string[] matches) - { - int offset = 0; - while(offset < pattern.Length) - { - int i = pattern.IndexOf('%', offset); - if (i < 0 || i == pattern.Length - 1) - { - ProcessLiteral(pattern.Substring(offset)); - offset = pattern.Length; - } - else - { - if (pattern[i+1] == '%') - { - // Escaped - ProcessLiteral(pattern.Substring(offset, i - offset + 1)); - offset = i + 2; - } - else - { - ProcessLiteral(pattern.Substring(offset, i - offset)); - offset = i + 1; - - FormattingInfo formattingInfo = new FormattingInfo(); - - // Process formatting options - - // Look for the align flag - if (offset < pattern.Length) - { - if (pattern[offset] == '-') - { - // Seen align flag - formattingInfo.LeftAlign = true; - offset++; - } - } - // Look for the minimum length - while (offset < pattern.Length && char.IsDigit(pattern[offset])) - { - // Seen digit - if (formattingInfo.Min < 0) - { - formattingInfo.Min = 0; - } - formattingInfo.Min = (formattingInfo.Min * 10) + int.Parse(pattern[offset].ToString(CultureInfo.InvariantCulture), System.Globalization.NumberFormatInfo.InvariantInfo); - offset++; - } - // Look for the separator between min and max - if (offset < pattern.Length) - { - if (pattern[offset] == '.') - { - // Seen separator - offset++; - } - } - // Look for the maximum length - while (offset < pattern.Length && char.IsDigit(pattern[offset])) - { - // Seen digit - if (formattingInfo.Max == int.MaxValue) - { - formattingInfo.Max = 0; - } - formattingInfo.Max = (formattingInfo.Max * 10) + int.Parse(pattern[offset].ToString(CultureInfo.InvariantCulture), System.Globalization.NumberFormatInfo.InvariantInfo); - offset++; - } - - int remainingStringLength = pattern.Length - offset; - - // Look for pattern - for(int m=0; m - /// Process a parsed literal - /// - /// the literal text - private void ProcessLiteral(string text) - { - if (text.Length > 0) - { - // Convert into a pattern - ProcessConverter("literal", text, new FormattingInfo()); - } - } - - /// - /// Process a parsed converter pattern - /// - /// the name of the converter - /// the optional option for the converter - /// the formatting info for the converter - private void ProcessConverter(string converterName, string option, FormattingInfo formattingInfo) - { - LogLog.Debug(declaringType, "Converter ["+converterName+"] Option ["+option+"] Format [min="+formattingInfo.Min+",max="+formattingInfo.Max+",leftAlign="+formattingInfo.LeftAlign+"]"); - - // Lookup the converter type - ConverterInfo converterInfo = (ConverterInfo)m_patternConverters[converterName]; - if (converterInfo == null) - { - LogLog.Error(declaringType, "Unknown converter name ["+converterName+"] in conversion pattern."); - } - else - { - // Create the pattern converter - PatternConverter pc = null; - try - { - pc = (PatternConverter)Activator.CreateInstance(converterInfo.Type); - } - catch(Exception createInstanceEx) - { - LogLog.Error(declaringType, "Failed to create instance of Type [" + converterInfo.Type.FullName + "] using default constructor. Exception: " + createInstanceEx.ToString()); - } - - // formattingInfo variable is an instance variable, occasionally reset - // and used over and over again - pc.FormattingInfo = formattingInfo; - pc.Option = option; - pc.Properties = converterInfo.Properties; - - IOptionHandler optionHandler = pc as IOptionHandler; - if (optionHandler != null) - { - optionHandler.ActivateOptions(); - } - - AddConverter(pc); - } - } - - /// - /// Resets the internal state of the parser and adds the specified pattern converter - /// to the chain. - /// - /// The pattern converter to add. - private void AddConverter(PatternConverter pc) - { - // Add the pattern converter to the list. - - if (m_head == null) - { - m_head = m_tail = pc; - } - else - { - // Set the next converter on the tail - // Update the tail reference - // note that a converter may combine the 'next' into itself - // and therefore the tail would not change! - m_tail = m_tail.SetNext(pc); - } - } - - #endregion Protected Instance Methods - - #region Private Constants - - private const char ESCAPE_CHAR = '%'; - - #endregion Private Constants - - #region Private Instance Fields - - /// - /// The first pattern converter in the chain - /// - private PatternConverter m_head; - - /// - /// the last pattern converter in the chain - /// - private PatternConverter m_tail; - - /// - /// The pattern - /// - private string m_pattern; - - /// - /// Internal map of converter identifiers to converter types - /// - /// - /// - /// This map overrides the static s_globalRulesRegistry map. - /// - /// - private Hashtable m_patternConverters = new Hashtable(); - - #endregion Private Instance Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the PatternParser class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(PatternParser); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/PatternString.cs b/src/log4net/Util/PatternString.cs deleted file mode 100644 index 73f5a5fa..00000000 --- a/src/log4net/Util/PatternString.cs +++ /dev/null @@ -1,501 +0,0 @@ -#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 System.Collections; -using System.IO; - -using log4net.Util; -using log4net.Util.PatternStringConverters; -using log4net.Core; - -namespace log4net.Util -{ - /// - /// This class implements a patterned string. - /// - /// - /// - /// This string has embedded patterns that are resolved and expanded - /// when the string is formatted. - /// - /// - /// This class functions similarly to the - /// in that it accepts a pattern and renders it to a string. Unlike the - /// however the PatternString - /// does not render the properties of a specific but - /// of the process in general. - /// - /// - /// The recognized conversion pattern names are: - /// - /// - /// - /// Conversion Pattern Name - /// Effect - /// - /// - /// appdomain - /// - /// - /// Used to output the friendly name of the current AppDomain. - /// - /// - /// - /// - /// date - /// - /// - /// Used to output the current date and time in the local time zone. - /// To output the date in universal time use the %utcdate pattern. - /// The date conversion - /// specifier may be followed by a date format specifier enclosed - /// between braces. For example, %date{HH:mm:ss,fff} or - /// %date{dd MMM yyyy HH:mm:ss,fff}. If no date format specifier is - /// given then ISO8601 format is - /// assumed (). - /// - /// - /// The date format specifier admits the same syntax as the - /// time pattern string of the . - /// - /// - /// For better results it is recommended to use the log4net date - /// formatters. These can be specified using one of the strings - /// "ABSOLUTE", "DATE" and "ISO8601" for specifying - /// , - /// and respectively - /// . For example, - /// %date{ISO8601} or %date{ABSOLUTE}. - /// - /// - /// These dedicated date formatters perform significantly - /// better than . - /// - /// - /// - /// - /// env - /// - /// - /// Used to output the a specific environment variable. The key to - /// lookup must be specified within braces and directly following the - /// pattern specifier, e.g. %env{COMPUTERNAME} would include the value - /// of the COMPUTERNAME environment variable. - /// - /// - /// The env pattern is not supported on the .NET Compact Framework. - /// - /// - /// - /// - /// identity - /// - /// - /// Used to output the user name for the currently active user - /// (Principal.Identity.Name). - /// - /// - /// - /// - /// newline - /// - /// - /// Outputs the platform dependent line separator character or - /// characters. - /// - /// - /// This conversion pattern name offers the same performance as using - /// non-portable line separator strings such as "\n", or "\r\n". - /// Thus, it is the preferred way of specifying a line separator. - /// - /// - /// - /// - /// processid - /// - /// - /// Used to output the system process ID for the current process. - /// - /// - /// - /// - /// property - /// - /// - /// Used to output a specific context property. The key to - /// lookup must be specified within braces and directly following the - /// pattern specifier, e.g. %property{user} would include the value - /// from the property that is keyed by the string 'user'. Each property value - /// that is to be included in the log must be specified separately. - /// Properties are stored in logging contexts. By default - /// the log4net:HostName property is set to the name of machine on - /// which the event was originally logged. - /// - /// - /// If no key is specified, e.g. %property then all the keys and their - /// values are printed in a comma separated list. - /// - /// - /// The properties of an event are combined from a number of different - /// contexts. These are listed below in the order in which they are searched. - /// - /// - /// - /// the thread properties - /// - /// The that are set on the current - /// thread. These properties are shared by all events logged on this thread. - /// - /// - /// - /// the global properties - /// - /// The that are set globally. These - /// properties are shared by all the threads in the AppDomain. - /// - /// - /// - /// - /// - /// - /// random - /// - /// - /// Used to output a random string of characters. The string is made up of - /// uppercase letters and numbers. By default the string is 4 characters long. - /// The length of the string can be specified within braces directly following the - /// pattern specifier, e.g. %random{8} would output an 8 character string. - /// - /// - /// - /// - /// username - /// - /// - /// Used to output the WindowsIdentity for the currently - /// active user. - /// - /// - /// - /// - /// utcdate - /// - /// - /// Used to output the date of the logging event in universal time. - /// The date conversion - /// specifier may be followed by a date format specifier enclosed - /// between braces. For example, %utcdate{HH:mm:ss,fff} or - /// %utcdate{dd MMM yyyy HH:mm:ss,fff}. If no date format specifier is - /// given then ISO8601 format is - /// assumed (). - /// - /// - /// The date format specifier admits the same syntax as the - /// time pattern string of the . - /// - /// - /// For better results it is recommended to use the log4net date - /// formatters. These can be specified using one of the strings - /// "ABSOLUTE", "DATE" and "ISO8601" for specifying - /// , - /// and respectively - /// . For example, - /// %utcdate{ISO8601} or %utcdate{ABSOLUTE}. - /// - /// - /// These dedicated date formatters perform significantly - /// better than . - /// - /// - /// - /// - /// % - /// - /// - /// The sequence %% outputs a single percent sign. - /// - /// - /// - /// - /// - /// Additional pattern converters may be registered with a specific - /// instance using or - /// . - /// - /// - /// See the for details on the - /// format modifiers supported by the patterns. - /// - /// - /// Nicko Cadell - public class PatternString : IOptionHandler - { - #region Static Fields - - /// - /// Internal map of converter identifiers to converter types. - /// - private static Hashtable s_globalRulesRegistry; - - #endregion Static Fields - - #region Member Variables - - /// - /// the pattern - /// - private string m_pattern; - - /// - /// the head of the pattern converter chain - /// - private PatternConverter m_head; - - /// - /// patterns defined on this PatternString only - /// - private Hashtable m_instanceRulesRegistry = new Hashtable(); - - #endregion - - #region Static Constructor - - /// - /// Initialize the global registry - /// - static PatternString() - { - s_globalRulesRegistry = new Hashtable(15); - - s_globalRulesRegistry.Add("appdomain", typeof(AppDomainPatternConverter)); - s_globalRulesRegistry.Add("date", typeof(DatePatternConverter)); -#if !NETCF - s_globalRulesRegistry.Add("env", typeof(EnvironmentPatternConverter)); - s_globalRulesRegistry.Add("envFolderPath", typeof(EnvironmentFolderPathPatternConverter)); -#endif - s_globalRulesRegistry.Add("identity", typeof(IdentityPatternConverter)); - s_globalRulesRegistry.Add("literal", typeof(LiteralPatternConverter)); - s_globalRulesRegistry.Add("newline", typeof(NewLinePatternConverter)); - s_globalRulesRegistry.Add("processid", typeof(ProcessIdPatternConverter)); - s_globalRulesRegistry.Add("property", typeof(PropertyPatternConverter)); - s_globalRulesRegistry.Add("random", typeof(RandomStringPatternConverter)); - s_globalRulesRegistry.Add("username", typeof(UserNamePatternConverter)); - - s_globalRulesRegistry.Add("utcdate", typeof(UtcDatePatternConverter)); - s_globalRulesRegistry.Add("utcDate", typeof(UtcDatePatternConverter)); - s_globalRulesRegistry.Add("UtcDate", typeof(UtcDatePatternConverter)); - } - - #endregion Static Constructor - - #region Constructors - - /// - /// Default constructor - /// - /// - /// - /// Initialize a new instance of - /// - /// - public PatternString() - { - } - - /// - /// Constructs a PatternString - /// - /// The pattern to use with this PatternString - /// - /// - /// Initialize a new instance of with the pattern specified. - /// - /// - public PatternString(string pattern) - { - m_pattern = pattern; - ActivateOptions(); - } - - #endregion - - /// - /// Gets or sets the pattern formatting string - /// - /// - /// The pattern formatting string - /// - /// - /// - /// The ConversionPattern option. This is the string which - /// controls formatting and consists of a mix of literal content and - /// conversion specifiers. - /// - /// - public string ConversionPattern - { - get { return m_pattern; } - set { m_pattern = value; } - } - - #region Implementation of IOptionHandler - - /// - /// Initialize object options - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - virtual public void ActivateOptions() - { - m_head = CreatePatternParser(m_pattern).Parse(); - } - - #endregion - - /// - /// Create the used to parse the pattern - /// - /// the pattern to parse - /// The - /// - /// - /// Returns PatternParser used to parse the conversion string. Subclasses - /// may override this to return a subclass of PatternParser which recognize - /// custom conversion pattern name. - /// - /// - private PatternParser CreatePatternParser(string pattern) - { - PatternParser patternParser = new PatternParser(pattern); - - // Add all the builtin patterns - foreach(DictionaryEntry entry in s_globalRulesRegistry) - { - ConverterInfo converterInfo = new ConverterInfo(); - converterInfo.Name = (string)entry.Key; - converterInfo.Type = (Type)entry.Value; - patternParser.PatternConverters.Add(entry.Key, converterInfo); - } - // Add the instance patterns - foreach(DictionaryEntry entry in m_instanceRulesRegistry) - { - patternParser.PatternConverters[entry.Key] = entry.Value; - } - - return patternParser; - } - - /// - /// Produces a formatted string as specified by the conversion pattern. - /// - /// The TextWriter to write the formatted event to - /// - /// - /// Format the pattern to the . - /// - /// - public void Format(TextWriter writer) - { - if (writer == null) - { - throw new ArgumentNullException("writer"); - } - - PatternConverter c = m_head; - - // loop through the chain of pattern converters - while(c != null) - { - c.Format(writer, null); - c = c.Next; - } - } - - /// - /// Format the pattern as a string - /// - /// the pattern formatted as a string - /// - /// - /// Format the pattern to a string. - /// - /// - public string Format() - { - StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture); - Format(writer); - return writer.ToString(); - } - - /// - /// Add a converter to this PatternString - /// - /// the converter info - /// - /// - /// This version of the method is used by the configurator. - /// Programmatic users should use the alternative method. - /// - /// - public void AddConverter(ConverterInfo converterInfo) - { - if (converterInfo == null) throw new ArgumentNullException("converterInfo"); - - if (!typeof(PatternConverter).IsAssignableFrom(converterInfo.Type)) - { - throw new ArgumentException("The converter type specified [" + converterInfo.Type + "] must be a subclass of log4net.Util.PatternConverter", "converterInfo"); - } - m_instanceRulesRegistry[converterInfo.Name] = converterInfo; - } - - /// - /// Add a converter to this PatternString - /// - /// the name of the conversion pattern for this converter - /// the type of the converter - /// - /// - /// Add a converter to this PatternString - /// - /// - public void AddConverter(string name, Type type) - { - if (name == null) throw new ArgumentNullException("name"); - if (type == null) throw new ArgumentNullException("type"); - - ConverterInfo converterInfo = new ConverterInfo(); - converterInfo.Name = name; - converterInfo.Type = type; - - AddConverter(converterInfo); - } - } -} diff --git a/src/log4net/Util/PatternStringConverters/AppDomainPatternConverter.cs b/src/log4net/Util/PatternStringConverters/AppDomainPatternConverter.cs deleted file mode 100644 index 9b110022..00000000 --- a/src/log4net/Util/PatternStringConverters/AppDomainPatternConverter.cs +++ /dev/null @@ -1,54 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Util; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Write the name of the current AppDomain to the output - /// - /// - /// - /// Write the name of the current AppDomain to the output writer - /// - /// - /// Nicko Cadell - internal sealed class AppDomainPatternConverter : PatternConverter - { - /// - /// Write the name of the current AppDomain to the output - /// - /// the writer to write to - /// null, state is not set - /// - /// - /// Writes name of the current AppDomain to the output . - /// - /// - override protected void Convert(TextWriter writer, object state) - { - writer.Write( SystemInfo.ApplicationFriendlyName ); - } - } -} diff --git a/src/log4net/Util/PatternStringConverters/DatePatternConverter.cs b/src/log4net/Util/PatternStringConverters/DatePatternConverter.cs deleted file mode 100644 index 88045dfa..00000000 --- a/src/log4net/Util/PatternStringConverters/DatePatternConverter.cs +++ /dev/null @@ -1,190 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Util; -using log4net.DateFormatter; -using log4net.Core; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Write the current date to the output - /// - /// - /// - /// Date pattern converter, uses a to format - /// the current date and time to the writer as a string. - /// - /// - /// The value of the determines - /// the formatting of the date. The following values are allowed: - /// - /// - /// Option value - /// Output - /// - /// - /// ISO8601 - /// - /// Uses the formatter. - /// Formats using the "yyyy-MM-dd HH:mm:ss,fff" pattern. - /// - /// - /// - /// DATE - /// - /// Uses the formatter. - /// Formats using the "dd MMM yyyy HH:mm:ss,fff" for example, "06 Nov 1994 15:49:37,459". - /// - /// - /// - /// ABSOLUTE - /// - /// Uses the formatter. - /// Formats using the "HH:mm:ss,fff" for example, "15:49:37,459". - /// - /// - /// - /// other - /// - /// Any other pattern string uses the formatter. - /// This formatter passes the pattern string to the - /// method. - /// For details on valid patterns see - /// DateTimeFormatInfo Class. - /// - /// - /// - /// - /// - /// The date and time is in the local time zone and is rendered in that zone. - /// To output the time in Universal time see . - /// - /// - /// Nicko Cadell - internal class DatePatternConverter : PatternConverter, IOptionHandler - { - /// - /// The used to render the date to a string - /// - /// - /// - /// The used to render the date to a string - /// - /// - protected IDateFormatter m_dateFormatter; - - #region Implementation of IOptionHandler - - /// - /// Initialize the converter options - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - public void ActivateOptions() - { - string dateFormatStr = Option; - if (dateFormatStr == null) - { - dateFormatStr = AbsoluteTimeDateFormatter.Iso8601TimeDateFormat; - } - - if (string.Compare(dateFormatStr, AbsoluteTimeDateFormatter.Iso8601TimeDateFormat, true, System.Globalization.CultureInfo.InvariantCulture) == 0) - { - m_dateFormatter = new Iso8601DateFormatter(); - } - else if (string.Compare(dateFormatStr, AbsoluteTimeDateFormatter.AbsoluteTimeDateFormat, true, System.Globalization.CultureInfo.InvariantCulture) == 0) - { - m_dateFormatter = new AbsoluteTimeDateFormatter(); - } - else if (string.Compare(dateFormatStr, AbsoluteTimeDateFormatter.DateAndTimeDateFormat, true, System.Globalization.CultureInfo.InvariantCulture) == 0) - { - m_dateFormatter = new DateTimeDateFormatter(); - } - else - { - try - { - m_dateFormatter = new SimpleDateFormatter(dateFormatStr); - } - catch (Exception e) - { - LogLog.Error(declaringType, "Could not instantiate SimpleDateFormatter with ["+dateFormatStr+"]", e); - m_dateFormatter = new Iso8601DateFormatter(); - } - } - } - - #endregion - - /// - /// Write the current date to the output - /// - /// that will receive the formatted result. - /// null, state is not set - /// - /// - /// Pass the current date and time to the - /// for it to render it to the writer. - /// - /// - /// The date and time passed is in the local time zone. - /// - /// - override protected void Convert(TextWriter writer, object state) - { - try - { - m_dateFormatter.FormatDate(DateTime.Now, writer); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Error occurred while converting date.", ex); - } - } - - #region Private Static Fields - - /// - /// The fully qualified type of the DatePatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(DatePatternConverter); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs b/src/log4net/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs deleted file mode 100644 index a6dd2216..00000000 --- a/src/log4net/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs +++ /dev/null @@ -1,98 +0,0 @@ -#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 - -#if !NETCF - -using System; -using System.IO; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Write an folder path to the output - /// - /// - /// - /// Write an special path environment folder path to the output writer. - /// The value of the determines - /// the name of the variable to output. - /// should be a value in the enumeration. - /// - /// - /// Ron Grabowski - internal sealed class EnvironmentFolderPathPatternConverter : PatternConverter - { - /// - /// Write an special path environment folder path to the output - /// - /// the writer to write to - /// null, state is not set - /// - /// - /// Writes the special path environment folder path to the output . - /// The name of the special path environment folder path to output must be set - /// using the - /// property. - /// - /// - override protected void Convert(TextWriter writer, object state) - { - try - { - if (Option != null && Option.Length > 0) - { - Environment.SpecialFolder specialFolder = - (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), Option, true); - - string envFolderPathValue = Environment.GetFolderPath(specialFolder); - if (envFolderPathValue != null && envFolderPathValue.Length > 0) - { - writer.Write(envFolderPathValue); - } - } - } - catch (System.Security.SecurityException secEx) - { - // This security exception will occur if the caller does not have - // unrestricted environment permission. If this occurs the expansion - // will be skipped with the following warning message. - LogLog.Debug(declaringType, "Security exception while trying to expand environment variables. Error Ignored. No Expansion.", secEx); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Error occurred while converting environment variable.", ex); - } - } - - #region Private Static Fields - - /// - /// The fully qualified type of the EnvironmentFolderPathPatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(EnvironmentFolderPathPatternConverter); - - #endregion Private Static Fields - } -} - -#endif // !NETCF \ No newline at end of file diff --git a/src/log4net/Util/PatternStringConverters/EnvironmentPatternConverter.cs b/src/log4net/Util/PatternStringConverters/EnvironmentPatternConverter.cs deleted file mode 100644 index 01241f9d..00000000 --- a/src/log4net/Util/PatternStringConverters/EnvironmentPatternConverter.cs +++ /dev/null @@ -1,114 +0,0 @@ -#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 - -// .NET Compact Framework 1.0 has no support for Environment.GetEnvironmentVariable() -#if !NETCF - -using System; -using System.Text; -using System.IO; - -using log4net.Util; -using log4net.DateFormatter; -using log4net.Core; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Write an environment variable to the output - /// - /// - /// - /// Write an environment variable to the output writer. - /// The value of the determines - /// the name of the variable to output. - /// - /// - /// Nicko Cadell - internal sealed class EnvironmentPatternConverter : PatternConverter - { - /// - /// Write an environment variable to the output - /// - /// the writer to write to - /// null, state is not set - /// - /// - /// Writes the environment variable to the output . - /// The name of the environment variable to output must be set - /// using the - /// property. - /// - /// - override protected void Convert(TextWriter writer, object state) - { - try - { - if (this.Option != null && this.Option.Length > 0) - { - // Lookup the environment variable - string envValue = Environment.GetEnvironmentVariable(this.Option); - - // If we didn't see it for the process, try a user level variable. - if (envValue == null) - { - envValue = Environment.GetEnvironmentVariable(this.Option, EnvironmentVariableTarget.User); - } - - // If we still didn't find it, try a system level one. - if (envValue == null) - { - envValue = Environment.GetEnvironmentVariable(this.Option, EnvironmentVariableTarget.Machine); - } - - if (envValue != null && envValue.Length > 0) - { - writer.Write(envValue); - } - } - } - catch(System.Security.SecurityException secEx) - { - // This security exception will occur if the caller does not have - // unrestricted environment permission. If this occurs the expansion - // will be skipped with the following warning message. - LogLog.Debug(declaringType, "Security exception while trying to expand environment variables. Error Ignored. No Expansion.", secEx); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Error occurred while converting environment variable.", ex); - } - } - - #region Private Static Fields - - /// - /// The fully qualified type of the EnvironmentPatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(EnvironmentPatternConverter); - - #endregion Private Static Fields - } -} - -#endif // !NETCF diff --git a/src/log4net/Util/PatternStringConverters/IdentityPatternConverter.cs b/src/log4net/Util/PatternStringConverters/IdentityPatternConverter.cs deleted file mode 100644 index 9ea58d75..00000000 --- a/src/log4net/Util/PatternStringConverters/IdentityPatternConverter.cs +++ /dev/null @@ -1,88 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Util; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Write the current thread identity to the output - /// - /// - /// - /// Write the current thread identity to the output writer - /// - /// - /// Nicko Cadell - internal sealed class IdentityPatternConverter : PatternConverter - { - /// - /// Write the current thread identity to the output - /// - /// the writer to write to - /// null, state is not set - /// - /// - /// Writes the current thread identity to the output . - /// - /// - override protected void Convert(TextWriter writer, object state) - { -#if NETCF - // On compact framework there's no notion of current thread principals - writer.Write( SystemInfo.NotAvailableText ); -#else - try - { - if (System.Threading.Thread.CurrentPrincipal != null && - System.Threading.Thread.CurrentPrincipal.Identity != null && - System.Threading.Thread.CurrentPrincipal.Identity.Name != null) - { - writer.Write( System.Threading.Thread.CurrentPrincipal.Identity.Name ); - } - } - catch(System.Security.SecurityException) - { - // This security exception will occur if the caller does not have - // some undefined set of SecurityPermission flags. - LogLog.Debug(declaringType, "Security exception while trying to get current thread principal. Error Ignored."); - - writer.Write( SystemInfo.NotAvailableText ); - } -#endif - } - - #region Private Static Fields - - /// - /// The fully qualified type of the IdentityPatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(IdentityPatternConverter); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/PatternStringConverters/LiteralPatternConverter.cs b/src/log4net/Util/PatternStringConverters/LiteralPatternConverter.cs deleted file mode 100644 index b40925a0..00000000 --- a/src/log4net/Util/PatternStringConverters/LiteralPatternConverter.cs +++ /dev/null @@ -1,107 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Util; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Pattern converter for literal string instances in the pattern - /// - /// - /// - /// Writes the literal string value specified in the - /// property to - /// the output. - /// - /// - /// Nicko Cadell - internal class LiteralPatternConverter : PatternConverter - { - /// - /// Set the next converter in the chain - /// - /// The next pattern converter in the chain - /// The next pattern converter - /// - /// - /// Special case the building of the pattern converter chain - /// for instances. Two adjacent - /// literals in the pattern can be represented by a single combined - /// pattern converter. This implementation detects when a - /// is added to the chain - /// after this converter and combines its value with this converter's - /// literal value. - /// - /// - public override PatternConverter SetNext(PatternConverter pc) - { - LiteralPatternConverter literalPc = pc as LiteralPatternConverter; - if (literalPc != null) - { - // Combine the two adjacent literals together - Option = Option + literalPc.Option; - - // We are the next converter now - return this; - } - - return base.SetNext(pc); - } - - /// - /// Write the literal to the output - /// - /// the writer to write to - /// null, not set - /// - /// - /// Override the formatting behavior to ignore the FormattingInfo - /// because we have a literal instead. - /// - /// - /// Writes the value of - /// to the output . - /// - /// - override public void Format(TextWriter writer, object state) - { - writer.Write(Option); - } - - /// - /// Convert this pattern into the rendered message - /// - /// that will receive the formatted result. - /// null, not set - /// - /// - /// This method is not used. - /// - /// - override protected void Convert(TextWriter writer, object state) - { - throw new InvalidOperationException("Should never get here because of the overridden Format method"); - } - } -} diff --git a/src/log4net/Util/PatternStringConverters/NewLinePatternConverter.cs b/src/log4net/Util/PatternStringConverters/NewLinePatternConverter.cs deleted file mode 100644 index c5b4e7ac..00000000 --- a/src/log4net/Util/PatternStringConverters/NewLinePatternConverter.cs +++ /dev/null @@ -1,91 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Util; -using log4net.Core; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Writes a newline to the output - /// - /// - /// - /// Writes the system dependent line terminator to the output. - /// This behavior can be overridden by setting the : - /// - /// - /// - /// Option Value - /// Output - /// - /// - /// DOS - /// DOS or Windows line terminator "\r\n" - /// - /// - /// UNIX - /// UNIX line terminator "\n" - /// - /// - /// - /// Nicko Cadell - internal sealed class NewLinePatternConverter : LiteralPatternConverter, IOptionHandler - { - #region Implementation of IOptionHandler - - /// - /// Initialize the converter - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - public void ActivateOptions() - { - if (string.Compare(Option, "DOS", true, System.Globalization.CultureInfo.InvariantCulture) == 0) - { - Option = "\r\n"; - } - else if (string.Compare(Option, "UNIX", true, System.Globalization.CultureInfo.InvariantCulture) == 0) - { - Option = "\n"; - } - else - { - Option = SystemInfo.NewLine; - } - } - - #endregion - } -} diff --git a/src/log4net/Util/PatternStringConverters/ProcessIdPatternConverter.cs b/src/log4net/Util/PatternStringConverters/ProcessIdPatternConverter.cs deleted file mode 100644 index 1abf4a5f..00000000 --- a/src/log4net/Util/PatternStringConverters/ProcessIdPatternConverter.cs +++ /dev/null @@ -1,86 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Util; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Write the current process ID to the output - /// - /// - /// - /// Write the current process ID to the output writer - /// - /// - /// Nicko Cadell - internal sealed class ProcessIdPatternConverter : PatternConverter - { - /// - /// Write the current process ID to the output - /// - /// the writer to write to - /// null, state is not set - /// - /// - /// Write the current process ID to the output . - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - override protected void Convert(TextWriter writer, object state) - { -#if NETCF - // On compact framework there is no System.Diagnostics.Process class - writer.Write( SystemInfo.NotAvailableText ); -#else - try - { - writer.Write( System.Diagnostics.Process.GetCurrentProcess().Id ); - } - catch(System.Security.SecurityException) - { - // This security exception will occur if the caller does not have - // some undefined set of SecurityPermission flags. - LogLog.Debug(declaringType, "Security exception while trying to get current process id. Error Ignored."); - - writer.Write( SystemInfo.NotAvailableText ); - } -#endif - } - - #region Private Static Fields - - /// - /// The fully qualified type of the ProcessIdPatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(ProcessIdPatternConverter); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/PatternStringConverters/PropertyPatternConverter.cs b/src/log4net/Util/PatternStringConverters/PropertyPatternConverter.cs deleted file mode 100644 index 3124b31d..00000000 --- a/src/log4net/Util/PatternStringConverters/PropertyPatternConverter.cs +++ /dev/null @@ -1,99 +0,0 @@ -#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 System.Text; -using System.IO; -using System.Collections; - -using log4net.Core; -using log4net.Util; -using log4net.Repository; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Property pattern converter - /// - /// - /// - /// This pattern converter reads the thread and global properties. - /// The thread properties take priority over global properties. - /// See for details of the - /// thread properties. See for - /// details of the global properties. - /// - /// - /// If the is specified then that will be used to - /// lookup a single property. If no is specified - /// then all properties will be dumped as a list of key value pairs. - /// - /// - /// Nicko Cadell - internal sealed class PropertyPatternConverter : PatternConverter - { - /// - /// Write the property value to the output - /// - /// that will receive the formatted result. - /// null, state is not set - /// - /// - /// Writes out the value of a named property. The property name - /// should be set in the - /// property. - /// - /// - /// If the is set to null - /// then all the properties are written as key value pairs. - /// - /// - override protected void Convert(TextWriter writer, object state) - { - CompositeProperties compositeProperties = new CompositeProperties(); - -#if !NETCF - PropertiesDictionary logicalThreadProperties = LogicalThreadContext.Properties.GetProperties(false); - if (logicalThreadProperties != null) - { - compositeProperties.Add(logicalThreadProperties); - } -#endif - PropertiesDictionary threadProperties = ThreadContext.Properties.GetProperties(false); - if (threadProperties != null) - { - compositeProperties.Add(threadProperties); - } - - // TODO: Add Repository Properties - compositeProperties.Add(GlobalContext.Properties.GetReadOnlyProperties()); - - if (Option != null) - { - // Write the value for the specified key - WriteObject(writer, null, compositeProperties[Option]); - } - else - { - // Write all the key value pairs - WriteDictionary(writer, null, compositeProperties.Flatten()); - } - } - } -} diff --git a/src/log4net/Util/PatternStringConverters/RandomStringPatternConverter.cs b/src/log4net/Util/PatternStringConverters/RandomStringPatternConverter.cs deleted file mode 100644 index dc11de95..00000000 --- a/src/log4net/Util/PatternStringConverters/RandomStringPatternConverter.cs +++ /dev/null @@ -1,156 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Util; -using log4net.DateFormatter; -using log4net.Core; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// A Pattern converter that generates a string of random characters - /// - /// - /// - /// The converter generates a string of random characters. By default - /// the string is length 4. This can be changed by setting the - /// to the string value of the length required. - /// - /// - /// The random characters in the string are limited to uppercase letters - /// and numbers only. - /// - /// - /// The random number generator used by this class is not cryptographically secure. - /// - /// - /// Nicko Cadell - internal sealed class RandomStringPatternConverter : PatternConverter, IOptionHandler - { - /// - /// Shared random number generator - /// - private static readonly Random s_random = new Random(); - - /// - /// Length of random string to generate. Default length 4. - /// - private int m_length = 4; - - #region Implementation of IOptionHandler - - /// - /// Initialize the converter options - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - public void ActivateOptions() - { - string optionStr = Option; - if (optionStr != null && optionStr.Length > 0) - { - int lengthVal; - if (SystemInfo.TryParse(optionStr, out lengthVal)) - { - m_length = lengthVal; - } - else - { - LogLog.Error(declaringType, "RandomStringPatternConverter: Could not convert Option ["+optionStr+"] to Length Int32"); - } - } - } - - #endregion - - /// - /// Write a randoim string to the output - /// - /// the writer to write to - /// null, state is not set - /// - /// - /// Write a randoim string to the output . - /// - /// - override protected void Convert(TextWriter writer, object state) - { - try - { - lock(s_random) - { - for(int i=0; i - /// The fully qualified type of the RandomStringPatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(RandomStringPatternConverter); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/PatternStringConverters/UserNamePatternConverter.cs b/src/log4net/Util/PatternStringConverters/UserNamePatternConverter.cs deleted file mode 100644 index b26ee766..00000000 --- a/src/log4net/Util/PatternStringConverters/UserNamePatternConverter.cs +++ /dev/null @@ -1,88 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Util; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Write the current threads username to the output - /// - /// - /// - /// Write the current threads username to the output writer - /// - /// - /// Nicko Cadell - internal sealed class UserNamePatternConverter : PatternConverter - { - /// - /// Write the current threads username to the output - /// - /// the writer to write to - /// null, state is not set - /// - /// - /// Write the current threads username to the output . - /// - /// - override protected void Convert(TextWriter writer, object state) - { -#if NETCF - // On compact framework there's no notion of current Windows user - writer.Write( SystemInfo.NotAvailableText ); -#else - try - { - System.Security.Principal.WindowsIdentity windowsIdentity = null; - windowsIdentity = System.Security.Principal.WindowsIdentity.GetCurrent(); - if (windowsIdentity != null && windowsIdentity.Name != null) - { - writer.Write( windowsIdentity.Name ); - } - } - catch(System.Security.SecurityException) - { - // This security exception will occur if the caller does not have - // some undefined set of SecurityPermission flags. - LogLog.Debug(declaringType, "Security exception while trying to get current windows identity. Error Ignored."); - - writer.Write( SystemInfo.NotAvailableText ); - } -#endif - } - - #region Private Static Fields - - /// - /// The fully qualified type of the UserNamePatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(UserNamePatternConverter); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/PatternStringConverters/UtcDatePatternConverter.cs b/src/log4net/Util/PatternStringConverters/UtcDatePatternConverter.cs deleted file mode 100644 index a2bf590d..00000000 --- a/src/log4net/Util/PatternStringConverters/UtcDatePatternConverter.cs +++ /dev/null @@ -1,86 +0,0 @@ -#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 System.Text; -using System.IO; - -using log4net.Core; -using log4net.Util; -using log4net.DateFormatter; - -namespace log4net.Util.PatternStringConverters -{ - /// - /// Write the UTC date time to the output - /// - /// - /// - /// Date pattern converter, uses a to format - /// the current date and time in Universal time. - /// - /// - /// See the for details on the date pattern syntax. - /// - /// - /// - /// Nicko Cadell - internal class UtcDatePatternConverter : DatePatternConverter - { - /// - /// Write the current date and time to the output - /// - /// that will receive the formatted result. - /// null, state is not set - /// - /// - /// Pass the current date and time to the - /// for it to render it to the writer. - /// - /// - /// The date is in Universal time when it is rendered. - /// - /// - /// - override protected void Convert(TextWriter writer, object state) - { - try - { - m_dateFormatter.FormatDate(DateTime.UtcNow, writer); - } - catch (Exception ex) - { - LogLog.Error(declaringType, "Error occurred while converting date.", ex); - } - } - - #region Private Static Fields - - /// - /// The fully qualified type of the UtcDatePatternConverter class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(UtcDatePatternConverter); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/PropertiesDictionary.cs b/src/log4net/Util/PropertiesDictionary.cs deleted file mode 100644 index be511d57..00000000 --- a/src/log4net/Util/PropertiesDictionary.cs +++ /dev/null @@ -1,335 +0,0 @@ -#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 System.Collections; -#if !NETCF -using System.Runtime.Serialization; -using System.Xml; -#endif - -namespace log4net.Util -{ - /// - /// String keyed object map. - /// - /// - /// - /// While this collection is serializable only member - /// objects that are serializable will - /// be serialized along with this collection. - /// - /// - /// Nicko Cadell - /// Gert Driesen -#if NETCF - public sealed class PropertiesDictionary : ReadOnlyPropertiesDictionary, IDictionary -#else - [Serializable] public sealed class PropertiesDictionary : ReadOnlyPropertiesDictionary, ISerializable, IDictionary -#endif - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public PropertiesDictionary() - { - } - - /// - /// Constructor - /// - /// properties to copy - /// - /// - /// Initializes a new instance of the class. - /// - /// - public PropertiesDictionary(ReadOnlyPropertiesDictionary propertiesDictionary) : base(propertiesDictionary) - { - } - - #endregion Public Instance Constructors - - #region Private Instance Constructors - -#if !NETCF - /// - /// Initializes a new instance of the class - /// with serialized data. - /// - /// The that holds the serialized object data. - /// The that contains contextual information about the source or destination. - /// - /// - /// Because this class is sealed the serialization constructor is private. - /// - /// - private PropertiesDictionary(SerializationInfo info, StreamingContext context) : base(info, context) - { - } -#endif - - #endregion Protected Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the value of the property with the specified key. - /// - /// - /// The value of the property with the specified key. - /// - /// The key of the property to get or set. - /// - /// - /// The property value will only be serialized if it is serializable. - /// If it cannot be serialized it will be silently ignored if - /// a serialization operation is performed. - /// - /// - override public object this[string key] - { - get { return InnerHashtable[key]; } - set { InnerHashtable[key] = value; } - } - - #endregion Public Instance Properties - - #region Public Instance Methods - - /// - /// Remove the entry with the specified key from this dictionary - /// - /// the key for the entry to remove - /// - /// - /// Remove the entry with the specified key from this dictionary - /// - /// - public void Remove(string key) - { - InnerHashtable.Remove(key); - } - - #endregion Public Instance Methods - - #region Implementation of IDictionary - - /// - /// See - /// - /// an enumerator - /// - /// - /// Returns a over the contest of this collection. - /// - /// - IDictionaryEnumerator IDictionary.GetEnumerator() - { - return InnerHashtable.GetEnumerator(); - } - - /// - /// See - /// - /// the key to remove - /// - /// - /// Remove the entry with the specified key from this dictionary - /// - /// - void IDictionary.Remove(object key) - { - InnerHashtable.Remove(key); - } - - /// - /// See - /// - /// the key to lookup in the collection - /// true if the collection contains the specified key - /// - /// - /// Test if this collection contains a specified key. - /// - /// - bool IDictionary.Contains(object key) - { - return InnerHashtable.Contains(key); - } - - /// - /// Remove all properties from the properties collection - /// - /// - /// - /// Remove all properties from the properties collection - /// - /// - public override void Clear() - { - InnerHashtable.Clear(); - } - - /// - /// See - /// - /// the key - /// the value to store for the key - /// - /// - /// Store a value for the specified . - /// - /// - /// Thrown if the is not a string - void IDictionary.Add(object key, object value) - { - if (!(key is string)) - { - throw new ArgumentException("key must be a string", "key"); - } - InnerHashtable.Add(key, value); - } - - /// - /// See - /// - /// - /// false - /// - /// - /// - /// This collection is modifiable. This property always - /// returns false. - /// - /// - bool IDictionary.IsReadOnly - { - get { return false; } - } - - /// - /// See - /// - /// - /// The value for the key specified. - /// - /// - /// - /// Get or set a value for the specified . - /// - /// - /// Thrown if the is not a string - object IDictionary.this[object key] - { - get - { - if (!(key is string)) - { - throw new ArgumentException("key must be a string", "key"); - } - return InnerHashtable[key]; - } - set - { - if (!(key is string)) - { - throw new ArgumentException("key must be a string", "key"); - } - InnerHashtable[key] = value; - } - } - - /// - /// See - /// - ICollection IDictionary.Values - { - get { return InnerHashtable.Values; } - } - - /// - /// See - /// - ICollection IDictionary.Keys - { - get { return InnerHashtable.Keys; } - } - - /// - /// See - /// - bool IDictionary.IsFixedSize - { - get { return false; } - } - - #endregion - - #region Implementation of ICollection - - /// - /// See - /// - /// - /// - void ICollection.CopyTo(Array array, int index) - { - InnerHashtable.CopyTo(array, index); - } - - /// - /// See - /// - bool ICollection.IsSynchronized - { - get { return InnerHashtable.IsSynchronized; } - } - - /// - /// See - /// - object ICollection.SyncRoot - { - get { return InnerHashtable.SyncRoot; } - } - - #endregion - - #region Implementation of IEnumerable - - /// - /// See - /// - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)InnerHashtable).GetEnumerator(); - } - - #endregion - } -} - diff --git a/src/log4net/Util/PropertyEntry.cs b/src/log4net/Util/PropertyEntry.cs deleted file mode 100644 index 3357d989..00000000 --- a/src/log4net/Util/PropertyEntry.cs +++ /dev/null @@ -1,80 +0,0 @@ -/* - * - * 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. - * -*/ - -namespace log4net.Util -{ - /// - /// A class to hold the key and data for a property set in the config file - /// - /// - /// - /// A class to hold the key and data for a property set in the config file - /// - /// - public class PropertyEntry - { - private string m_key = null; - private object m_value = null; - - /// - /// Property Key - /// - /// - /// Property Key - /// - /// - /// - /// Property Key. - /// - /// - public string Key - { - get { return m_key; } - set { m_key = value; } - } - - /// - /// Property Value - /// - /// - /// Property Value - /// - /// - /// - /// Property Value. - /// - /// - public object Value - { - get { return m_value; } - set { m_value = value; } - } - - /// - /// Override Object.ToString to return sensible debug info - /// - /// string info about this object - public override string ToString() - { - return "PropertyEntry(Key=" + m_key + ", Value=" + m_value + ")"; - } - } -} diff --git a/src/log4net/Util/ProtectCloseTextWriter.cs b/src/log4net/Util/ProtectCloseTextWriter.cs deleted file mode 100644 index cd610e2e..00000000 --- a/src/log4net/Util/ProtectCloseTextWriter.cs +++ /dev/null @@ -1,93 +0,0 @@ -#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 System.IO; -using System.Text; - -using log4net.Core; - -namespace log4net.Util -{ - /// - /// A that ignores the message - /// - /// - /// - /// This writer is used in special cases where it is necessary - /// to protect a writer from being closed by a client. - /// - /// - /// Nicko Cadell - public class ProtectCloseTextWriter : TextWriterAdapter - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// the writer to actually write to - /// - /// - /// Create a new ProtectCloseTextWriter using a writer - /// - /// - public ProtectCloseTextWriter(TextWriter writer) : base(writer) - { - } - - #endregion Public Instance Constructors - - #region Public Properties - - /// - /// Attach this instance to a different underlying - /// - /// the writer to attach to - /// - /// - /// Attach this instance to a different underlying - /// - /// - public void Attach(TextWriter writer) - { - this.Writer = writer; - } - - #endregion - - #region Override Implementation of TextWriter - - /// - /// Does not close the underlying output writer. - /// - /// - /// - /// Does not close the underlying output writer. - /// This method does nothing. - /// - /// - override public void Close() - { - // do nothing - } - - #endregion Public Instance Methods - } -} diff --git a/src/log4net/Util/QuietTextWriter.cs b/src/log4net/Util/QuietTextWriter.cs deleted file mode 100644 index 81629b79..00000000 --- a/src/log4net/Util/QuietTextWriter.cs +++ /dev/null @@ -1,205 +0,0 @@ -#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 System.IO; - -using log4net.Core; - -namespace log4net.Util -{ - /// - /// that does not leak exceptions - /// - /// - /// - /// does not throw exceptions when things go wrong. - /// Instead, it delegates error handling to its . - /// - /// - /// Nicko Cadell - /// Gert Driesen - public class QuietTextWriter : TextWriterAdapter - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// the writer to actually write to - /// the error handler to report error to - /// - /// - /// Create a new QuietTextWriter using a writer and error handler - /// - /// - public QuietTextWriter(TextWriter writer, IErrorHandler errorHandler) : base(writer) - { - if (errorHandler == null) - { - throw new ArgumentNullException("errorHandler"); - } - ErrorHandler = errorHandler; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the error handler that all errors are passed to. - /// - /// - /// The error handler that all errors are passed to. - /// - /// - /// - /// Gets or sets the error handler that all errors are passed to. - /// - /// - public IErrorHandler ErrorHandler - { - get { return m_errorHandler; } - set - { - if (value == null) - { - // This is a programming error on the part of the enclosing appender. - throw new ArgumentNullException("value"); - } - m_errorHandler = value; - } - } - - /// - /// Gets a value indicating whether this writer is closed. - /// - /// - /// true if this writer is closed, otherwise false. - /// - /// - /// - /// Gets a value indicating whether this writer is closed. - /// - /// - public bool Closed - { - get { return m_closed; } - } - - #endregion Public Instance Properties - - #region Override Implementation of TextWriter - - /// - /// Writes a character to the underlying writer - /// - /// the char to write - /// - /// - /// Writes a character to the underlying writer - /// - /// - public override void Write(char value) - { - try - { - base.Write(value); - } - catch(Exception e) - { - m_errorHandler.Error("Failed to write [" + value + "].", e, ErrorCode.WriteFailure); - } - } - - /// - /// Writes a buffer to the underlying writer - /// - /// the buffer to write - /// the start index to write from - /// the number of characters to write - /// - /// - /// Writes a buffer to the underlying writer - /// - /// - public override void Write(char[] buffer, int index, int count) - { - try - { - base.Write(buffer, index, count); - } - catch(Exception e) - { - m_errorHandler.Error("Failed to write buffer.", e, ErrorCode.WriteFailure); - } - } - - /// - /// Writes a string to the output. - /// - /// The string data to write to the output. - /// - /// - /// Writes a string to the output. - /// - /// - override public void Write(string value) - { - try - { - base.Write(value); - } - catch(Exception e) - { - m_errorHandler.Error("Failed to write [" + value + "].", e, ErrorCode.WriteFailure); - } - } - - /// - /// Closes the underlying output writer. - /// - /// - /// - /// Closes the underlying output writer. - /// - /// - override public void Close() - { - m_closed = true; - base.Close(); - } - - #endregion Public Instance Methods - - #region Private Instance Fields - - /// - /// The error handler instance to pass all errors to - /// - private IErrorHandler m_errorHandler; - - /// - /// Flag to indicate if this writer is closed - /// - private bool m_closed = false; - - #endregion Private Instance Fields - } -} diff --git a/src/log4net/Util/ReadOnlyPropertiesDictionary.cs b/src/log4net/Util/ReadOnlyPropertiesDictionary.cs deleted file mode 100644 index 619567fe..00000000 --- a/src/log4net/Util/ReadOnlyPropertiesDictionary.cs +++ /dev/null @@ -1,381 +0,0 @@ -#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 System.Collections; -#if !NETCF -using System.Runtime.Serialization; -using System.Xml; -#endif - -namespace log4net.Util -{ - /// - /// String keyed object map that is read only. - /// - /// - /// - /// This collection is readonly and cannot be modified. - /// - /// - /// While this collection is serializable only member - /// objects that are serializable will - /// be serialized along with this collection. - /// - /// - /// Nicko Cadell - /// Gert Driesen -#if NETCF - public class ReadOnlyPropertiesDictionary : IDictionary -#else - [Serializable] public class ReadOnlyPropertiesDictionary : ISerializable, IDictionary -#endif - { - #region Private Instance Fields - - /// - /// The Hashtable used to store the properties data - /// - private readonly Hashtable m_hashtable = new Hashtable(); - - #endregion Private Instance Fields - - #region Public Instance Constructors - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public ReadOnlyPropertiesDictionary() - { - } - - /// - /// Copy Constructor - /// - /// properties to copy - /// - /// - /// Initializes a new instance of the class. - /// - /// - public ReadOnlyPropertiesDictionary(ReadOnlyPropertiesDictionary propertiesDictionary) - { - foreach(DictionaryEntry entry in propertiesDictionary) - { - InnerHashtable.Add(entry.Key, entry.Value); - } - } - - #endregion Public Instance Constructors - - #region Private Instance Constructors - -#if !NETCF - /// - /// Deserialization constructor - /// - /// The that holds the serialized object data. - /// The that contains contextual information about the source or destination. - /// - /// - /// Initializes a new instance of the class - /// with serialized data. - /// - /// - protected ReadOnlyPropertiesDictionary(SerializationInfo info, StreamingContext context) - { - foreach(SerializationEntry entry in info) - { - // The keys are stored as Xml encoded names - InnerHashtable[XmlConvert.DecodeName(entry.Name)] = entry.Value; - } - } -#endif - - #endregion Protected Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the key names. - /// - /// An array of all the keys. - /// - /// - /// Gets the key names. - /// - /// - public string[] GetKeys() - { - string[] keys = new String[InnerHashtable.Count]; - InnerHashtable.Keys.CopyTo(keys, 0); - return keys; - } - - /// - /// Gets or sets the value of the property with the specified key. - /// - /// - /// The value of the property with the specified key. - /// - /// The key of the property to get or set. - /// - /// - /// The property value will only be serialized if it is serializable. - /// If it cannot be serialized it will be silently ignored if - /// a serialization operation is performed. - /// - /// - public virtual object this[string key] - { - get { return InnerHashtable[key]; } - set { throw new NotSupportedException("This is a Read Only Dictionary and can not be modified"); } - } - - #endregion Public Instance Properties - - #region Public Instance Methods - - /// - /// Test if the dictionary contains a specified key - /// - /// the key to look for - /// true if the dictionary contains the specified key - /// - /// - /// Test if the dictionary contains a specified key - /// - /// - public bool Contains(string key) - { - return InnerHashtable.Contains(key); - } - - #endregion - - /// - /// The hashtable used to store the properties - /// - /// - /// The internal collection used to store the properties - /// - /// - /// - /// The hashtable used to store the properties - /// - /// - protected Hashtable InnerHashtable - { - get { return m_hashtable; } - } - - #region Implementation of ISerializable - -#if !NETCF - /// - /// Serializes this object into the provided. - /// - /// The to populate with data. - /// The destination for this serialization. - /// - /// - /// Serializes this object into the provided. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecurityCritical] -#else - [System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.Demand, SerializationFormatter=true)] -#endif - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - foreach(DictionaryEntry entry in InnerHashtable.Clone() as IDictionary) - { - string entryKey = entry.Key as string; - object entryValue = entry.Value; - - // If value is serializable then we add it to the list - if (entryKey != null && entryValue != null && entryValue.GetType().IsSerializable) - { - // Store the keys as an Xml encoded local name as it may contain colons (':') - // which are NOT escaped by the Xml Serialization framework. - // This must be a bug in the serialization framework as we cannot be expected - // to know the implementation details of all the possible transport layers. - info.AddValue(XmlConvert.EncodeLocalName(entryKey), entryValue); - } - } - } -#endif - - #endregion Implementation of ISerializable - - #region Implementation of IDictionary - - /// - /// See - /// - IDictionaryEnumerator IDictionary.GetEnumerator() - { - return InnerHashtable.GetEnumerator(); - } - - /// - /// See - /// - /// - void IDictionary.Remove(object key) - { - throw new NotSupportedException("This is a Read Only Dictionary and can not be modified"); - } - - /// - /// See - /// - /// - /// - bool IDictionary.Contains(object key) - { - return InnerHashtable.Contains(key); - } - - /// - /// Remove all properties from the properties collection - /// - public virtual void Clear() - { - throw new NotSupportedException("This is a Read Only Dictionary and can not be modified"); - } - - /// - /// See - /// - /// - /// - void IDictionary.Add(object key, object value) - { - throw new NotSupportedException("This is a Read Only Dictionary and can not be modified"); - } - - /// - /// See - /// - bool IDictionary.IsReadOnly - { - get { return true; } - } - - /// - /// See - /// - object IDictionary.this[object key] - { - get - { - if (!(key is string)) throw new ArgumentException("key must be a string"); - return InnerHashtable[key]; - } - set - { - throw new NotSupportedException("This is a Read Only Dictionary and can not be modified"); - } - } - - /// - /// See - /// - ICollection IDictionary.Values - { - get { return InnerHashtable.Values; } - } - - /// - /// See - /// - ICollection IDictionary.Keys - { - get { return InnerHashtable.Keys; } - } - - /// - /// See - /// - bool IDictionary.IsFixedSize - { - get { return InnerHashtable.IsFixedSize; } - } - - #endregion - - #region Implementation of ICollection - - /// - /// See - /// - /// - /// - void ICollection.CopyTo(Array array, int index) - { - InnerHashtable.CopyTo(array, index); - } - - /// - /// See - /// - bool ICollection.IsSynchronized - { - get { return InnerHashtable.IsSynchronized; } - } - - /// - /// The number of properties in this collection - /// - public int Count - { - get { return InnerHashtable.Count; } - } - - /// - /// See - /// - object ICollection.SyncRoot - { - get { return InnerHashtable.SyncRoot; } - } - - #endregion - - #region Implementation of IEnumerable - - /// - /// See - /// - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)InnerHashtable).GetEnumerator(); - } - - #endregion - } -} - diff --git a/src/log4net/Util/ReaderWriterLock.cs b/src/log4net/Util/ReaderWriterLock.cs deleted file mode 100644 index 91f93cfd..00000000 --- a/src/log4net/Util/ReaderWriterLock.cs +++ /dev/null @@ -1,191 +0,0 @@ -#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 - -#if !NETCF -#define HAS_READERWRITERLOCK -#if FRAMEWORK_4_0_OR_ABOVE -#define HAS_READERWRITERLOCKSLIM -#endif -#endif - -using System; - -namespace log4net.Util -{ - /// - /// Defines a lock that supports single writers and multiple readers - /// - /// - /// - /// ReaderWriterLock is used to synchronize access to a resource. - /// At any given time, it allows either concurrent read access for - /// multiple threads, or write access for a single thread. In a - /// situation where a resource is changed infrequently, a - /// ReaderWriterLock provides better throughput than a simple - /// one-at-a-time lock, such as . - /// - /// - /// If a platform does not support a System.Threading.ReaderWriterLock - /// implementation then all readers and writers are serialized. Therefore - /// the caller must not rely on multiple simultaneous readers. - /// - /// - /// Nicko Cadell - public sealed class ReaderWriterLock - { - #region Instance Constructors - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public ReaderWriterLock() - { - -#if HAS_READERWRITERLOCK -#if HAS_READERWRITERLOCKSLIM - m_lock = new System.Threading.ReaderWriterLockSlim(); -#else - m_lock = new System.Threading.ReaderWriterLock(); -#endif -#endif - } - - #endregion Private Instance Constructors - - #region Public Methods - - /// - /// Acquires a reader lock - /// - /// - /// - /// blocks if a different thread has the writer - /// lock, or if at least one thread is waiting for the writer lock. - /// - /// - public void AcquireReaderLock() - { -#if HAS_READERWRITERLOCK -#if HAS_READERWRITERLOCKSLIM - // prevent ThreadAbort while updating state, see https://issues.apache.org/jira/browse/LOG4NET-443 - try { } - finally - { - m_lock.EnterReadLock(); - } -#else - m_lock.AcquireReaderLock(-1); -#endif -#else - System.Threading.Monitor.Enter(this); -#endif - } - - /// - /// Decrements the lock count - /// - /// - /// - /// decrements the lock count. When the count - /// reaches zero, the lock is released. - /// - /// - public void ReleaseReaderLock() - { -#if HAS_READERWRITERLOCK -#if HAS_READERWRITERLOCKSLIM - m_lock.ExitReadLock(); -#else - m_lock.ReleaseReaderLock(); - -#endif -#else - System.Threading.Monitor.Exit(this); -#endif - } - - /// - /// Acquires the writer lock - /// - /// - /// - /// This method blocks if another thread has a reader lock or writer lock. - /// - /// - public void AcquireWriterLock() - { -#if HAS_READERWRITERLOCK -#if HAS_READERWRITERLOCKSLIM - // prevent ThreadAbort while updating state, see https://issues.apache.org/jira/browse/LOG4NET-443 - try { } - finally - { - m_lock.EnterWriteLock(); - } -#else - m_lock.AcquireWriterLock(-1); -#endif -#else - System.Threading.Monitor.Enter(this); -#endif - } - - /// - /// Decrements the lock count on the writer lock - /// - /// - /// - /// ReleaseWriterLock decrements the writer lock count. - /// When the count reaches zero, the writer lock is released. - /// - /// - public void ReleaseWriterLock() - { -#if HAS_READERWRITERLOCK -#if HAS_READERWRITERLOCKSLIM - m_lock.ExitWriteLock(); -#else - m_lock.ReleaseWriterLock(); -#endif -#else - System.Threading.Monitor.Exit(this); -#endif - } - - #endregion Public Methods - - #region Private Members - -#if HAS_READERWRITERLOCK -#if HAS_READERWRITERLOCKSLIM - private System.Threading.ReaderWriterLockSlim m_lock; -#else - private System.Threading.ReaderWriterLock m_lock; -#endif - -#endif - - #endregion - } -} \ No newline at end of file diff --git a/src/log4net/Util/ReusableStringWriter.cs b/src/log4net/Util/ReusableStringWriter.cs deleted file mode 100644 index 8c1aad13..00000000 --- a/src/log4net/Util/ReusableStringWriter.cs +++ /dev/null @@ -1,94 +0,0 @@ -#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 System.Text; -using System.IO; - -namespace log4net.Util -{ - /// - /// A that can be and reused - /// - /// - /// - /// A that can be and reused. - /// This uses a single buffer for string operations. - /// - /// - /// Nicko Cadell - public class ReusableStringWriter : StringWriter - { - #region Constructor - - /// - /// Create an instance of - /// - /// the format provider to use - /// - /// - /// Create an instance of - /// - /// - public ReusableStringWriter(IFormatProvider formatProvider) : base(formatProvider) - { - } - - #endregion - - /// - /// Override Dispose to prevent closing of writer - /// - /// flag - /// - /// - /// Override Dispose to prevent closing of writer - /// - /// - protected override void Dispose(bool disposing) - { - // Do not close the writer - } - - /// - /// Reset this string writer so that it can be reused. - /// - /// the maximum buffer capacity before it is trimmed - /// the default size to make the buffer - /// - /// - /// Reset this string writer so that it can be reused. - /// The internal buffers are cleared and reset. - /// - /// - public void Reset(int maxCapacity, int defaultSize) - { - // Reset working string buffer - StringBuilder sb = this.GetStringBuilder(); - - sb.Length = 0; - - // Check if over max size - if (sb.Capacity > maxCapacity) - { - sb.Capacity = defaultSize; - } - } - } -} diff --git a/src/log4net/Util/SystemInfo.cs b/src/log4net/Util/SystemInfo.cs deleted file mode 100644 index 482d1a4e..00000000 --- a/src/log4net/Util/SystemInfo.cs +++ /dev/null @@ -1,1113 +0,0 @@ -#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 System.Configuration; -using System.Reflection; -using System.Text; -using System.IO; -using System.Runtime.InteropServices; -using System.Collections; - -namespace log4net.Util -{ - /// - /// Utility class for system specific information. - /// - /// - /// - /// Utility class of static methods for system specific information. - /// - /// - /// Nicko Cadell - /// Gert Driesen - /// Alexey Solofnenko - public sealed class SystemInfo - { - #region Private Constants - - private const string DEFAULT_NULL_TEXT = "(null)"; - private const string DEFAULT_NOT_AVAILABLE_TEXT = "NOT AVAILABLE"; - - #endregion - - #region Private Instance Constructors - - /// - /// Private constructor to prevent instances. - /// - /// - /// - /// Only static methods are exposed from this type. - /// - /// - private SystemInfo() - { - } - - #endregion Private Instance Constructors - - #region Public Static Constructor - - /// - /// Initialize default values for private static fields. - /// - /// - /// - /// Only static methods are exposed from this type. - /// - /// - static SystemInfo() - { - string nullText = DEFAULT_NULL_TEXT; - string notAvailableText = DEFAULT_NOT_AVAILABLE_TEXT; - -#if !NETCF - // Look for log4net.NullText in AppSettings - string nullTextAppSettingsKey = SystemInfo.GetAppSetting("log4net.NullText"); - if (nullTextAppSettingsKey != null && nullTextAppSettingsKey.Length > 0) - { - LogLog.Debug(declaringType, "Initializing NullText value to [" + nullTextAppSettingsKey + "]."); - nullText = nullTextAppSettingsKey; - } - - // Look for log4net.NotAvailableText in AppSettings - string notAvailableTextAppSettingsKey = SystemInfo.GetAppSetting("log4net.NotAvailableText"); - if (notAvailableTextAppSettingsKey != null && notAvailableTextAppSettingsKey.Length > 0) - { - LogLog.Debug(declaringType, "Initializing NotAvailableText value to [" + notAvailableTextAppSettingsKey + "]."); - notAvailableText = notAvailableTextAppSettingsKey; - } -#endif - s_notAvailableText = notAvailableText; - s_nullText = nullText; - } - - #endregion - - #region Public Static Properties - - /// - /// Gets the system dependent line terminator. - /// - /// - /// The system dependent line terminator. - /// - /// - /// - /// Gets the system dependent line terminator. - /// - /// - public static string NewLine - { - get - { -#if NETCF - return "\r\n"; -#else - return System.Environment.NewLine; -#endif - } - } - - /// - /// Gets the base directory for this . - /// - /// The base directory path for the current . - /// - /// - /// Gets the base directory for this . - /// - /// - /// The value returned may be either a local file path or a URI. - /// - /// - public static string ApplicationBaseDirectory - { - get - { -#if NETCF - return System.IO.Path.GetDirectoryName(SystemInfo.EntryAssemblyLocation) + System.IO.Path.DirectorySeparatorChar; -#else - return AppDomain.CurrentDomain.BaseDirectory; -#endif - } - } - - /// - /// Gets the path to the configuration file for the current . - /// - /// The path to the configuration file for the current . - /// - /// - /// The .NET Compact Framework 1.0 does not have a concept of a configuration - /// file. For this runtime, we use the entry assembly location as the root for - /// the configuration file name. - /// - /// - /// The value returned may be either a local file path or a URI. - /// - /// - public static string ConfigurationFileLocation - { - get - { -#if NETCF - return SystemInfo.EntryAssemblyLocation+".config"; -#else - return System.AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; -#endif - } - } - - /// - /// Gets the path to the file that first executed in the current . - /// - /// The path to the entry assembly. - /// - /// - /// Gets the path to the file that first executed in the current . - /// - /// - public static string EntryAssemblyLocation - { - get - { -#if NETCF - return SystemInfo.NativeEntryAssemblyLocation; -#else - return System.Reflection.Assembly.GetEntryAssembly().Location; -#endif - } - } - - /// - /// Gets the ID of the current thread. - /// - /// The ID of the current thread. - /// - /// - /// On the .NET framework, the AppDomain.GetCurrentThreadId method - /// is used to obtain the thread ID for the current thread. This is the - /// operating system ID for the thread. - /// - /// - /// On the .NET Compact Framework 1.0 it is not possible to get the - /// operating system thread ID for the current thread. The native method - /// GetCurrentThreadId is implemented inline in a header file - /// and cannot be called. - /// - /// - /// On the .NET Framework 2.0 the Thread.ManagedThreadId is used as this - /// gives a stable id unrelated to the operating system thread ID which may - /// change if the runtime is using fibers. - /// - /// - public static int CurrentThreadId - { - get - { - return System.Threading.Thread.CurrentThread.ManagedThreadId; - } - } - - /// - /// Get the host name or machine name for the current machine - /// - /// - /// The hostname or machine name - /// - /// - /// - /// Get the host name or machine name for the current machine - /// - /// - /// The host name () or - /// the machine name (Environment.MachineName) for - /// the current machine, or if neither of these are available - /// then NOT AVAILABLE is returned. - /// - /// - public static string HostName - { - get - { - if (s_hostName == null) - { - - // Get the DNS host name of the current machine - try - { - // Lookup the host name - s_hostName = System.Net.Dns.GetHostName(); - } - catch (System.Net.Sockets.SocketException) - { - LogLog.Debug(declaringType, "Socket exception occurred while getting the dns hostname. Error Ignored."); - } - catch (System.Security.SecurityException) - { - // We may get a security exception looking up the hostname - // You must have Unrestricted DnsPermission to access resource - LogLog.Debug(declaringType, "Security exception occurred while getting the dns hostname. Error Ignored."); - } - catch (Exception ex) - { - LogLog.Debug(declaringType, "Some other exception occurred while getting the dns hostname. Error Ignored.", ex); - } - - // Get the NETBIOS machine name of the current machine - if (s_hostName == null || s_hostName.Length == 0) - { - try - { -#if !NETCF - s_hostName = Environment.MachineName; -#endif - } - catch(InvalidOperationException) - { - } - catch(System.Security.SecurityException) - { - // We may get a security exception looking up the machine name - // You must have Unrestricted EnvironmentPermission to access resource - } - } - - // Couldn't find a value - if (s_hostName == null || s_hostName.Length == 0) - { - s_hostName = s_notAvailableText; - LogLog.Debug(declaringType, "Could not determine the hostname. Error Ignored. Empty host name will be used"); - } - } - return s_hostName; - } - } - - /// - /// Get this application's friendly name - /// - /// - /// The friendly name of this application as a string - /// - /// - /// - /// If available the name of the application is retrieved from - /// the AppDomain using AppDomain.CurrentDomain.FriendlyName. - /// - /// - /// Otherwise the file name of the entry assembly is used. - /// - /// - public static string ApplicationFriendlyName - { - get - { - if (s_appFriendlyName == null) - { - try - { -#if !NETCF - s_appFriendlyName = AppDomain.CurrentDomain.FriendlyName; -#endif - } - catch(System.Security.SecurityException) - { - // This security exception will occur if the caller does not have - // some undefined set of SecurityPermission flags. - LogLog.Debug(declaringType, "Security exception while trying to get current domain friendly name. Error Ignored."); - } - - if (s_appFriendlyName == null || s_appFriendlyName.Length == 0) - { - try - { - string assemblyLocation = SystemInfo.EntryAssemblyLocation; - s_appFriendlyName = System.IO.Path.GetFileName(assemblyLocation); - } - catch(System.Security.SecurityException) - { - // Caller needs path discovery permission - } - } - - if (s_appFriendlyName == null || s_appFriendlyName.Length == 0) - { - s_appFriendlyName = s_notAvailableText; - } - } - return s_appFriendlyName; - } - } - - /// - /// Get the start time for the current process. - /// - /// - /// - /// This is the time at which the log4net library was loaded into the - /// AppDomain. Due to reports of a hang in the call to System.Diagnostics.Process.StartTime - /// this is not the start time for the current process. - /// - /// - /// The log4net library should be loaded by an application early during its - /// startup, therefore this start time should be a good approximation for - /// the actual start time. - /// - /// - /// Note that AppDomains may be loaded and unloaded within the - /// same process without the process terminating, however this start time - /// will be set per AppDomain. - /// - /// - public static DateTime ProcessStartTime - { - get { return s_processStartTime; } - } - - /// - /// Text to output when a null is encountered. - /// - /// - /// - /// Use this value to indicate a null has been encountered while - /// outputting a string representation of an item. - /// - /// - /// The default value is (null). This value can be overridden by specifying - /// a value for the log4net.NullText appSetting in the application's - /// .config file. - /// - /// - public static string NullText - { - get { return s_nullText; } - set { s_nullText = value; } - } - - /// - /// Text to output when an unsupported feature is requested. - /// - /// - /// - /// Use this value when an unsupported feature is requested. - /// - /// - /// The default value is NOT AVAILABLE. This value can be overridden by specifying - /// a value for the log4net.NotAvailableText appSetting in the application's - /// .config file. - /// - /// - public static string NotAvailableText - { - get { return s_notAvailableText; } - set { s_notAvailableText = value; } - } - - #endregion Public Static Properties - - #region Public Static Methods - - /// - /// Gets the assembly location path for the specified assembly. - /// - /// The assembly to get the location for. - /// The location of the assembly. - /// - /// - /// This method does not guarantee to return the correct path - /// to the assembly. If only tries to give an indication as to - /// where the assembly was loaded from. - /// - /// - public static string AssemblyLocationInfo(Assembly myAssembly) - { -#if NETCF - return "Not supported on Microsoft .NET Compact Framework"; -#else - if (myAssembly.GlobalAssemblyCache) - { - return "Global Assembly Cache"; - } - else - { - try - { -#if FRAMEWORK_4_0_OR_ABOVE - if (myAssembly.IsDynamic) - { - return "Dynamic Assembly"; - } -#else - if (myAssembly is System.Reflection.Emit.AssemblyBuilder) - { - return "Dynamic Assembly"; - } - else if(myAssembly.GetType().FullName == "System.Reflection.Emit.InternalAssemblyBuilder") - { - return "Dynamic Assembly"; - } -#endif - else - { - // This call requires FileIOPermission for access to the path - // if we don't have permission then we just ignore it and - // carry on. - return myAssembly.Location; - } - } - catch (NotSupportedException) - { - // The location information may be unavailable for dynamic assemblies and a NotSupportedException - // is thrown in those cases. See: http://msdn.microsoft.com/de-de/library/system.reflection.assembly.location.aspx - return "Dynamic Assembly"; - } - catch (TargetInvocationException ex) - { - return "Location Detect Failed (" + ex.Message + ")"; - } - catch (ArgumentException ex) - { - return "Location Detect Failed (" + ex.Message + ")"; - } - catch (System.Security.SecurityException) - { - return "Location Permission Denied"; - } - } -#endif - } - - /// - /// Gets the fully qualified name of the , including - /// the name of the assembly from which the was - /// loaded. - /// - /// The to get the fully qualified name for. - /// The fully qualified name for the . - /// - /// - /// This is equivalent to the Type.AssemblyQualifiedName property, - /// but this method works on the .NET Compact Framework 1.0 as well as - /// the full .NET runtime. - /// - /// - public static string AssemblyQualifiedName(Type type) - { - return type.FullName + ", " + type.Assembly.FullName; - } - - /// - /// Gets the short name of the . - /// - /// The to get the name for. - /// The short name of the . - /// - /// - /// The short name of the assembly is the - /// without the version, culture, or public key. i.e. it is just the - /// assembly's file name without the extension. - /// - /// - /// Use this rather than Assembly.GetName().Name because that - /// is not available on the Compact Framework. - /// - /// - /// Because of a FileIOPermission security demand we cannot do - /// the obvious Assembly.GetName().Name. We are allowed to get - /// the of the assembly so we - /// start from there and strip out just the assembly name. - /// - /// - public static string AssemblyShortName(Assembly myAssembly) - { - string name = myAssembly.FullName; - int offset = name.IndexOf(','); - if (offset > 0) - { - name = name.Substring(0, offset); - } - return name.Trim(); - - // TODO: Do we need to unescape the assembly name string? - // Doc says '\' is an escape char but has this already been - // done by the string loader? - } - - /// - /// Gets the file name portion of the , including the extension. - /// - /// The to get the file name for. - /// The file name of the assembly. - /// - /// - /// Gets the file name portion of the , including the extension. - /// - /// - public static string AssemblyFileName(Assembly myAssembly) - { -#if NETCF - // This is not very good because it assumes that only - // the entry assembly can be an EXE. In fact multiple - // EXEs can be loaded in to a process. - - string assemblyShortName = SystemInfo.AssemblyShortName(myAssembly); - string entryAssemblyShortName = System.IO.Path.GetFileNameWithoutExtension(SystemInfo.EntryAssemblyLocation); - - if (string.Compare(assemblyShortName, entryAssemblyShortName, true) == 0) - { - // assembly is entry assembly - return assemblyShortName + ".exe"; - } - else - { - // assembly is not entry assembly - return assemblyShortName + ".dll"; - } -#else - return System.IO.Path.GetFileName(myAssembly.Location); -#endif - } - - /// - /// Loads the type specified in the type string. - /// - /// A sibling type to use to load the type. - /// The name of the type to load. - /// Flag set to true to throw an exception if the type cannot be loaded. - /// true to ignore the case of the type name; otherwise, false - /// The type loaded or null if it could not be loaded. - /// - /// - /// If the type name is fully qualified, i.e. if contains an assembly name in - /// the type name, the type will be loaded from the system using - /// . - /// - /// - /// If the type name is not fully qualified, it will be loaded from the assembly - /// containing the specified relative type. If the type is not found in the assembly - /// then all the loaded assemblies will be searched for the type. - /// - /// - public static Type GetTypeFromString(Type relativeType, string typeName, bool throwOnError, bool ignoreCase) - { - return GetTypeFromString(relativeType.Assembly, typeName, throwOnError, ignoreCase); - } - - /// - /// Loads the type specified in the type string. - /// - /// The name of the type to load. - /// Flag set to true to throw an exception if the type cannot be loaded. - /// true to ignore the case of the type name; otherwise, false - /// The type loaded or null if it could not be loaded. - /// - /// - /// If the type name is fully qualified, i.e. if contains an assembly name in - /// the type name, the type will be loaded from the system using - /// . - /// - /// - /// If the type name is not fully qualified it will be loaded from the - /// assembly that is directly calling this method. If the type is not found - /// in the assembly then all the loaded assemblies will be searched for the type. - /// - /// - public static Type GetTypeFromString(string typeName, bool throwOnError, bool ignoreCase) - { - return GetTypeFromString(Assembly.GetCallingAssembly(), typeName, throwOnError, ignoreCase); - } - - /// - /// Loads the type specified in the type string. - /// - /// An assembly to load the type from. - /// The name of the type to load. - /// Flag set to true to throw an exception if the type cannot be loaded. - /// true to ignore the case of the type name; otherwise, false - /// The type loaded or null if it could not be loaded. - /// - /// - /// If the type name is fully qualified, i.e. if contains an assembly name in - /// the type name, the type will be loaded from the system using - /// . - /// - /// - /// If the type name is not fully qualified it will be loaded from the specified - /// assembly. If the type is not found in the assembly then all the loaded assemblies - /// will be searched for the type. - /// - /// - public static Type GetTypeFromString(Assembly relativeAssembly, string typeName, bool throwOnError, bool ignoreCase) - { - // Check if the type name specifies the assembly name - if(typeName.IndexOf(',') == -1) - { - //LogLog.Debug(declaringType, "SystemInfo: Loading type ["+typeName+"] from assembly ["+relativeAssembly.FullName+"]"); -#if NETCF - return relativeAssembly.GetType(typeName, throwOnError); -#else - // Attempt to lookup the type from the relativeAssembly - Type type = relativeAssembly.GetType(typeName, false, ignoreCase); - if (type != null) - { - // Found type in relative assembly - //LogLog.Debug(declaringType, "SystemInfo: Loaded type ["+typeName+"] from assembly ["+relativeAssembly.FullName+"]"); - return type; - } - - Assembly[] loadedAssemblies = null; - try - { - loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); - } - catch(System.Security.SecurityException) - { - // Insufficient permissions to get the list of loaded assemblies - } - - if (loadedAssemblies != null) - { - Type fallback = null; - // Search the loaded assemblies for the type - foreach (Assembly assembly in loadedAssemblies) - { - Type t = assembly.GetType(typeName, false, ignoreCase); - if (t != null) - { - // Found type in loaded assembly - LogLog.Debug(declaringType, "Loaded type ["+typeName+"] from assembly ["+assembly.FullName+"] by searching loaded assemblies."); - if (assembly.GlobalAssemblyCache) - { - fallback = t; - } - else - { - return t; - } - } - } - if (fallback != null) - { - return fallback; - } - } - - // Didn't find the type - if (throwOnError) - { - throw new TypeLoadException("Could not load type ["+typeName+"]. Tried assembly ["+relativeAssembly.FullName+"] and all loaded assemblies"); - } - return null; -#endif - } - else - { - // Includes explicit assembly name - //LogLog.Debug(declaringType, "SystemInfo: Loading type ["+typeName+"] from global Type"); - -#if NETCF - // In NETCF 2 and 3 arg versions seem to behave differently - // https://issues.apache.org/jira/browse/LOG4NET-113 - return Type.GetType(typeName, throwOnError); -#else - return Type.GetType(typeName, throwOnError, ignoreCase); -#endif - } - } - - - /// - /// Generate a new guid - /// - /// A new Guid - /// - /// - /// Generate a new guid - /// - /// - public static Guid NewGuid() - { - return Guid.NewGuid(); - } - - /// - /// Create an - /// - /// The name of the parameter that caused the exception - /// The value of the argument that causes this exception - /// The message that describes the error - /// the ArgumentOutOfRangeException object - /// - /// - /// Create a new instance of the class - /// with a specified error message, the parameter name, and the value - /// of the argument. - /// - /// - /// The Compact Framework does not support the 3 parameter constructor for the - /// type. This method provides an - /// implementation that works for all platforms. - /// - /// - public static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(string parameterName, object actualValue, string message) - { -#if NETCF - return new ArgumentOutOfRangeException(parameterName, message + " [value=" + actualValue + "]"); -#else - return new ArgumentOutOfRangeException(parameterName, actualValue, message); -#endif - } - - - /// - /// Parse a string into an value - /// - /// the string to parse - /// out param where the parsed value is placed - /// true if the string was able to be parsed into an integer - /// - /// - /// Attempts to parse the string into an integer. If the string cannot - /// be parsed then this method returns false. The method does not throw an exception. - /// - /// - public static bool TryParse(string s, out int val) - { -#if NETCF - val = 0; - try - { - val = int.Parse(s, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture); - return true; - } - catch - { - } - - return false; -#else - // Initialise out param - val = 0; - - try - { - double doubleVal; - if (Double.TryParse(s, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out doubleVal)) - { - val = Convert.ToInt32(doubleVal); - return true; - } - } - catch - { - // Ignore exception, just return false - } - - return false; -#endif - } - - /// - /// Parse a string into an value - /// - /// the string to parse - /// out param where the parsed value is placed - /// true if the string was able to be parsed into an integer - /// - /// - /// Attempts to parse the string into an integer. If the string cannot - /// be parsed then this method returns false. The method does not throw an exception. - /// - /// - public static bool TryParse(string s, out long val) - { -#if NETCF - val = 0; - try - { - val = long.Parse(s, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture); - return true; - } - catch - { - } - - return false; -#else - // Initialise out param - val = 0; - - try - { - double doubleVal; - if (Double.TryParse(s, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out doubleVal)) - { - val = Convert.ToInt64(doubleVal); - return true; - } - } - catch - { - // Ignore exception, just return false - } - - return false; -#endif - } - - /// - /// Parse a string into an value - /// - /// the string to parse - /// out param where the parsed value is placed - /// true if the string was able to be parsed into an integer - /// - /// - /// Attempts to parse the string into an integer. If the string cannot - /// be parsed then this method returns false. The method does not throw an exception. - /// - /// - public static bool TryParse(string s, out short val) - { -#if NETCF - val = 0; - try - { - val = short.Parse(s, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture); - return true; - } - catch - { - } - - return false; -#else - // Initialise out param - val = 0; - - try - { - double doubleVal; - if (Double.TryParse(s, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out doubleVal)) - { - val = Convert.ToInt16(doubleVal); - return true; - } - } - catch - { - // Ignore exception, just return false - } - - return false; -#endif - } - - /// - /// Lookup an application setting - /// - /// the application settings key to lookup - /// the value for the key, or null - /// - /// - /// Configuration APIs are not supported under the Compact Framework - /// - /// - public static string GetAppSetting(string key) - { -#if NETCF - // Configuration APIs are not suported under the Compact Framework -#else - try - { - return ConfigurationManager.AppSettings[key]; - } - catch(Exception ex) - { - // If an exception is thrown here then it looks like the config file does not parse correctly. - LogLog.Error(declaringType, "Exception while reading ConfigurationSettings. Check your .config file is well formed XML.", ex); - } -#endif - return null; - } - - /// - /// Convert a path into a fully qualified local file path. - /// - /// The path to convert. - /// The fully qualified path. - /// - /// - /// Converts the path specified to a fully - /// qualified path. If the path is relative it is - /// taken as relative from the application base - /// directory. - /// - /// - /// The path specified must be a local file path, a URI is not supported. - /// - /// - public static string ConvertToFullPath(string path) - { - if (path == null) - { - throw new ArgumentNullException("path"); - } - - string baseDirectory = ""; - try - { - string applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; - if (applicationBaseDirectory != null) - { - // applicationBaseDirectory may be a URI not a local file path - Uri applicationBaseDirectoryUri = new Uri(applicationBaseDirectory); - if (applicationBaseDirectoryUri.IsFile) - { - baseDirectory = applicationBaseDirectoryUri.LocalPath; - } - } - } - catch - { - // Ignore URI exceptions & SecurityExceptions from SystemInfo.ApplicationBaseDirectory - } - - if (baseDirectory != null && baseDirectory.Length > 0) - { - // Note that Path.Combine will return the second path if it is rooted - return Path.GetFullPath(Path.Combine(baseDirectory, path)); - } - return Path.GetFullPath(path); - } - - /// - /// Creates a new case-insensitive instance of the class with the default initial capacity. - /// - /// A new case-insensitive instance of the class with the default initial capacity - /// - /// - /// The new Hashtable instance uses the default load factor, the CaseInsensitiveHashCodeProvider, and the CaseInsensitiveComparer. - /// - /// - public static Hashtable CreateCaseInsensitiveHashtable() - { - return new Hashtable(StringComparer.OrdinalIgnoreCase); - } - - #endregion Public Static Methods - - #region Private Static Methods - -#if NETCF - private static string NativeEntryAssemblyLocation - { - get - { - StringBuilder moduleName = null; - - IntPtr moduleHandle = GetModuleHandle(IntPtr.Zero); - - if (moduleHandle != IntPtr.Zero) - { - moduleName = new StringBuilder(255); - if (GetModuleFileName(moduleHandle, moduleName, moduleName.Capacity) == 0) - { - throw new NotSupportedException(NativeError.GetLastError().ToString()); - } - } - else - { - throw new NotSupportedException(NativeError.GetLastError().ToString()); - } - - return moduleName.ToString(); - } - } - - [DllImport("CoreDll.dll", SetLastError=true, CharSet=CharSet.Unicode)] - private static extern IntPtr GetModuleHandle(IntPtr ModuleName); - - [DllImport("CoreDll.dll", SetLastError=true, CharSet=CharSet.Unicode)] - private static extern Int32 GetModuleFileName( - IntPtr hModule, - StringBuilder ModuleName, - Int32 cch); - -#endif - - #endregion Private Static Methods - - #region Public Static Fields - - /// - /// Gets an empty array of types. - /// - /// - /// - /// The Type.EmptyTypes field is not available on - /// the .NET Compact Framework 1.0. - /// - /// - public static readonly Type[] EmptyTypes = new Type[0]; - - #endregion Public Static Fields - - #region Private Static Fields - - /// - /// The fully qualified type of the SystemInfo class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(SystemInfo); - - /// - /// Cache the host name for the current machine - /// - private static string s_hostName; - - /// - /// Cache the application friendly name - /// - private static string s_appFriendlyName; - - /// - /// Text to output when a null is encountered. - /// - private static string s_nullText; - - /// - /// Text to output when an unsupported feature is requested. - /// - private static string s_notAvailableText; - - /// - /// Start time for the current process. - /// - private static DateTime s_processStartTime = DateTime.Now; - - #endregion - } -} diff --git a/src/log4net/Util/SystemStringFormat.cs b/src/log4net/Util/SystemStringFormat.cs deleted file mode 100644 index d7e504fd..00000000 --- a/src/log4net/Util/SystemStringFormat.cs +++ /dev/null @@ -1,237 +0,0 @@ -#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 System.Text; -using System.Xml; -using System.Text.RegularExpressions; - -namespace log4net.Util -{ - /// - /// Utility class that represents a format string. - /// - /// - /// - /// Utility class that represents a format string. - /// - /// - /// Nicko Cadell - public sealed class SystemStringFormat - { - private readonly IFormatProvider m_provider; - private readonly string m_format; - private readonly object[] m_args; - - #region Constructor - - /// - /// Initialise the - /// - /// An that supplies culture-specific formatting information. - /// A containing zero or more format items. - /// An array containing zero or more objects to format. - public SystemStringFormat(IFormatProvider provider, string format, params object[] args) - { - m_provider = provider; - m_format = format; - m_args = args; - } - - #endregion Constructor - - /// - /// Format the string and arguments - /// - /// the formatted string - public override string ToString() - { - return StringFormat(m_provider, m_format, m_args); - } - - #region StringFormat - - /// - /// Replaces the format item in a specified with the text equivalent - /// of the value of a corresponding instance in a specified array. - /// A specified parameter supplies culture-specific formatting information. - /// - /// An that supplies culture-specific formatting information. - /// A containing zero or more format items. - /// An array containing zero or more objects to format. - /// - /// A copy of format in which the format items have been replaced by the - /// equivalent of the corresponding instances of in args. - /// - /// - /// - /// This method does not throw exceptions. If an exception thrown while formatting the result the - /// exception and arguments are returned in the result string. - /// - /// - private static string StringFormat(IFormatProvider provider, string format, params object[] args) - { - try - { - // The format is missing, log null value - if (format == null) - { - return null; - } - - // The args are missing - should not happen unless we are called explicitly with a null array - if (args == null) - { - return format; - } - - // Try to format the string - return String.Format(provider, format, args); - } - catch(Exception ex) - { - log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]", ex); - return StringFormatError(ex, format, args); - } -#if NETCF - catch - { - log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]"); - return StringFormatError(null, format, args); - } -#endif - } - - /// - /// Process an error during StringFormat - /// - private static string StringFormatError(Exception formatException, string format, object[] args) - { - try - { - StringBuilder buf = new StringBuilder(""); - - if (formatException != null) - { - buf.Append("Exception during StringFormat: ").Append(formatException.Message); - } - else - { - buf.Append("Exception during StringFormat"); - } - buf.Append(" ").Append(format).Append(""); - buf.Append(""); - RenderArray(args, buf); - buf.Append(""); - buf.Append(""); - - return buf.ToString(); - } - catch(Exception ex) - { - log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex); - return "Exception during StringFormat. See Internal Log."; - } -#if NETCF - catch - { - log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling"); - return "Exception during StringFormat. See Internal Log."; - } -#endif - } - - /// - /// Dump the contents of an array into a string builder - /// - private static void RenderArray(Array array, StringBuilder buffer) - { - if (array == null) - { - buffer.Append(SystemInfo.NullText); - } - else - { - if (array.Rank != 1) - { - buffer.Append(array.ToString()); - } - else - { - buffer.Append("{"); - int len = array.Length; - - if (len > 0) - { - RenderObject(array.GetValue(0), buffer); - for (int i = 1; i < len; i++) - { - buffer.Append(", "); - RenderObject(array.GetValue(i), buffer); - } - } - buffer.Append("}"); - } - } - } - - /// - /// Dump an object to a string - /// - private static void RenderObject(Object obj, StringBuilder buffer) - { - if (obj == null) - { - buffer.Append(SystemInfo.NullText); - } - else - { - try - { - buffer.Append(obj); - } - catch(Exception ex) - { - buffer.Append(""); - } -#if NETCF - catch - { - buffer.Append(""); - } -#endif - } - } - - #endregion StringFormat - - #region Private Static Fields - - /// - /// The fully qualified type of the SystemStringFormat class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(SystemStringFormat); - - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/TextWriterAdapter.cs b/src/log4net/Util/TextWriterAdapter.cs deleted file mode 100644 index 67380204..00000000 --- a/src/log4net/Util/TextWriterAdapter.cs +++ /dev/null @@ -1,234 +0,0 @@ -#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 System.Text; -using System.IO; -using System.Globalization; - -namespace log4net.Util -{ - /// - /// Adapter that extends and forwards all - /// messages to an instance of . - /// - /// - /// - /// Adapter that extends and forwards all - /// messages to an instance of . - /// - /// - /// Nicko Cadell - public abstract class TextWriterAdapter : TextWriter - { - #region Private Member Variables - - /// - /// The writer to forward messages to - /// - private TextWriter m_writer; - - #endregion - - #region Constructors - - /// - /// Create an instance of that forwards all - /// messages to a . - /// - /// The to forward to - /// - /// - /// Create an instance of that forwards all - /// messages to a . - /// - /// - protected TextWriterAdapter(TextWriter writer) : base(CultureInfo.InvariantCulture) - { - m_writer = writer; - } - - #endregion - - #region Protected Instance Properties - - /// - /// Gets or sets the underlying . - /// - /// - /// The underlying . - /// - /// - /// - /// Gets or sets the underlying . - /// - /// - protected TextWriter Writer - { - get { return m_writer; } - set { m_writer = value; } - } - - #endregion Protected Instance Properties - - #region Public Properties - - /// - /// The Encoding in which the output is written - /// - /// - /// The - /// - /// - /// - /// The Encoding in which the output is written - /// - /// - override public Encoding Encoding - { - get { return m_writer.Encoding; } - } - - /// - /// Gets an object that controls formatting - /// - /// - /// The format provider - /// - /// - /// - /// Gets an object that controls formatting - /// - /// - override public IFormatProvider FormatProvider - { - get { return m_writer.FormatProvider; } - } - - /// - /// Gets or sets the line terminator string used by the TextWriter - /// - /// - /// The line terminator to use - /// - /// - /// - /// Gets or sets the line terminator string used by the TextWriter - /// - /// - override public String NewLine - { - get { return m_writer.NewLine; } - set { m_writer.NewLine = value; } - } - - #endregion - - #region Public Methods - - /// - /// Closes the writer and releases any system resources associated with the writer - /// - /// - /// - /// - /// - override public void Close() - { - m_writer.Close(); - } - - /// - /// Dispose this writer - /// - /// flag indicating if we are being disposed - /// - /// - /// Dispose this writer - /// - /// - override protected void Dispose(bool disposing) - { - if (disposing) - { - ((IDisposable)m_writer).Dispose(); - } - } - - /// - /// Flushes any buffered output - /// - /// - /// - /// Clears all buffers for the writer and causes any buffered data to be written - /// to the underlying device - /// - /// - override public void Flush() - { - m_writer.Flush(); - } - - /// - /// Writes a character to the wrapped TextWriter - /// - /// the value to write to the TextWriter - /// - /// - /// Writes a character to the wrapped TextWriter - /// - /// - override public void Write(char value) - { - m_writer.Write(value); - } - - /// - /// Writes a character buffer to the wrapped TextWriter - /// - /// the data buffer - /// the start index - /// the number of characters to write - /// - /// - /// Writes a character buffer to the wrapped TextWriter - /// - /// - override public void Write(char[] buffer, int index, int count) - { - m_writer.Write(buffer, index, count); - } - - /// - /// Writes a string to the wrapped TextWriter - /// - /// the value to write to the TextWriter - /// - /// - /// Writes a string to the wrapped TextWriter - /// - /// - override public void Write(String value) - { - m_writer.Write(value); - } - - #endregion - } -} diff --git a/src/log4net/Util/ThreadContextProperties.cs b/src/log4net/Util/ThreadContextProperties.cs deleted file mode 100644 index 17060852..00000000 --- a/src/log4net/Util/ThreadContextProperties.cs +++ /dev/null @@ -1,200 +0,0 @@ -#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; -#if NETCF -using System.Collections; -#endif - -namespace log4net.Util -{ - /// - /// Implementation of Properties collection for the - /// - /// - /// - /// Class implements a collection of properties that is specific to each thread. - /// The class is not synchronized as each thread has its own . - /// - /// - /// Nicko Cadell - public sealed class ThreadContextProperties : ContextPropertiesBase - { - #region Private Instance Fields - -#if NETCF - /// - /// The thread local data slot to use to store a PropertiesDictionary. - /// - private readonly static LocalDataStoreSlot s_threadLocalSlot = System.Threading.Thread.AllocateDataSlot(); -#else - /// - /// Each thread will automatically have its instance. - /// - [ThreadStatic] - private static PropertiesDictionary _dictionary; -#endif - - #endregion Private Instance Fields - - #region Public Instance Constructors - - /// - /// Internal constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - internal ThreadContextProperties() - { - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets or sets the value of a property - /// - /// - /// The value for the property with the specified key - /// - /// - /// - /// Gets or sets the value of a property - /// - /// - override public object this[string key] - { - get - { -#if NETCF - PropertiesDictionary _dictionary = GetProperties(false); -#endif - if (_dictionary != null) - { - return _dictionary[key]; - } - return null; - } - set - { - GetProperties(true)[key] = value; - } - } - - #endregion Public Instance Properties - - #region Public Instance Methods - - /// - /// Remove a property - /// - /// the key for the entry to remove - /// - /// - /// Remove a property - /// - /// - public void Remove(string key) - { -#if NETCF - PropertiesDictionary _dictionary = GetProperties(false); -#endif - if (_dictionary != null) - { - _dictionary.Remove(key); - } - } - - /// - /// Get the keys stored in the properties. - /// - /// - /// Gets the keys stored in the properties. - /// - /// a set of the defined keys - public string[] GetKeys() - { -#if NETCF - PropertiesDictionary _dictionary = GetProperties(false); -#endif - if (_dictionary != null) - { - return _dictionary.GetKeys(); - } - return null; - } - - /// - /// Clear all properties - /// - /// - /// - /// Clear all properties - /// - /// - public void Clear() - { -#if NETCF - PropertiesDictionary _dictionary = GetProperties(false); -#endif - if (_dictionary != null) - { - _dictionary.Clear(); - } - } - - #endregion Public Instance Methods - - #region Internal Instance Methods - - /// - /// Get the PropertiesDictionary for this thread. - /// - /// create the dictionary if it does not exist, otherwise return null if does not exist - /// the properties for this thread - /// - /// - /// The collection returned is only to be used on the calling thread. If the - /// caller needs to share the collection between different threads then the - /// caller must clone the collection before doing so. - /// - /// - internal PropertiesDictionary GetProperties(bool create) - { -#if NETCF - PropertiesDictionary _dictionary = (PropertiesDictionary)System.Threading.Thread.GetData(s_threadLocalSlot); -#endif - if (_dictionary == null && create) - { - _dictionary = new PropertiesDictionary(); -#if NETCF - System.Threading.Thread.SetData(s_threadLocalSlot, _dictionary); -#endif - } - return _dictionary; - } - - #endregion Internal Instance Methods - } -} - diff --git a/src/log4net/Util/ThreadContextStack.cs b/src/log4net/Util/ThreadContextStack.cs deleted file mode 100644 index e8a3074d..00000000 --- a/src/log4net/Util/ThreadContextStack.cs +++ /dev/null @@ -1,381 +0,0 @@ -#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 System.Collections; - -using log4net.Core; - -namespace log4net.Util -{ - /// - /// Implementation of Stack for the - /// - /// - /// - /// Implementation of Stack for the - /// - /// - /// Nicko Cadell - public sealed class ThreadContextStack : IFixingRequired - { - #region Private Static Fields - - /// - /// The stack store. - /// - private Stack m_stack = new Stack(); - - #endregion Private Static Fields - - #region Public Instance Constructors - - /// - /// Internal constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - internal ThreadContextStack() - { - } - - #endregion Public Instance Constructors - - #region Public Properties - - /// - /// The number of messages in the stack - /// - /// - /// The current number of messages in the stack - /// - /// - /// - /// The current number of messages in the stack. That is - /// the number of times has been called - /// minus the number of times has been called. - /// - /// - public int Count - { - get { return m_stack.Count; } - } - - #endregion // Public Properties - - #region Public Methods - - /// - /// Clears all the contextual information held in this stack. - /// - /// - /// - /// Clears all the contextual information held in this stack. - /// Only call this if you think that this tread is being reused after - /// a previous call execution which may not have completed correctly. - /// You do not need to use this method if you always guarantee to call - /// the method of the - /// returned from even in exceptional circumstances, - /// for example by using the using(log4net.ThreadContext.Stacks["NDC"].Push("Stack_Message")) - /// syntax. - /// - /// - public void Clear() - { - m_stack.Clear(); - } - - /// - /// Removes the top context from this stack. - /// - /// The message in the context that was removed from the top of this stack. - /// - /// - /// Remove the top context from this stack, and return - /// it to the caller. If this stack is empty then an - /// empty string (not ) is returned. - /// - /// - public string Pop() - { - Stack stack = m_stack; - if (stack.Count > 0) - { - return ((StackFrame)(stack.Pop())).Message; - } - return ""; - } - - /// - /// Pushes a new context message into this stack. - /// - /// The new context message. - /// - /// An that can be used to clean up the context stack. - /// - /// - /// - /// Pushes a new context onto this stack. An - /// is returned that can be used to clean up this stack. This - /// can be easily combined with the using keyword to scope the - /// context. - /// - /// - /// Simple example of using the Push method with the using keyword. - /// - /// using(log4net.ThreadContext.Stacks["NDC"].Push("Stack_Message")) - /// { - /// log.Warn("This should have an ThreadContext Stack message"); - /// } - /// - /// - public IDisposable Push(string message) - { - Stack stack = m_stack; - stack.Push(new StackFrame(message, (stack.Count>0) ? (StackFrame)stack.Peek() : null)); - - return new AutoPopStackFrame(stack, stack.Count - 1); - } - - #endregion Public Methods - - #region Internal Methods - - /// - /// Gets the current context information for this stack. - /// - /// The current context information. - internal string GetFullMessage() - { - Stack stack = m_stack; - if (stack.Count > 0) - { - return ((StackFrame)(stack.Peek())).FullMessage; - } - return null; - } - - /// - /// Gets and sets the internal stack used by this - /// - /// The internal storage stack - /// - /// - /// This property is provided only to support backward compatability - /// of the . Tytpically the internal stack should not - /// be modified. - /// - /// - internal Stack InternalStack - { - get { return m_stack; } - set { m_stack = value; } - } - - #endregion Internal Methods - - /// - /// Gets the current context information for this stack. - /// - /// Gets the current context information - /// - /// - /// Gets the current context information for this stack. - /// - /// - public override string ToString() - { - return GetFullMessage(); - } - - /// - /// Get a portable version of this object - /// - /// the portable instance of this object - /// - /// - /// Get a cross thread portable version of this object - /// - /// - object IFixingRequired.GetFixedObject() - { - return GetFullMessage(); - } - - /// - /// Inner class used to represent a single context frame in the stack. - /// - /// - /// - /// Inner class used to represent a single context frame in the stack. - /// - /// - private sealed class StackFrame - { - #region Private Instance Fields - - private readonly string m_message; - private readonly StackFrame m_parent; - private string m_fullMessage = null; - - #endregion - - #region Internal Instance Constructors - - /// - /// Constructor - /// - /// The message for this context. - /// The parent context in the chain. - /// - /// - /// Initializes a new instance of the class - /// with the specified message and parent context. - /// - /// - internal StackFrame(string message, StackFrame parent) - { - m_message = message; - m_parent = parent; - - if (parent == null) - { - m_fullMessage = message; - } - } - - #endregion Internal Instance Constructors - - #region Internal Instance Properties - - /// - /// Get the message. - /// - /// The message. - /// - /// - /// Get the message. - /// - /// - internal string Message - { - get { return m_message; } - } - - /// - /// Gets the full text of the context down to the root level. - /// - /// - /// The full text of the context down to the root level. - /// - /// - /// - /// Gets the full text of the context down to the root level. - /// - /// - internal string FullMessage - { - get - { - if (m_fullMessage == null && m_parent != null) - { - m_fullMessage = string.Concat(m_parent.FullMessage, " ", m_message); - } - return m_fullMessage; - } - } - - #endregion Internal Instance Properties - } - - /// - /// Struct returned from the method. - /// - /// - /// - /// This struct implements the and is designed to be used - /// with the pattern to remove the stack frame at the end of the scope. - /// - /// - private struct AutoPopStackFrame : IDisposable - { - #region Private Instance Fields - - /// - /// The ThreadContextStack internal stack - /// - private Stack m_frameStack; - - /// - /// The depth to trim the stack to when this instance is disposed - /// - private int m_frameDepth; - - #endregion Private Instance Fields - - #region Internal Instance Constructors - - /// - /// Constructor - /// - /// The internal stack used by the ThreadContextStack. - /// The depth to return the stack to when this object is disposed. - /// - /// - /// Initializes a new instance of the class with - /// the specified stack and return depth. - /// - /// - internal AutoPopStackFrame(Stack frameStack, int frameDepth) - { - m_frameStack = frameStack; - m_frameDepth = frameDepth; - } - - #endregion Internal Instance Constructors - - #region Implementation of IDisposable - - /// - /// Returns the stack to the correct depth. - /// - /// - /// - /// Returns the stack to the correct depth. - /// - /// - public void Dispose() - { - if (m_frameDepth >= 0 && m_frameStack != null) - { - while(m_frameStack.Count > m_frameDepth) - { - m_frameStack.Pop(); - } - } - } - - #endregion Implementation of IDisposable - } - - } -} diff --git a/src/log4net/Util/ThreadContextStacks.cs b/src/log4net/Util/ThreadContextStacks.cs deleted file mode 100644 index 3fffb05a..00000000 --- a/src/log4net/Util/ThreadContextStacks.cs +++ /dev/null @@ -1,124 +0,0 @@ -#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 System.Collections; - -namespace log4net.Util -{ - /// - /// Implementation of Stacks collection for the - /// - /// - /// - /// Implementation of Stacks collection for the - /// - /// - /// Nicko Cadell - public sealed class ThreadContextStacks - { - private readonly ContextPropertiesBase m_properties; - - #region Public Instance Constructors - - /// - /// Internal constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - internal ThreadContextStacks(ContextPropertiesBase properties) - { - m_properties = properties; - } - - #endregion Public Instance Constructors - - #region Public Instance Properties - - /// - /// Gets the named thread context stack - /// - /// - /// The named stack - /// - /// - /// - /// Gets the named thread context stack - /// - /// - public ThreadContextStack this[string key] - { - get - { - ThreadContextStack stack = null; - - object propertyValue = m_properties[key]; - if (propertyValue == null) - { - // Stack does not exist, create - stack = new ThreadContextStack(); - m_properties[key] = stack; - } - else - { - // Look for existing stack - stack = propertyValue as ThreadContextStack; - if (stack == null) - { - // Property is not set to a stack! - string propertyValueString = SystemInfo.NullText; - - try - { - propertyValueString = propertyValue.ToString(); - } - catch - { - } - - LogLog.Error(declaringType, "ThreadContextStacks: Request for stack named ["+key+"] failed because a property with the same name exists which is a ["+propertyValue.GetType().Name+"] with value ["+propertyValueString+"]"); - - stack = new ThreadContextStack(); - } - } - - return stack; - } - } - - #endregion Public Instance Properties - - #region Private Static Fields - - /// - /// The fully qualified type of the ThreadContextStacks class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(ThreadContextStacks); - - #endregion Private Static Fields - } -} - diff --git a/src/log4net/Util/Transform.cs b/src/log4net/Util/Transform.cs deleted file mode 100644 index 7e8f4086..00000000 --- a/src/log4net/Util/Transform.cs +++ /dev/null @@ -1,200 +0,0 @@ -#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 System.Text; -using System.Xml; -using System.Text.RegularExpressions; - -namespace log4net.Util -{ - /// - /// Utility class for transforming strings. - /// - /// - /// - /// Utility class for transforming strings. - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class Transform - { - #region Private Instance Constructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// Uses a private access modifier to prevent instantiation of this class. - /// - /// - private Transform() - { - } - - #endregion Private Instance Constructors - - #region XML String Methods - - /// - /// Write a string to an - /// - /// the writer to write to - /// the string to write - /// The string to replace non XML compliant chars with - /// - /// - /// The test is escaped either using XML escape entities - /// or using CDATA sections. - /// - /// - public static void WriteEscapedXmlString(XmlWriter writer, string textData, string invalidCharReplacement) - { - string stringData = MaskXmlInvalidCharacters(textData, invalidCharReplacement); - // Write either escaped text or CDATA sections - - int weightCData = 12 * (1 + CountSubstrings(stringData, CDATA_END)); - int weightStringEscapes = 3*(CountSubstrings(stringData, "<") + CountSubstrings(stringData, ">")) + 4*CountSubstrings(stringData, "&"); - - if (weightStringEscapes <= weightCData) - { - // Write string using string escapes - writer.WriteString(stringData); - } - else - { - // Write string using CDATA section - - int end = stringData.IndexOf(CDATA_END); - - if (end < 0) - { - writer.WriteCData(stringData); - } - else - { - int start = 0; - while (end > -1) - { - writer.WriteCData(stringData.Substring(start, end - start)); - if (end == stringData.Length - 3) - { - start = stringData.Length; - writer.WriteString(CDATA_END); - break; - } - else - { - writer.WriteString(CDATA_UNESCAPABLE_TOKEN); - start = end + 2; - end = stringData.IndexOf(CDATA_END, start); - } - } - - if (start < stringData.Length) - { - writer.WriteCData(stringData.Substring(start)); - } - } - } - } - - /// - /// Replace invalid XML characters in text string - /// - /// the XML text input string - /// the string to use in place of invalid characters - /// A string that does not contain invalid XML characters. - /// - /// - /// Certain Unicode code points are not allowed in the XML InfoSet, for - /// details see: http://www.w3.org/TR/REC-xml/#charsets. - /// - /// - /// This method replaces any illegal characters in the input string - /// with the mask string specified. - /// - /// - public static string MaskXmlInvalidCharacters(string textData, string mask) - { - return INVALIDCHARS.Replace(textData, mask); - } - - #endregion XML String Methods - - #region Private Helper Methods - - /// - /// Count the number of times that the substring occurs in the text - /// - /// the text to search - /// the substring to find - /// the number of times the substring occurs in the text - /// - /// - /// The substring is assumed to be non repeating within itself. - /// - /// - private static int CountSubstrings(string text, string substring) - { - int count = 0; - int offset = 0; - int length = text.Length; - int substringLength = substring.Length; - - if (length == 0) - { - return 0; - } - if (substringLength == 0) - { - return 0; - } - - while(offset < length) - { - int index = text.IndexOf(substring, offset); - - if (index == -1) - { - break; - } - - count++; - offset = index + substringLength; - } - return count; - } - - #endregion - - #region Private Static Fields - - private const string CDATA_END = "]]>"; - private const string CDATA_UNESCAPABLE_TOKEN = "]]"; - - /// - /// Characters illegal in XML 1.0 - /// - private static Regex INVALIDCHARS=new Regex(@"[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD]",RegexOptions.Compiled); - #endregion Private Static Fields - } -} diff --git a/src/log4net/Util/TypeConverters/BooleanConverter.cs b/src/log4net/Util/TypeConverters/BooleanConverter.cs deleted file mode 100644 index 7853c45a..00000000 --- a/src/log4net/Util/TypeConverters/BooleanConverter.cs +++ /dev/null @@ -1,85 +0,0 @@ -#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; - -namespace log4net.Util.TypeConverters -{ - /// - /// Type converter for Boolean. - /// - /// - /// - /// Supports conversion from string to bool type. - /// - /// - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - internal class BooleanConverter : IConvertFrom - { - #region Implementation of IConvertFrom - - /// - /// Can the source type be converted to the type supported by this object - /// - /// the type to convert - /// true if the conversion is possible - /// - /// - /// Returns true if the is - /// the type. - /// - /// - public bool CanConvertFrom(Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Convert the source object to the type supported by this object - /// - /// the object to convert - /// the converted object - /// - /// - /// Uses the method to convert the - /// argument to a . - /// - /// - /// - /// The object cannot be converted to the - /// target type. To check for this condition use the - /// method. - /// - public object ConvertFrom(object source) - { - string str = source as string; - if (str != null) - { - return bool.Parse(str); - } - throw ConversionNotSupportedException.Create(typeof(bool), source); - } - - #endregion - } -} diff --git a/src/log4net/Util/TypeConverters/ConversionNotSupportedException.cs b/src/log4net/Util/TypeConverters/ConversionNotSupportedException.cs deleted file mode 100644 index b677aaf9..00000000 --- a/src/log4net/Util/TypeConverters/ConversionNotSupportedException.cs +++ /dev/null @@ -1,154 +0,0 @@ -#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; -#if !NETCF -using System.Runtime.Serialization; -#endif - -namespace log4net.Util.TypeConverters -{ - /// - /// Exception base type for conversion errors. - /// - /// - /// - /// This type extends . It - /// does not add any new functionality but does differentiate the - /// type of exception being thrown. - /// - /// - /// Nicko Cadell - /// Gert Driesen -#if !NETCF - [Serializable] -#endif - public class ConversionNotSupportedException : ApplicationException - { - #region Public Instance Constructors - - /// - /// Constructor - /// - /// - /// - /// Initializes a new instance of the class. - /// - /// - public ConversionNotSupportedException() - { - } - - /// - /// Constructor - /// - /// A message to include with the exception. - /// - /// - /// Initializes a new instance of the class - /// with the specified message. - /// - /// - public ConversionNotSupportedException(String message) : base(message) - { - } - - /// - /// Constructor - /// - /// A message to include with the exception. - /// A nested exception to include. - /// - /// - /// Initializes a new instance of the class - /// with the specified message and inner exception. - /// - /// - public ConversionNotSupportedException(String message, Exception innerException) : base(message, innerException) - { - } - - #endregion Public Instance Constructors - - #region Protected Instance Constructors - -#if !NETCF - /// - /// Serialization constructor - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// - /// - /// Initializes a new instance of the class - /// with serialized data. - /// - /// - protected ConversionNotSupportedException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } -#endif - - #endregion Protected Instance Constructors - - #region Public Static Methods - - /// - /// Creates a new instance of the class. - /// - /// The conversion destination type. - /// The value to convert. - /// An instance of the . - /// - /// - /// Creates a new instance of the class. - /// - /// - public static ConversionNotSupportedException Create(Type destinationType, object sourceValue) - { - return Create(destinationType, sourceValue, null); - } - - /// - /// Creates a new instance of the class. - /// - /// The conversion destination type. - /// The value to convert. - /// A nested exception to include. - /// An instance of the . - /// - /// - /// Creates a new instance of the class. - /// - /// - public static ConversionNotSupportedException Create(Type destinationType, object sourceValue, Exception innerException) - { - if (sourceValue == null) - { - return new ConversionNotSupportedException("Cannot convert value [null] to type ["+destinationType+"]", innerException); - } - else - { - return new ConversionNotSupportedException("Cannot convert from type ["+sourceValue.GetType()+"] value ["+sourceValue+"] to type ["+destinationType+"]", innerException); - } - } - - #endregion Public Static Methods - } -} diff --git a/src/log4net/Util/TypeConverters/ConverterRegistry.cs b/src/log4net/Util/TypeConverters/ConverterRegistry.cs deleted file mode 100644 index 77271766..00000000 --- a/src/log4net/Util/TypeConverters/ConverterRegistry.cs +++ /dev/null @@ -1,293 +0,0 @@ -#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 System.Globalization; -using System.Reflection; -using System.Collections; - -namespace log4net.Util.TypeConverters -{ - /// - /// Register of type converters for specific types. - /// - /// - /// - /// Maintains a registry of type converters used to convert between - /// types. - /// - /// - /// Use the and - /// methods to register new converters. - /// The and methods - /// lookup appropriate converters to use. - /// - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - public sealed class ConverterRegistry - { - #region Private Constructors - - /// - /// Private constructor - /// - /// - /// Initializes a new instance of the class. - /// - private ConverterRegistry() - { - } - - #endregion Private Constructors - - #region Static Constructor - - /// - /// Static constructor. - /// - /// - /// - /// This constructor defines the intrinsic type converters. - /// - /// - static ConverterRegistry() - { - // Add predefined converters here - AddConverter(typeof(bool), typeof(BooleanConverter)); - AddConverter(typeof(System.Text.Encoding), typeof(EncodingConverter)); - AddConverter(typeof(System.Type), typeof(TypeConverter)); - AddConverter(typeof(log4net.Layout.PatternLayout), typeof(PatternLayoutConverter)); - AddConverter(typeof(log4net.Util.PatternString), typeof(PatternStringConverter)); - AddConverter(typeof(System.Net.IPAddress), typeof(IPAddressConverter)); - } - - #endregion Static Constructor - - #region Public Static Methods - - /// - /// Adds a converter for a specific type. - /// - /// The type being converted to. - /// The type converter to use to convert to the destination type. - /// - /// - /// Adds a converter instance for a specific type. - /// - /// - public static void AddConverter(Type destinationType, object converter) - { - if (destinationType != null && converter != null) - { - lock(s_type2converter) - { - s_type2converter[destinationType] = converter; - } - } - } - - /// - /// Adds a converter for a specific type. - /// - /// The type being converted to. - /// The type of the type converter to use to convert to the destination type. - /// - /// - /// Adds a converter for a specific type. - /// - /// - public static void AddConverter(Type destinationType, Type converterType) - { - AddConverter(destinationType, CreateConverterInstance(converterType)); - } - - /// - /// Gets the type converter to use to convert values to the destination type. - /// - /// The type being converted from. - /// The type being converted to. - /// - /// The type converter instance to use for type conversions or null - /// if no type converter is found. - /// - /// - /// - /// Gets the type converter to use to convert values to the destination type. - /// - /// - public static IConvertTo GetConvertTo(Type sourceType, Type destinationType) - { - // TODO: Support inheriting type converters. - // i.e. getting a type converter for a base of sourceType - - // TODO: Is destinationType required? We don't use it for anything. - - lock(s_type2converter) - { - // Lookup in the static registry - IConvertTo converter = s_type2converter[sourceType] as IConvertTo; - - if (converter == null) - { - // Lookup using attributes - converter = GetConverterFromAttribute(sourceType) as IConvertTo; - - if (converter != null) - { - // Store in registry - s_type2converter[sourceType] = converter; - } - } - - return converter; - } - } - - /// - /// Gets the type converter to use to convert values to the destination type. - /// - /// The type being converted to. - /// - /// The type converter instance to use for type conversions or null - /// if no type converter is found. - /// - /// - /// - /// Gets the type converter to use to convert values to the destination type. - /// - /// - public static IConvertFrom GetConvertFrom(Type destinationType) - { - // TODO: Support inheriting type converters. - // i.e. getting a type converter for a base of destinationType - - lock(s_type2converter) - { - // Lookup in the static registry - IConvertFrom converter = s_type2converter[destinationType] as IConvertFrom; - - if (converter == null) - { - // Lookup using attributes - converter = GetConverterFromAttribute(destinationType) as IConvertFrom; - - if (converter != null) - { - // Store in registry - s_type2converter[destinationType] = converter; - } - } - - return converter; - } - } - - /// - /// Lookups the type converter to use as specified by the attributes on the - /// destination type. - /// - /// The type being converted to. - /// - /// The type converter instance to use for type conversions or null - /// if no type converter is found. - /// - private static object GetConverterFromAttribute(Type destinationType) - { - // Look for an attribute on the destination type - object[] attributes = destinationType.GetCustomAttributes(typeof(TypeConverterAttribute), true); - if (attributes != null && attributes.Length > 0) - { - TypeConverterAttribute tcAttr = attributes[0] as TypeConverterAttribute; - if (tcAttr != null) - { - Type converterType = SystemInfo.GetTypeFromString(destinationType, tcAttr.ConverterTypeName, false, true); - return CreateConverterInstance(converterType); - } - } - - // Not found converter using attributes - return null; - } - - /// - /// Creates the instance of the type converter. - /// - /// The type of the type converter. - /// - /// The type converter instance to use for type conversions or null - /// if no type converter is found. - /// - /// - /// - /// The type specified for the type converter must implement - /// the or interfaces - /// and must have a public default (no argument) constructor. - /// - /// - private static object CreateConverterInstance(Type converterType) - { - if (converterType == null) - { - throw new ArgumentNullException("converterType", "CreateConverterInstance cannot create instance, converterType is null"); - } - - // Check type is a converter - if (typeof(IConvertFrom).IsAssignableFrom(converterType) || typeof(IConvertTo).IsAssignableFrom(converterType)) - { - try - { - // Create the type converter - return Activator.CreateInstance(converterType); - } - catch(Exception ex) - { - LogLog.Error(declaringType, "Cannot CreateConverterInstance of type ["+converterType.FullName+"], Exception in call to Activator.CreateInstance", ex); - } - } - else - { - LogLog.Error(declaringType, "Cannot CreateConverterInstance of type ["+converterType.FullName+"], type does not implement IConvertFrom or IConvertTo"); - } - return null; - } - - #endregion Public Static Methods - - #region Private Static Fields - - /// - /// The fully qualified type of the ConverterRegistry class. - /// - /// - /// Used by the internal logger to record the Type of the - /// log message. - /// - private readonly static Type declaringType = typeof(ConverterRegistry); - - /// - /// Mapping from to type converter. - /// - private static Hashtable s_type2converter = new Hashtable(); - - #endregion - } -} diff --git a/src/log4net/Util/TypeConverters/EncodingConverter.cs b/src/log4net/Util/TypeConverters/EncodingConverter.cs deleted file mode 100644 index 93c9eac9..00000000 --- a/src/log4net/Util/TypeConverters/EncodingConverter.cs +++ /dev/null @@ -1,86 +0,0 @@ -#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 System.Text; - -namespace log4net.Util.TypeConverters -{ - /// - /// Supports conversion from string to type. - /// - /// - /// - /// Supports conversion from string to type. - /// - /// - /// - /// - /// - /// Nicko Cadell - /// Gert Driesen - internal class EncodingConverter : IConvertFrom - { - #region Implementation of IConvertFrom - - /// - /// Can the source type be converted to the type supported by this object - /// - /// the type to convert - /// true if the conversion is possible - /// - /// - /// Returns true if the is - /// the type. - /// - /// - public bool CanConvertFrom(Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Overrides the ConvertFrom method of IConvertFrom. - /// - /// the object to convert to an encoding - /// the encoding - /// - /// - /// Uses the method to - /// convert the argument to an . - /// - /// - /// - /// The object cannot be converted to the - /// target type. To check for this condition use the - /// method. - /// - public object ConvertFrom(object source) - { - string str = source as string; - if (str != null) - { - return Encoding.GetEncoding(str); - } - throw ConversionNotSupportedException.Create(typeof(Encoding), source); - } - - #endregion - } -} diff --git a/src/log4net/Util/TypeConverters/IConvertFrom.cs b/src/log4net/Util/TypeConverters/IConvertFrom.cs deleted file mode 100644 index 1dbd4738..00000000 --- a/src/log4net/Util/TypeConverters/IConvertFrom.cs +++ /dev/null @@ -1,63 +0,0 @@ -#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; - -namespace log4net.Util.TypeConverters -{ - /// - /// Interface supported by type converters - /// - /// - /// - /// This interface supports conversion from arbitrary types - /// to a single target type. See . - /// - /// - /// Nicko Cadell - /// Gert Driesen - public interface IConvertFrom - { - /// - /// Can the source type be converted to the type supported by this object - /// - /// the type to convert - /// true if the conversion is possible - /// - /// - /// Test if the can be converted to the - /// type supported by this converter. - /// - /// - bool CanConvertFrom(Type sourceType); - - /// - /// Convert the source object to the type supported by this object - /// - /// the object to convert - /// the converted object - /// - /// - /// Converts the to the type supported - /// by this converter. - /// - /// - object ConvertFrom(object source); - } -} diff --git a/src/log4net/Util/TypeConverters/IConvertTo.cs b/src/log4net/Util/TypeConverters/IConvertTo.cs deleted file mode 100644 index e9863728..00000000 --- a/src/log4net/Util/TypeConverters/IConvertTo.cs +++ /dev/null @@ -1,63 +0,0 @@ -#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; - -namespace log4net.Util.TypeConverters -{ - /// - /// Interface supported by type converters - /// - /// - /// - /// This interface supports conversion from a single type to arbitrary types. - /// See . - /// - /// - /// Nicko Cadell - public interface IConvertTo - { - /// - /// Returns whether this converter can convert the object to the specified type - /// - /// A Type that represents the type you want to convert to - /// true if the conversion is possible - /// - /// - /// Test if the type supported by this converter can be converted to the - /// . - /// - /// - bool CanConvertTo(Type targetType); - - /// - /// Converts the given value object to the specified type, using the arguments - /// - /// the object to convert - /// The Type to convert the value parameter to - /// the converted object - /// - /// - /// Converts the (which must be of the type supported - /// by this converter) to the specified.. - /// - /// - object ConvertTo(object source, Type targetType); - } -} diff --git a/src/log4net/Util/TypeConverters/IPAddressConverter.cs b/src/log4net/Util/TypeConverters/IPAddressConverter.cs deleted file mode 100644 index 19799405..00000000 --- a/src/log4net/Util/TypeConverters/IPAddressConverter.cs +++ /dev/null @@ -1,111 +0,0 @@ -#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 System.Net; - -namespace log4net.Util.TypeConverters -{ - /// - /// Supports conversion from string to type. - /// - /// - /// - /// Supports conversion from string to type. - /// - /// - /// - /// - /// Nicko Cadell - internal class IPAddressConverter : IConvertFrom - { - #region Implementation of IConvertFrom - - /// - /// Can the source type be converted to the type supported by this object - /// - /// the type to convert - /// true if the conversion is possible - /// - /// - /// Returns true if the is - /// the type. - /// - /// - public bool CanConvertFrom(Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Overrides the ConvertFrom method of IConvertFrom. - /// - /// the object to convert to an IPAddress - /// the IPAddress - /// - /// - /// Uses the method to convert the - /// argument to an . - /// If that fails then the string is resolved as a DNS hostname. - /// - /// - /// - /// The object cannot be converted to the - /// target type. To check for this condition use the - /// method. - /// - public object ConvertFrom(object source) - { - string str = source as string; - if (str != null && str.Length > 0) - { - try - { -#if !NETCF - // Try an explicit parse of string representation of an IPAddress (v4 or v6) - IPAddress result; - if (IPAddress.TryParse(str, out result)) - { - return result; - } -#endif - - // Try to resolve via DNS. This is a blocking call. - // GetHostEntry works with either an IPAddress string or a host name - IPHostEntry host = Dns.GetHostEntry(str); - if (host != null && - host.AddressList != null && - host.AddressList.Length > 0 && - host.AddressList[0] != null) - { - return host.AddressList[0]; - } - } - catch(Exception ex) - { - throw ConversionNotSupportedException.Create(typeof(IPAddress), source, ex); - } - } - throw ConversionNotSupportedException.Create(typeof(IPAddress), source); - } - - #endregion - - } -} diff --git a/src/log4net/Util/TypeConverters/PatternLayoutConverter.cs b/src/log4net/Util/TypeConverters/PatternLayoutConverter.cs deleted file mode 100644 index c9942b2d..00000000 --- a/src/log4net/Util/TypeConverters/PatternLayoutConverter.cs +++ /dev/null @@ -1,92 +0,0 @@ -#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 System.Text; - -using log4net.Layout; - -namespace log4net.Util.TypeConverters -{ - /// - /// Supports conversion from string to type. - /// - /// - /// - /// Supports conversion from string to type. - /// - /// - /// The string is used as the - /// of the . - /// - /// - /// - /// - /// - /// Nicko Cadell - internal class PatternLayoutConverter : IConvertFrom - { - #region Implementation of IConvertFrom - - /// - /// Can the source type be converted to the type supported by this object - /// - /// the type to convert - /// true if the conversion is possible - /// - /// - /// Returns true if the is - /// the type. - /// - /// - public bool CanConvertFrom(System.Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Overrides the ConvertFrom method of IConvertFrom. - /// - /// the object to convert to a PatternLayout - /// the PatternLayout - /// - /// - /// Creates and returns a new using - /// the as the - /// . - /// - /// - /// - /// The object cannot be converted to the - /// target type. To check for this condition use the - /// method. - /// - public object ConvertFrom(object source) - { - string str = source as string; - if (str != null) - { - return new PatternLayout(str); - } - throw ConversionNotSupportedException.Create(typeof(PatternLayout), source); - } - - #endregion - } -} diff --git a/src/log4net/Util/TypeConverters/PatternStringConverter.cs b/src/log4net/Util/TypeConverters/PatternStringConverter.cs deleted file mode 100644 index 2c79552f..00000000 --- a/src/log4net/Util/TypeConverters/PatternStringConverter.cs +++ /dev/null @@ -1,140 +0,0 @@ -#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 System.Text; - -using log4net.Util; - -namespace log4net.Util.TypeConverters -{ - /// - /// Convert between string and - /// - /// - /// - /// Supports conversion from string to type, - /// and from a type to a string. - /// - /// - /// The string is used as the - /// of the . - /// - /// - /// - /// - /// - /// Nicko Cadell - internal class PatternStringConverter : IConvertTo, IConvertFrom - { - #region Implementation of IConvertTo - - /// - /// Can the target type be converted to the type supported by this object - /// - /// A that represents the type you want to convert to - /// true if the conversion is possible - /// - /// - /// Returns true if the is - /// assignable from a type. - /// - /// - public bool CanConvertTo(Type targetType) - { - return (typeof(string).IsAssignableFrom(targetType)); - } - - /// - /// Converts the given value object to the specified type, using the arguments - /// - /// the object to convert - /// The Type to convert the value parameter to - /// the converted object - /// - /// - /// Uses the method to convert the - /// argument to a . - /// - /// - /// - /// The object cannot be converted to the - /// . To check for this condition use the - /// method. - /// - public object ConvertTo(object source, Type targetType) - { - PatternString patternString = source as PatternString; - if (patternString != null && CanConvertTo(targetType)) - { - return patternString.Format(); - } - throw ConversionNotSupportedException.Create(targetType, source); - } - - #endregion - - #region Implementation of IConvertFrom - - /// - /// Can the source type be converted to the type supported by this object - /// - /// the type to convert - /// true if the conversion is possible - /// - /// - /// Returns true if the is - /// the type. - /// - /// - public bool CanConvertFrom(System.Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Overrides the ConvertFrom method of IConvertFrom. - /// - /// the object to convert to a PatternString - /// the PatternString - /// - /// - /// Creates and returns a new using - /// the as the - /// . - /// - /// - /// - /// The object cannot be converted to the - /// target type. To check for this condition use the - /// method. - /// - public object ConvertFrom(object source) - { - string str = source as string; - if (str != null) - { - return new PatternString(str); - } - throw ConversionNotSupportedException.Create(typeof(PatternString), source); - } - - #endregion - } -} diff --git a/src/log4net/Util/TypeConverters/TypeConverter.cs b/src/log4net/Util/TypeConverters/TypeConverter.cs deleted file mode 100644 index 8fc8150c..00000000 --- a/src/log4net/Util/TypeConverters/TypeConverter.cs +++ /dev/null @@ -1,87 +0,0 @@ -#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 System.Text; - -namespace log4net.Util.TypeConverters -{ - /// - /// Supports conversion from string to type. - /// - /// - /// - /// Supports conversion from string to type. - /// - /// - /// - /// - /// - /// Nicko Cadell - internal class TypeConverter : IConvertFrom - { - #region Implementation of IConvertFrom - - /// - /// Can the source type be converted to the type supported by this object - /// - /// the type to convert - /// true if the conversion is possible - /// - /// - /// Returns true if the is - /// the type. - /// - /// - public bool CanConvertFrom(Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Overrides the ConvertFrom method of IConvertFrom. - /// - /// the object to convert to a Type - /// the Type - /// - /// - /// Uses the method to convert the - /// argument to a . - /// Additional effort is made to locate partially specified types - /// by searching the loaded assemblies. - /// - /// - /// - /// The object cannot be converted to the - /// target type. To check for this condition use the - /// method. - /// - public object ConvertFrom(object source) - { - string str = source as string; - if (str != null) - { - return SystemInfo.GetTypeFromString(str, true, true); - } - throw ConversionNotSupportedException.Create(typeof(Type), source); - } - - #endregion - } -} diff --git a/src/log4net/Util/TypeConverters/TypeConverterAttribute.cs b/src/log4net/Util/TypeConverters/TypeConverterAttribute.cs deleted file mode 100644 index 196c5a81..00000000 --- a/src/log4net/Util/TypeConverters/TypeConverterAttribute.cs +++ /dev/null @@ -1,116 +0,0 @@ -#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; - -namespace log4net.Util.TypeConverters -{ - /// - /// Attribute used to associate a type converter - /// - /// - /// - /// Class and Interface level attribute that specifies a type converter - /// to use with the associated type. - /// - /// - /// To associate a type converter with a target type apply a - /// TypeConverterAttribute to the target type. Specify the - /// type of the type converter on the attribute. - /// - /// - /// Nicko Cadell - /// Gert Driesen - [AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface|AttributeTargets.Enum)] - public sealed class TypeConverterAttribute : Attribute - { - #region Member Variables - - /// - /// The string type name of the type converter - /// - private string m_typeName = null; - - #endregion - - #region Constructors - - /// - /// Default constructor - /// - /// - /// - /// Default constructor - /// - /// - public TypeConverterAttribute() - { - } - - /// - /// Create a new type converter attribute for the specified type name - /// - /// The string type name of the type converter - /// - /// - /// The type specified must implement the - /// or the interfaces. - /// - /// - public TypeConverterAttribute(string typeName) - { - m_typeName = typeName; - } - - /// - /// Create a new type converter attribute for the specified type - /// - /// The type of the type converter - /// - /// - /// The type specified must implement the - /// or the interfaces. - /// - /// - public TypeConverterAttribute(Type converterType) - { - m_typeName = log4net.Util.SystemInfo.AssemblyQualifiedName(converterType); - } - - #endregion - - /// - /// The string type name of the type converter - /// - /// - /// The string type name of the type converter - /// - /// - /// - /// The type specified must implement the - /// or the interfaces. - /// - /// - public string ConverterTypeName - { - get { return m_typeName; } - set { m_typeName = value ; } - } - } -} diff --git a/src/log4net/Util/WindowsSecurityContext.cs b/src/log4net/Util/WindowsSecurityContext.cs deleted file mode 100644 index 0ee0eb0d..00000000 --- a/src/log4net/Util/WindowsSecurityContext.cs +++ /dev/null @@ -1,378 +0,0 @@ -#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 - -// .NET Compact Framework has no support for WindowsIdentity -#if !NETCF - -using System; -using System.Runtime.InteropServices; -using System.Security.Principal; -using System.Security.Permissions; - -using log4net.Core; - -namespace log4net.Util -{ - /// - /// Impersonate a Windows Account - /// - /// - /// - /// This impersonates a Windows account. - /// - /// - /// How the impersonation is done depends on the value of . - /// This allows the context to either impersonate a set of user credentials specified - /// using username, domain name and password or to revert to the process credentials. - /// - /// - public class WindowsSecurityContext : SecurityContext, IOptionHandler - { - /// - /// The impersonation modes for the - /// - /// - /// - /// See the property for - /// details. - /// - /// - public enum ImpersonationMode - { - /// - /// Impersonate a user using the credentials supplied - /// - User, - - /// - /// Revert this the thread to the credentials of the process - /// - Process - } - - #region Member Variables - - private ImpersonationMode m_impersonationMode = ImpersonationMode.User; - private string m_userName; - private string m_domainName = Environment.MachineName; - private string m_password; - private WindowsIdentity m_identity; - - #endregion - - #region Constructor - - /// - /// Default constructor - /// - /// - /// - /// Default constructor - /// - /// - public WindowsSecurityContext() - { - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the impersonation mode for this security context - /// - /// - /// The impersonation mode for this security context - /// - /// - /// - /// Impersonate either a user with user credentials or - /// revert this thread to the credentials of the process. - /// The value is one of the - /// enum. - /// - /// - /// The default value is - /// - /// - /// When the mode is set to - /// the user's credentials are established using the - /// , and - /// values. - /// - /// - /// When the mode is set to - /// no other properties need to be set. If the calling thread is - /// impersonating then it will be reverted back to the process credentials. - /// - /// - public ImpersonationMode Credentials - { - get { return m_impersonationMode; } - set { m_impersonationMode = value; } - } - - /// - /// Gets or sets the Windows username for this security context - /// - /// - /// The Windows username for this security context - /// - /// - /// - /// This property must be set if - /// is set to (the default setting). - /// - /// - public string UserName - { - get { return m_userName; } - set { m_userName = value; } - } - - /// - /// Gets or sets the Windows domain name for this security context - /// - /// - /// The Windows domain name for this security context - /// - /// - /// - /// The default value for is the local machine name - /// taken from the property. - /// - /// - /// This property must be set if - /// is set to (the default setting). - /// - /// - public string DomainName - { - get { return m_domainName; } - set { m_domainName = value; } - } - - /// - /// Sets the password for the Windows account specified by the and properties. - /// - /// - /// The password for the Windows account specified by the and properties. - /// - /// - /// - /// This property must be set if - /// is set to (the default setting). - /// - /// - public string Password - { - set { m_password = value; } - } - - #endregion - - #region IOptionHandler Members - - /// - /// Initialize the SecurityContext based on the options set. - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// The security context will try to Logon the specified user account and - /// capture a primary token for impersonation. - /// - /// - /// The required , - /// or properties were not specified. - public void ActivateOptions() - { - if (m_impersonationMode == ImpersonationMode.User) - { - if (m_userName == null) throw new ArgumentNullException("m_userName"); - if (m_domainName == null) throw new ArgumentNullException("m_domainName"); - if (m_password == null) throw new ArgumentNullException("m_password"); - - m_identity = LogonUser(m_userName, m_domainName, m_password); - } - } - - #endregion - - /// - /// Impersonate the Windows account specified by the and properties. - /// - /// caller provided state - /// - /// An instance that will revoke the impersonation of this SecurityContext - /// - /// - /// - /// Depending on the property either - /// impersonate a user using credentials supplied or revert - /// to the process credentials. - /// - /// - public override IDisposable Impersonate(object state) - { - if (m_impersonationMode == ImpersonationMode.User) - { - if (m_identity != null) - { - return new DisposableImpersonationContext(m_identity.Impersonate()); - } - } - else if (m_impersonationMode == ImpersonationMode.Process) - { - // Impersonate(0) will revert to the process credentials - return new DisposableImpersonationContext(WindowsIdentity.Impersonate(IntPtr.Zero)); - } - return null; - } - - /// - /// Create a given the userName, domainName and password. - /// - /// the user name - /// the domain name - /// the password - /// the for the account specified - /// - /// - /// Uses the Windows API call LogonUser to get a principal token for the account. This - /// token is used to initialize the WindowsIdentity. - /// - /// -#if FRAMEWORK_4_0_OR_ABOVE - [System.Security.SecuritySafeCritical] -#endif - [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] - private static WindowsIdentity LogonUser(string userName, string domainName, string password) - { - const int LOGON32_PROVIDER_DEFAULT = 0; - //This parameter causes LogonUser to create a primary token. - const int LOGON32_LOGON_INTERACTIVE = 2; - - // Call LogonUser to obtain a handle to an access token. - IntPtr tokenHandle = IntPtr.Zero; - if(!LogonUser(userName, domainName, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle)) - { - NativeError error = NativeError.GetLastError(); - throw new Exception("Failed to LogonUser ["+userName+"] in Domain ["+domainName+"]. Error: "+ error.ToString()); - } - - const int SecurityImpersonation = 2; - IntPtr dupeTokenHandle = IntPtr.Zero; - if(!DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle)) - { - NativeError error = NativeError.GetLastError(); - if (tokenHandle != IntPtr.Zero) - { - CloseHandle(tokenHandle); - } - throw new Exception("Failed to DuplicateToken after LogonUser. Error: " + error.ToString()); - } - - WindowsIdentity identity = new WindowsIdentity(dupeTokenHandle); - - // Free the tokens. - if (dupeTokenHandle != IntPtr.Zero) - { - CloseHandle(dupeTokenHandle); - } - if (tokenHandle != IntPtr.Zero) - { - CloseHandle(tokenHandle); - } - - return identity; - } - - #region Native Method Stubs - - [DllImport("advapi32.dll", SetLastError=true)] - private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); - - [DllImport("kernel32.dll", CharSet=CharSet.Auto)] - private extern static bool CloseHandle(IntPtr handle); - - [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] - private extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); - - #endregion - - #region DisposableImpersonationContext class - - /// - /// Adds to - /// - /// - /// - /// Helper class to expose the - /// through the interface. - /// - /// - private sealed class DisposableImpersonationContext : IDisposable - { - private readonly WindowsImpersonationContext m_impersonationContext; - - /// - /// Constructor - /// - /// the impersonation context being wrapped - /// - /// - /// Constructor - /// - /// - public DisposableImpersonationContext(WindowsImpersonationContext impersonationContext) - { - m_impersonationContext = impersonationContext; - } - - /// - /// Revert the impersonation - /// - /// - /// - /// Revert the impersonation - /// - /// - public void Dispose() - { - m_impersonationContext.Undo(); - } - } - - #endregion - } -} - -#endif // !NETCF - diff --git a/src/log4net/log4net.vs2008.csproj b/src/log4net/log4net.vs2008.csproj deleted file mode 100644 index fecd2d7c..00000000 --- a/src/log4net/log4net.vs2008.csproj +++ /dev/null @@ -1,754 +0,0 @@ - - - - - - Local - 9.0.30729 - 2.0 - {181FE707-E161-4722-9F38-6AAAB6FAA106} - Debug - AnyCPU - - - - - log4net-1.3 - - - JScript - Grid - IE50 - false - Library - log4net - - - - - - - 2.0 - - - ..\..\build\bin\log4net\net\2.0\debug\ - false - 285212672 - false - - - TRACE;DEBUG;DOTNET - log4net-1.3.xml - true - 4096 - false - false - false - false - 4 - full - prompt - - - ..\..\build\bin\log4net\net\2.0\release\ - false - 285212672 - false - - - TRACE;STRONG;DOTNET; - log4net-1.3.xml - true - 4096 - true - false - false - false - 4 - pdbonly - prompt - - - - System - - - - System.Data - - - System.Web - - - System.XML - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - - - - - - diff --git a/src/log4net/log4net.vs2008.sln b/src/log4net/log4net.vs2008.sln deleted file mode 100644 index 0442d222..00000000 --- a/src/log4net/log4net.vs2008.sln +++ /dev/null @@ -1,45 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -# -# -# 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. -# -# -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.vs2008", "log4net.vs2008.csproj", "{181FE707-E161-4722-9F38-6AAAB6FAA106}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Tests.vs2008", "..\log4net.Tests\log4net.Tests.vs2008.csproj", "{B0530F10-0238-49A9-93B0-8EF412E90BCF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.Build.0 = Debug|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.ActiveCfg = Release|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.Build.0 = Release|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/log4net/log4net.vs2010.csproj b/src/log4net/log4net.vs2010.csproj deleted file mode 100644 index dfbaa537..00000000 --- a/src/log4net/log4net.vs2010.csproj +++ /dev/null @@ -1,793 +0,0 @@ - - - - - Local - 9.0.30729 - 2.0 - {181FE707-E161-4722-9F38-6AAAB6FAA106} - Debug - AnyCPU - - - - - log4net-1.3 - - - JScript - Grid - IE50 - false - Library - log4net - - - - - - - 3.5 - v4.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - ..\..\build\bin\log4net\net\2.0\debug\ - false - 285212672 - false - - - TRACE;DEBUG;DOTNET;FRAMEWORK_3_5_OR_ABOVE;FRAMEWORK_4_0_OR_ABOVE - log4net-1.3.xml - true - 4096 - false - false - false - false - 4 - full - prompt - SecurityRules.ruleset - - - ..\..\build\bin\log4net\net\2.0\release\ - false - 285212672 - false - - - TRACE;STRONG;DOTNET;FRAMEWORK_3_5_OR_ABOVE;FRAMEWORK_4_0_OR_ABOVE - log4net-1.3.xml - true - 4096 - true - false - false - false - 4 - pdbonly - prompt - AllRules.ruleset - - - - System - - - - System.Data - - - System.Web - - - System.XML - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - - - - - - diff --git a/src/log4net/log4net.vs2010.sln b/src/log4net/log4net.vs2010.sln deleted file mode 100644 index 17b9aa54..00000000 --- a/src/log4net/log4net.vs2010.sln +++ /dev/null @@ -1,45 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -# -# -# 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. -# -# -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.vs2010", "log4net.vs2010.csproj", "{181FE707-E161-4722-9F38-6AAAB6FAA106}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Tests.vs2010", "..\log4net.Tests\log4net.Tests.vs2010.csproj", "{B0530F10-0238-49A9-93B0-8EF412E90BCF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.Build.0 = Debug|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.ActiveCfg = Release|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.Build.0 = Release|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/log4net/log4net.vs2012.csproj b/src/log4net/log4net.vs2012.csproj deleted file mode 100644 index 42e6aa64..00000000 --- a/src/log4net/log4net.vs2012.csproj +++ /dev/null @@ -1,793 +0,0 @@ - - - - - Local - 9.0.30729 - 2.0 - {181FE707-E161-4722-9F38-6AAAB6FAA106} - Debug - AnyCPU - - - - - log4net-1.3 - - - JScript - Grid - IE50 - false - Library - log4net - - - - - - - 3.5 - v4.5 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - ..\..\build\bin\log4net\net\4.5\debug\ - false - 285212672 - false - - - TRACE;DEBUG;DOTNET;FRAMEWORK_3_5_OR_ABOVE;FRAMEWORK_4_0_OR_ABOVE;FRAMEWORK_4_5_OR_ABOVE - log4net-1.3.xml - true - 4096 - false - false - false - false - 4 - full - prompt - SecurityRules.ruleset - - - ..\..\build\bin\log4net\net\4.5\release\ - false - 285212672 - false - - - TRACE;STRONG;DOTNET;FRAMEWORK_3_5_OR_ABOVE;FRAMEWORK_4_0_OR_ABOVE;FRAMEWORK_4_5_OR_ABOVE - log4net-1.3.xml - true - 4096 - true - false - false - false - 4 - pdbonly - prompt - AllRules.ruleset - - - - System - - - - System.Data - - - System.Web - - - System.XML - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - - - - - - \ No newline at end of file diff --git a/src/log4net/log4net.vs2012.sln b/src/log4net/log4net.vs2012.sln deleted file mode 100644 index 89702486..00000000 --- a/src/log4net/log4net.vs2012.sln +++ /dev/null @@ -1,37 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.vs2012", "log4net.vs2012.csproj", "{181FE707-E161-4722-9F38-6AAAB6FAA106}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Tests.vs2012", "..\log4net.Tests\log4net.Tests.vs2012.csproj", "{B0530F10-0238-49A9-93B0-8EF412E90BCF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Ext.EventID.vs2012", "..\extensions\log4net.Ext.EventID\log4net.Ext.EventID.vs2012.csproj", "{CB985027-C009-4C0F-88C1-8CF11912EE4C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Ext.MarshalByRef.vs2012", "..\extensions\log4net.Ext.MarshalByRef\log4net.Ext.MarshalByRef.vs2012.csproj", "{CB985027-C009-4C0F-88C1-8CF11912AE4C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.Build.0 = Debug|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.ActiveCfg = Release|Any CPU - {181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.Build.0 = Release|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.Build.0 = Release|Any CPU - {CB985027-C009-4C0F-88C1-8CF11912EE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CB985027-C009-4C0F-88C1-8CF11912EE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CB985027-C009-4C0F-88C1-8CF11912EE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CB985027-C009-4C0F-88C1-8CF11912EE4C}.Release|Any CPU.Build.0 = Release|Any CPU - {CB985027-C009-4C0F-88C1-8CF11912AE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CB985027-C009-4C0F-88C1-8CF11912AE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CB985027-C009-4C0F-88C1-8CF11912AE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CB985027-C009-4C0F-88C1-8CF11912AE4C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/playground/AbsoluteTimeDateFormatterTiming.cs b/src/playground/AbsoluteTimeDateFormatterTiming.cs deleted file mode 100644 index e5a641da..00000000 --- a/src/playground/AbsoluteTimeDateFormatterTiming.cs +++ /dev/null @@ -1,64 +0,0 @@ -#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 System.IO; -using System.Threading; -using log4net.DateFormatter; - -namespace log4net.playground { - - // dmcs -m:log4net.playground.AbsoluteTimeDateFormatterTiming -r:build/bin/log4net-1.3/mono/4.0/debug/log4net-1.3.dll src/playground/AbsoluteTimeDateFormatterTiming.cs - public class AbsoluteTimeDateFormatterTiming { - - private static long TICKS = 0; - - private static readonly Random RND = new Random(Environment.TickCount); - private static readonly AbsoluteTimeDateFormatter F = new AbsoluteTimeDateFormatter(); - - public static void Main(string[] args) { - - Thread[] threads = new Thread[20]; - for (int i = 0; i < threads.Length; i++) { - threads[i] = new Thread(SingleThread); - threads[i].Start(); - } - for (int i = 0; i < threads.Length; i++) { - threads[i].Join(); - } - - Console.Error.WriteLine("used {0} ticks", TICKS); - } - - private static void SingleThread() { - StringWriter sw = new StringWriter(); - for (int i = 0; i < 1000; i++) { - Thread.Sleep(RND.Next(15)); - int before = Environment.TickCount; - for (int j = 0; j < 1000; j++) { - F.FormatDate(DateTime.Now, sw); - } - int after = Environment.TickCount; - Interlocked.Add(ref TICKS, after - before); - } - } - - } - -} \ No newline at end of file diff --git a/tests.build b/tests.build deleted file mode 100644 index 59d992dd..00000000 --- a/tests.build +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 2deb2119247a48be84972e3118f8e1af7900d178 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 7 Oct 2015 03:54:57 +0000 Subject: [PATCH 330/370] bring back 1.2.x branch as trunk git-svn-id: https://svn.apache.org/repos/asf/logging/log4net/trunk@1707180 13f79535-47bb-0310-9956-ffa450edef68 --- KEYS | 602 +++++ LICENSE | 201 ++ NOTICE | 5 + README.txt | 16 + STATUS.txt | 31 + build.cmd | 131 ++ .../1.0/Performance/NotLogging/cs/nant.build | 45 + .../1.0/Performance/NotLogging/cs/nant.config | 23 + .../NotLogging/cs/src/AssemblyInfo.cs | 61 + .../NotLogging/cs/src/NotLogging.cs | 434 ++++ .../1.0/Performance/NotLogging/nant.build | 29 + .../1.0/Performance/NotLogging/nant.config | 21 + examples/mono/1.0/Performance/nant.build | 29 + examples/mono/1.0/Performance/nant.config | 21 + .../1.0/Repository/SharedModule/cs/nant.build | 39 + .../Repository/SharedModule/cs/nant.config | 23 + .../SharedModule/cs/src/AssemblyInfo.cs | 61 + .../Repository/SharedModule/cs/src/Math.cs | 42 + .../1.0/Repository/SharedModule/nant.build | 29 + .../1.0/Repository/SharedModule/nant.config | 21 + .../1.0/Repository/SimpleApp/cs/nant.build | 67 + .../1.0/Repository/SimpleApp/cs/nant.config | 23 + .../Repository/SimpleApp/cs/src/App.config | 30 + .../SimpleApp/cs/src/AssemblyInfo.cs | 61 + .../Repository/SimpleApp/cs/src/EntryPoint.cs | 80 + .../SimpleApp/cs/src/SimpleApp.exe.log4net | 15 + .../mono/1.0/Repository/SimpleApp/nant.build | 29 + .../mono/1.0/Repository/SimpleApp/nant.config | 21 + .../1.0/Repository/SimpleModule/cs/nant.build | 41 + .../Repository/SimpleModule/cs/nant.config | 23 + .../SimpleModule/cs/src/AssemblyInfo.cs | 61 + .../Repository/SimpleModule/cs/src/Math.cs | 49 + .../cs/src/SimpleModule.dll.log4net | 15 + .../1.0/Repository/SimpleModule/nant.build | 29 + .../1.0/Repository/SimpleModule/nant.config | 21 + examples/mono/1.0/Repository/nant.build | 29 + examples/mono/1.0/Repository/nant.config | 21 + .../1.0/Tutorials/ConsoleApp/cs/nant.build | 47 + .../1.0/Tutorials/ConsoleApp/cs/nant.config | 23 + .../Tutorials/ConsoleApp/cs/src/App.config | 208 ++ .../ConsoleApp/cs/src/AssemblyInfo.cs | 61 + .../ConsoleApp/cs/src/LoggingExample.cs | 112 + .../mono/1.0/Tutorials/ConsoleApp/nant.build | 23 + .../mono/1.0/Tutorials/ConsoleApp/nant.config | 21 + examples/mono/1.0/Tutorials/nant.build | 23 + examples/mono/1.0/Tutorials/nant.config | 21 + examples/mono/1.0/nant.build | 41 + examples/mono/1.0/nant.config | 25 + examples/mono/nant.build | 29 + examples/mono/nant.config | 23 + examples/nant.build | 31 + examples/nant.config | 21 + .../1.1/Repository/SharedModule/js/nant.build | 39 + .../Repository/SharedModule/js/nant.config | 23 + .../SharedModule/js/src/AssemblyInfo.js | 61 + .../Repository/SharedModule/js/src/Math.js | 37 + .../1.1/Repository/SharedModule/nant.build | 29 + .../1.1/Repository/SharedModule/nant.config | 21 + .../1.1/Repository/SimpleApp/js/nant.build | 67 + .../1.1/Repository/SimpleApp/js/nant.config | 23 + .../Repository/SimpleApp/js/src/App.config | 29 + .../SimpleApp/js/src/AssemblyInfo.js | 61 + .../Repository/SimpleApp/js/src/EntryPoint.js | 79 + .../SimpleApp/js/src/SimpleApp.exe.log4net | 16 + .../net/1.1/Repository/SimpleApp/nant.build | 29 + .../net/1.1/Repository/SimpleApp/nant.config | 21 + .../1.1/Repository/SimpleModule/js/nant.build | 41 + .../Repository/SimpleModule/js/nant.config | 23 + .../SimpleModule/js/src/AssemblyInfo.js | 61 + .../Repository/SimpleModule/js/src/Math.js | 45 + .../js/src/SimpleModule.dll.log4net | 16 + .../1.1/Repository/SimpleModule/nant.build | 29 + .../1.1/Repository/SimpleModule/nant.config | 21 + examples/net/1.1/Repository/nant.build | 25 + examples/net/1.1/Repository/nant.config | 21 + .../1.1/Tutorials/ConsoleApp/cpp/nant.build | 53 + .../1.1/Tutorials/ConsoleApp/cpp/nant.config | 23 + .../Tutorials/ConsoleApp/cpp/src/App.config | 214 ++ .../ConsoleApp/cpp/src/AssemblyInfo.cpp | 59 + .../ConsoleApp/cpp/src/ConsoleApp.cpp | 133 ++ .../ConsoleApp/cpp/src/ConsoleApp.vcproj | 186 ++ .../1.1/Tutorials/ConsoleApp/js/nant.build | 47 + .../1.1/Tutorials/ConsoleApp/js/nant.config | 23 + .../Tutorials/ConsoleApp/js/src/App.config | 214 ++ .../ConsoleApp/js/src/AssemblyInfo.js | 61 + .../ConsoleApp/js/src/LoggingExample.js | 104 + .../net/1.1/Tutorials/ConsoleApp/nant.build | 23 + .../net/1.1/Tutorials/ConsoleApp/nant.config | 21 + examples/net/1.1/Tutorials/nant.build | 23 + examples/net/1.1/Tutorials/nant.config | 21 + examples/net/1.1/cpp-examples.sln | 41 + examples/net/1.1/nant.build | 41 + examples/net/1.1/nant.config | 25 + .../SampleAppendersApp/cs/nant.build | 52 + .../SampleAppendersApp/cs/nant.config | 23 + .../SampleAppendersApp/cs/src/App.config | 126 ++ .../cs/src/Appender/AsyncAppender.cs | 194 ++ .../cs/src/Appender/FastDbAppender.cs | 201 ++ .../cs/src/Appender/FireEventAppender.cs | 90 + .../cs/src/Appender/MessageBoxAppender.cs | 103 + .../Appender/MessageObjectExpanderAppender.cs | 83 + .../cs/src/Appender/MsmqAppender.cs | 104 + .../cs/src/Appender/PatternFileAppender.cs | 124 ++ .../Appender/PatternLayoutAdoNetAppender.cs | 86 + .../PatternLayoutAdoNetAppenderParameter.cs | 34 + .../cs/src/Appender/SimpleSmtpAppender.cs | 132 ++ .../SampleAppendersApp/cs/src/AssemblyInfo.cs | 61 + .../cs/src/LoggingExample.cs | 139 ++ .../cs/src/SampleAppendersApp.csproj | 165 ++ .../Appenders/SampleAppendersApp/nant.build | 29 + .../Appenders/SampleAppendersApp/nant.config | 21 + .../2.0/Appenders/WmiAppender/cs/nant.build | 48 + .../2.0/Appenders/WmiAppender/cs/nant.config | 23 + .../WmiAppender/cs/src/AssemblyInfo.cs | 67 + .../WmiAppender/cs/src/IWmiBoundEvent.cs | 53 + .../WmiAppender/cs/src/WmiAppender.cs | 255 +++ .../WmiAppender/cs/src/WmiAppender.csproj | 134 ++ .../WmiAppender/cs/src/WmiInstaller.cs | 32 + .../Appenders/WmiAppender/cs/src/WmiLayout.cs | 100 + .../WmiAppender/cs/src/WmiLoggingEvent.cs | 47 + .../net/2.0/Appenders/WmiAppender/nant.build | 29 + .../net/2.0/Appenders/WmiAppender/nant.config | 21 + examples/net/2.0/Appenders/nant.build | 29 + examples/net/2.0/Appenders/nant.config | 21 + .../Extensibility/EventIDLogApp/cs/nant.build | 57 + .../EventIDLogApp/cs/nant.config | 23 + .../EventIDLogApp/cs/src/App.config | 57 + .../EventIDLogApp/cs/src/AssemblyInfo.cs | 61 + .../EventIDLogApp/cs/src/EventIDLogApp.cs | 47 + .../EventIDLogApp/cs/src/EventIDLogApp.csproj | 138 ++ .../Extensibility/EventIDLogApp/nant.build | 29 + .../Extensibility/EventIDLogApp/nant.config | 21 + .../Extensibility/TraceLogApp/cs/nant.build | 57 + .../Extensibility/TraceLogApp/cs/nant.config | 23 + .../TraceLogApp/cs/src/AssemblyInfo.cs | 61 + .../TraceLogApp/cs/src/TraceLogApp.cs | 47 + .../TraceLogApp/cs/src/TraceLogApp.csproj | 136 ++ .../cs/src/TraceLogApp.exe.log4net | 18 + .../2.0/Extensibility/TraceLogApp/nant.build | 29 + .../2.0/Extensibility/TraceLogApp/nant.config | 21 + examples/net/2.0/Extensibility/nant.build | 29 + examples/net/2.0/Extensibility/nant.config | 21 + .../Layouts/SampleLayoutsApp/cs/nant.build | 50 + .../Layouts/SampleLayoutsApp/cs/nant.config | 23 + .../SampleLayoutsApp/cs/src/App.config | 59 + .../SampleLayoutsApp/cs/src/AssemblyInfo.cs | 61 + .../cs/src/Layout/ForwardingLayout.cs | 202 ++ .../cs/src/Layout/LevelConversionPattern.cs | 41 + .../cs/src/Layout/LevelPatternLayout.cs | 50 + .../cs/src/Layout/LineWrappingLayout.cs | 102 + .../SampleLayoutsApp/cs/src/LoggingExample.cs | 67 + .../cs/src/SampleLayoutsApp.csproj | 142 ++ .../2.0/Layouts/SampleLayoutsApp/nant.build | 29 + .../2.0/Layouts/SampleLayoutsApp/nant.config | 21 + examples/net/2.0/Layouts/nant.build | 29 + examples/net/2.0/Layouts/nant.config | 21 + .../2.0/Performance/NotLogging/cs/nant.build | 45 + .../2.0/Performance/NotLogging/cs/nant.config | 23 + .../NotLogging/cs/src/AssemblyInfo.cs | 61 + .../NotLogging/cs/src/NotLogging.cs | 437 ++++ .../NotLogging/cs/src/NotLogging.csproj | 131 ++ .../net/2.0/Performance/NotLogging/nant.build | 29 + .../2.0/Performance/NotLogging/nant.config | 21 + .../2.0/Performance/NotLogging/vb/nant.build | 45 + .../2.0/Performance/NotLogging/vb/nant.config | 23 + .../NotLogging/vb/src/AssemblyInfo.vb | 61 + .../NotLogging/vb/src/NotLogging.vb | 417 ++++ .../NotLogging/vb/src/NotLogging.vbproj | 130 ++ examples/net/2.0/Performance/nant.build | 29 + examples/net/2.0/Performance/nant.config | 21 + .../2.0/Remoting/RemotingClient/cs/nant.build | 47 + .../Remoting/RemotingClient/cs/nant.config | 23 + .../Remoting/RemotingClient/cs/src/App.config | 63 + .../RemotingClient/cs/src/AssemblyInfo.cs | 61 + .../RemotingClient/cs/src/RemotingClient.cs | 80 + .../cs/src/RemotingClient.csproj | 126 ++ .../2.0/Remoting/RemotingClient/nant.build | 29 + .../2.0/Remoting/RemotingClient/nant.config | 21 + .../2.0/Remoting/RemotingServer/cs/nant.build | 47 + .../Remoting/RemotingServer/cs/nant.config | 23 + .../Remoting/RemotingServer/cs/src/App.config | 59 + .../RemotingServer/cs/src/AssemblyInfo.cs | 61 + .../RemotingServer/cs/src/RemotingServer.cs | 63 + .../cs/src/RemotingServer.csproj | 125 ++ .../2.0/Remoting/RemotingServer/nant.build | 29 + .../2.0/Remoting/RemotingServer/nant.config | 21 + examples/net/2.0/Remoting/nant.build | 29 + examples/net/2.0/Remoting/nant.config | 21 + .../2.0/Repository/SharedModule/cs/nant.build | 39 + .../Repository/SharedModule/cs/nant.config | 23 + .../SharedModule/cs/src/AssemblyInfo.cs | 61 + .../Repository/SharedModule/cs/src/Math.cs | 42 + .../SharedModule/cs/src/SharedModule.csproj | 132 ++ .../2.0/Repository/SharedModule/nant.build | 29 + .../2.0/Repository/SharedModule/nant.config | 21 + .../2.0/Repository/SharedModule/vb/nant.build | 39 + .../Repository/SharedModule/vb/nant.config | 23 + .../SharedModule/vb/src/AssemblyInfo.vb | 61 + .../Repository/SharedModule/vb/src/Math.vb | 35 + .../SharedModule/vb/src/SharedModule.vbproj | 130 ++ .../2.0/Repository/SimpleApp/cs/nant.build | 67 + .../2.0/Repository/SimpleApp/cs/nant.config | 23 + .../Repository/SimpleApp/cs/src/App.config | 29 + .../SimpleApp/cs/src/AssemblyInfo.cs | 61 + .../Repository/SimpleApp/cs/src/EntryPoint.cs | 80 + .../SimpleApp/cs/src/SimpleApp.csproj | 143 ++ .../SimpleApp/cs/src/SimpleApp.exe.log4net | 16 + .../net/2.0/Repository/SimpleApp/nant.build | 29 + .../net/2.0/Repository/SimpleApp/nant.config | 21 + .../2.0/Repository/SimpleApp/vb/nant.build | 67 + .../2.0/Repository/SimpleApp/vb/nant.config | 23 + .../Repository/SimpleApp/vb/src/App.config | 29 + .../SimpleApp/vb/src/AssemblyInfo.vb | 61 + .../Repository/SimpleApp/vb/src/EntryPoint.vb | 69 + .../SimpleApp/vb/src/SimpleApp.exe.log4net | 16 + .../SimpleApp/vb/src/SimpleApp.vbproj | 144 ++ .../2.0/Repository/SimpleModule/cs/nant.build | 41 + .../Repository/SimpleModule/cs/nant.config | 23 + .../SimpleModule/cs/src/AssemblyInfo.cs | 61 + .../Repository/SimpleModule/cs/src/Math.cs | 49 + .../SimpleModule/cs/src/SimpleModule.csproj | 133 ++ .../cs/src/SimpleModule.dll.log4net | 21 + .../2.0/Repository/SimpleModule/nant.build | 29 + .../2.0/Repository/SimpleModule/nant.config | 21 + .../2.0/Repository/SimpleModule/vb/nant.build | 41 + .../Repository/SimpleModule/vb/nant.config | 23 + .../SimpleModule/vb/src/AssemblyInfo.vb | 61 + .../Repository/SimpleModule/vb/src/Math.vb | 42 + .../vb/src/SimpleModule.dll.log4net | 21 + .../SimpleModule/vb/src/SimpleModule.vbproj | 134 ++ examples/net/2.0/Repository/nant.build | 29 + examples/net/2.0/Repository/nant.config | 21 + .../2.0/Tutorials/ConsoleApp/cs/nant.build | 47 + .../2.0/Tutorials/ConsoleApp/cs/nant.config | 23 + .../Tutorials/ConsoleApp/cs/src/App.config | 214 ++ .../ConsoleApp/cs/src/AssemblyInfo.cs | 61 + .../ConsoleApp/cs/src/ConsoleApp.csproj | 132 ++ .../ConsoleApp/cs/src/LoggingExample.cs | 112 + .../net/2.0/Tutorials/ConsoleApp/nant.build | 29 + .../net/2.0/Tutorials/ConsoleApp/nant.config | 21 + .../2.0/Tutorials/ConsoleApp/vb/nant.build | 47 + .../2.0/Tutorials/ConsoleApp/vb/nant.config | 23 + .../Tutorials/ConsoleApp/vb/src/App.config | 214 ++ .../ConsoleApp/vb/src/AssemblyInfo.vb | 61 + .../ConsoleApp/vb/src/ConsoleApp.vbproj | 134 ++ .../ConsoleApp/vb/src/LoggingExample.vb | 100 + .../net/2.0/Tutorials/WebApp/cs/nant.build | 73 + .../net/2.0/Tutorials/WebApp/cs/nant.config | 23 + .../Tutorials/WebApp/cs/src/AssemblyInfo.cs | 65 + .../WebApp/cs/src/AssemblyVersionInfo.cs | 36 + .../2.0/Tutorials/WebApp/cs/src/Global.asax | 22 + .../Tutorials/WebApp/cs/src/Global.asax.cs | 52 + .../Tutorials/WebApp/cs/src/Global.asax.resx | 63 + .../WebApp/cs/src/SimpleModule.dll.log4net | 23 + .../2.0/Tutorials/WebApp/cs/src/Web.config | 107 + .../2.0/Tutorials/WebApp/cs/src/WebApp.csproj | 191 ++ .../WebApp/cs/src/WebApp.csproj.webinfo | 26 + .../WebApp/cs/src/WebApp.dll.log4net | 32 + .../Tutorials/WebApp/cs/src/WebApp.vsdisco | 30 + .../2.0/Tutorials/WebApp/cs/src/WebForm1.aspx | 48 + .../Tutorials/WebApp/cs/src/WebForm1.aspx.cs | 119 + .../WebApp/cs/src/WebForm1.aspx.resx | 63 + examples/net/2.0/Tutorials/WebApp/nant.build | 39 + examples/net/2.0/Tutorials/WebApp/nant.config | 21 + examples/net/2.0/Tutorials/WebApp/readme.txt | 29 + .../net/2.0/Tutorials/WebApp/vb/nant.build | 73 + .../net/2.0/Tutorials/WebApp/vb/nant.config | 23 + .../Tutorials/WebApp/vb/src/AssemblyInfo.vb | 61 + .../WebApp/vb/src/AssemblyVersionInfo.vb | 36 + .../2.0/Tutorials/WebApp/vb/src/Global.asax | 22 + .../Tutorials/WebApp/vb/src/Global.asax.resx | 63 + .../Tutorials/WebApp/vb/src/Global.asax.vb | 43 + .../WebApp/vb/src/SimpleModule.dll.log4net | 23 + .../2.0/Tutorials/WebApp/vb/src/Web.config | 107 + .../WebApp/vb/src/WebApp.dll.log4net | 32 + .../2.0/Tutorials/WebApp/vb/src/WebApp.vbproj | 193 ++ .../WebApp/vb/src/WebApp.vbproj.webinfo | 26 + .../Tutorials/WebApp/vb/src/WebApp.vsdisco | 30 + .../2.0/Tutorials/WebApp/vb/src/WebForm1.aspx | 48 + .../WebApp/vb/src/WebForm1.aspx.resx | 63 + .../Tutorials/WebApp/vb/src/WebForm1.aspx.vb | 108 + examples/net/2.0/Tutorials/nant.build | 33 + examples/net/2.0/Tutorials/nant.config | 21 + examples/net/2.0/cs-examples.sln | 173 ++ examples/net/2.0/nant.build | 45 + examples/net/2.0/nant.config | 25 + examples/net/2.0/vb-examples.sln | 71 + examples/net/nant.build | 33 + examples/net/nant.config | 23 + .../1.0/Tutorials/ConsoleApp/cs/nant.build | 49 + .../1.0/Tutorials/ConsoleApp/cs/nant.config | 23 + .../ConsoleApp/cs/src/AssemblyInfo.cs | 61 + .../ConsoleApp/cs/src/ConsoleApp.csdproj | 155 ++ .../ConsoleApp/cs/src/ConsoleApp.exe.config | 124 ++ .../Tutorials/ConsoleApp/cs/src/EntryPoint.cs | 75 + .../ConsoleApp/cs/src/LoggingExample.cs | 93 + .../netcf/1.0/Tutorials/ConsoleApp/nant.build | 29 + .../1.0/Tutorials/ConsoleApp/nant.config | 21 + .../1.0/Tutorials/ConsoleApp/vb/nant.build | 48 + .../1.0/Tutorials/ConsoleApp/vb/nant.config | 23 + .../ConsoleApp/vb/src/AssemblyInfo.vb | 61 + .../ConsoleApp/vb/src/ConsoleApp.exe.config | 124 ++ .../ConsoleApp/vb/src/ConsoleApp.vbdproj | 156 ++ .../Tutorials/ConsoleApp/vb/src/EntryPoint.vb | 64 + .../ConsoleApp/vb/src/LoggingExample.vb | 82 + examples/netcf/1.0/Tutorials/nant.build | 29 + examples/netcf/1.0/Tutorials/nant.config | 21 + examples/netcf/1.0/cs-examples.sln | 43 + examples/netcf/1.0/nant.build | 41 + examples/netcf/1.0/nant.config | 25 + examples/netcf/1.0/vb-examples.sln | 43 + examples/netcf/nant.build | 29 + examples/netcf/nant.config | 23 + .../1.0/Repository/SharedModule/cs/nant.build | 39 + .../Repository/SharedModule/cs/nant.config | 23 + .../SharedModule/cs/src/AssemblyInfo.cs | 60 + .../Repository/SharedModule/cs/src/Math.cs | 42 + .../1.0/Repository/SharedModule/nant.build | 29 + .../1.0/Repository/SharedModule/nant.config | 21 + .../1.0/Repository/SimpleApp/cs/nant.build | 67 + .../1.0/Repository/SimpleApp/cs/nant.config | 23 + .../Repository/SimpleApp/cs/src/App.config | 30 + .../SimpleApp/cs/src/AssemblyInfo.cs | 60 + .../Repository/SimpleApp/cs/src/EntryPoint.cs | 79 + .../SimpleApp/cs/src/SimpleApp.exe.log4net | 21 + .../sscli/1.0/Repository/SimpleApp/nant.build | 29 + .../1.0/Repository/SimpleApp/nant.config | 21 + .../1.0/Repository/SimpleModule/cs/nant.build | 41 + .../Repository/SimpleModule/cs/nant.config | 23 + .../SimpleModule/cs/src/AssemblyInfo.cs | 60 + .../Repository/SimpleModule/cs/src/Math.cs | 49 + .../cs/src/SimpleModule.dll.log4net | 21 + .../1.0/Repository/SimpleModule/nant.build | 29 + .../1.0/Repository/SimpleModule/nant.config | 21 + examples/sscli/1.0/Repository/nant.build | 29 + examples/sscli/1.0/Repository/nant.config | 21 + .../1.0/Tutorials/ConsoleApp/js/nant.build | 47 + .../1.0/Tutorials/ConsoleApp/js/nant.config | 23 + .../Tutorials/ConsoleApp/js/src/App.config | 87 + .../ConsoleApp/js/src/AssemblyInfo.js | 62 + .../ConsoleApp/js/src/LoggingExample.js | 104 + .../sscli/1.0/Tutorials/ConsoleApp/nant.build | 29 + .../1.0/Tutorials/ConsoleApp/nant.config | 21 + examples/sscli/1.0/Tutorials/nant.build | 29 + examples/sscli/1.0/Tutorials/nant.config | 21 + examples/sscli/1.0/nant.build | 41 + examples/sscli/1.0/nant.config | 25 + examples/sscli/nant.build | 29 + examples/sscli/nant.config | 23 + extensions/nant.build | 28 + extensions/nant.config | 21 + extensions/net/1.0/cs-extensions.sln | 63 + .../net/1.0/log4net.Ext.EventID/cs/nant.build | 52 + .../1.0/log4net.Ext.EventID/cs/nant.config | 23 + .../cs/src/AssemblyInfo.cs | 63 + .../cs/src/EventIDLogImpl.cs | 101 + .../cs/src/EventIDLogManager.cs | 289 +++ .../log4net.Ext.EventID/cs/src/IEventIDLog.cs | 45 + .../cs/src/log4net.Ext.EventID.csproj | 143 ++ .../net/1.0/log4net.Ext.EventID/nant.build | 29 + .../net/1.0/log4net.Ext.EventID/nant.config | 21 + .../log4net.Ext.MarshalByRef/cs/nant.build | 52 + .../log4net.Ext.MarshalByRef/cs/nant.config | 23 + .../cs/src/AssemblyInfo.cs | 63 + .../cs/src/MarshalByRefLogImpl.cs | 380 ++++ .../cs/src/MarshalByRefLogManager.cs | 292 +++ .../cs/src/log4net.Ext.MarshalByRef.csproj | 133 ++ .../1.0/log4net.Ext.MarshalByRef/nant.build | 29 + .../1.0/log4net.Ext.MarshalByRef/nant.config | 21 + .../net/1.0/log4net.Ext.Trace/cs/nant.build | 52 + .../net/1.0/log4net.Ext.Trace/cs/nant.config | 23 + .../log4net.Ext.Trace/cs/src/AssemblyInfo.cs | 63 + .../1.0/log4net.Ext.Trace/cs/src/ITraceLog.cs | 34 + .../log4net.Ext.Trace/cs/src/TraceLogImpl.cs | 96 + .../cs/src/TraceLogManager.cs | 289 +++ .../cs/src/log4net.Ext.Trace.csproj | 143 ++ .../net/1.0/log4net.Ext.Trace/nant.build | 29 + .../net/1.0/log4net.Ext.Trace/nant.config | 21 + extensions/net/1.0/nant.build | 41 + extensions/net/1.0/nant.config | 25 + extensions/net/nant.build | 29 + extensions/net/nant.config | 23 + log4net.build | 1799 +++++++++++++++ log4net.include | 391 ++++ log4net.snk | Bin 0 -> 596 bytes log4net.snk.readme | 28 + old-log4net.snk.gpg | Bin 0 -> 2535 bytes pom.xml | 256 +++ src/Appender/AdoNetAppender.cs | 1257 +++++++++++ src/Appender/AnsiColorTerminalAppender.cs | 574 +++++ src/Appender/AppenderCollection.cs | 902 ++++++++ src/Appender/AppenderSkeleton.cs | 897 ++++++++ src/Appender/AspNetTraceAppender.cs | 155 ++ src/Appender/BufferingAppenderSkeleton.cs | 647 ++++++ src/Appender/BufferingForwardingAppender.cs | 274 +++ src/Appender/ColoredConsoleAppender.cs | 666 ++++++ src/Appender/ConsoleAppender.cs | 220 ++ src/Appender/DebugAppender.cs | 171 ++ src/Appender/EventLogAppender.cs | 690 ++++++ src/Appender/FileAppender.cs | 1360 ++++++++++++ src/Appender/ForwardingAppender.cs | 279 +++ src/Appender/IAppender.cs | 78 + src/Appender/IBulkAppender.cs | 48 + src/Appender/LocalSyslogAppender.cs | 605 +++++ src/Appender/ManagedColoredConsoleAppender.cs | 348 +++ src/Appender/MemoryAppender.cs | 225 ++ src/Appender/NetSendAppender.cs | 425 ++++ src/Appender/OutputDebugStringAppender.cs | 128 ++ src/Appender/RemoteSyslogAppender.cs | 592 +++++ src/Appender/RemotingAppender.cs | 328 +++ src/Appender/RollingFileAppender.cs | 1726 +++++++++++++++ src/Appender/SmtpAppender.cs | 661 ++++++ src/Appender/SmtpPickupDirAppender.cs | 317 +++ src/Appender/TelnetAppender.cs | 517 +++++ src/Appender/TextWriterAppender.cs | 485 ++++ src/Appender/TraceAppender.cs | 210 ++ src/Appender/UdpAppender.cs | 543 +++++ src/AssemblyInfo.cs | 145 ++ src/AssemblyVersionInfo.cpp | 49 + src/AssemblyVersionInfo.cs | 46 + src/AssemblyVersionInfo.js | 49 + src/AssemblyVersionInfo.vb | 46 + src/Config/AliasDomainAttribute.cs | 74 + src/Config/AliasRepositoryAttribute.cs | 103 + src/Config/BasicConfigurator.cs | 232 ++ src/Config/ConfiguratorAttribute.cs | 113 + src/Config/DOMConfigurator.cs | 358 +++ src/Config/DOMConfiguratorAttribute.cs | 60 + src/Config/DomainAttribute.cs | 87 + .../Log4NetConfigurationSectionHandler.cs | 92 + src/Config/PluginAttribute.cs | 195 ++ src/Config/RepositoryAttribute.cs | 144 ++ .../SecurityContextProviderAttribute.cs | 151 ++ src/Config/XmlConfigurator.cs | 1133 ++++++++++ src/Config/XmlConfiguratorAttribute.cs | 469 ++++ src/Core/CompactRepositorySelector.cs | 357 +++ src/Core/DefaultRepositorySelector.cs | 893 ++++++++ src/Core/ErrorCode.cs | 70 + src/Core/ExceptionEvaluator.cs | 130 ++ src/Core/IAppenderAttachable.cs | 121 + src/Core/IErrorHandler.cs | 75 + src/Core/IFixingRequired.cs | 58 + src/Core/ILogger.cs | 115 + src/Core/ILoggerWrapper.cs | 59 + src/Core/IOptionHandler.cs | 58 + src/Core/IRepositorySelector.cs | 213 ++ src/Core/ITriggeringEventEvaluator.cs | 51 + src/Core/Level.cs | 611 +++++ src/Core/LevelCollection.cs | 857 +++++++ src/Core/LevelEvaluator.cs | 133 ++ src/Core/LevelMap.cs | 229 ++ src/Core/LocationInfo.cs | 319 +++ src/Core/LogException.cs | 110 + src/Core/LogImpl.cs | 1296 +++++++++++ src/Core/LoggerManager.cs | 873 ++++++++ src/Core/LoggerWrapperImpl.cs | 86 + src/Core/LoggingEvent.cs | 1548 +++++++++++++ src/Core/MethodItem.cs | 171 ++ src/Core/SecurityContext.cs | 55 + src/Core/SecurityContextProvider.cs | 124 ++ src/Core/StackFrameItem.cs | 196 ++ src/Core/TimeEvaluator.cs | 148 ++ src/Core/WrapperMap.cs | 259 +++ .../AbsoluteTimeDateFormatter.cs | 213 ++ src/DateFormatter/DateTimeDateFormatter.cs | 106 + src/DateFormatter/IDateFormatter.cs | 55 + src/DateFormatter/Iso8601DateFormatter.cs | 96 + src/DateFormatter/SimpleDateFormatter.cs | 95 + src/Filter/DenyAllFilter.cs | 75 + src/Filter/FilterDecision.cs | 54 + src/Filter/FilterSkeleton.cs | 155 ++ src/Filter/IFilter.cs | 102 + src/Filter/LevelMatchFilter.cs | 142 ++ src/Filter/LevelRangeFilter.cs | 185 ++ src/Filter/LoggerMatchFilter.cs | 160 ++ src/Filter/MdcFilter.cs | 47 + src/Filter/NdcFilter.cs | 60 + src/Filter/PropertyFilter.cs | 165 ++ src/Filter/StringMatchFilter.cs | 241 ++ src/GlobalContext.cs | 102 + src/ILog.cs | 960 ++++++++ src/Layout/DynamicPatternLayout.cs | 143 ++ src/Layout/ExceptionLayout.cs | 108 + src/Layout/ILayout.cs | 121 + src/Layout/IRawLayout.cs | 61 + src/Layout/Layout2RawLayoutAdapter.cs | 93 + src/Layout/LayoutSkeleton.cs | 232 ++ .../Pattern/AppDomainPatternConverter.cs | 55 + .../Pattern/AspNetCachePatternConverter.cs | 77 + .../Pattern/AspNetContextPatternConverter.cs | 68 + src/Layout/Pattern/AspNetPatternConverter.cs | 65 + .../Pattern/AspNetRequestPatternConverter.cs | 86 + .../Pattern/AspNetSessionPatternConverter.cs | 77 + src/Layout/Pattern/DatePatternConverter.cs | 190 ++ .../Pattern/ExceptionPatternConverter.cs | 135 ++ .../Pattern/FileLocationPatternConverter.cs | 56 + .../Pattern/FullLocationPatternConverter.cs | 54 + .../Pattern/IdentityPatternConverter.cs | 58 + src/Layout/Pattern/LevelPatternConverter.cs | 56 + .../Pattern/LineLocationPatternConverter.cs | 56 + src/Layout/Pattern/LoggerPatternConverter.cs | 54 + src/Layout/Pattern/MessagePatternConverter.cs | 56 + .../Pattern/MethodLocationPatternConverter.cs | 56 + src/Layout/Pattern/NamedPatternConverter.cs | 171 ++ src/Layout/Pattern/NdcPatternConverter.cs | 62 + src/Layout/Pattern/PatternLayoutConverter.cs | 123 ++ .../Pattern/PropertyPatternConverter.cs | 77 + .../Pattern/RelativeTimePatternConverter.cs | 70 + .../StackTraceDetailPatternConverter.cs | 91 + .../Pattern/StackTracePatternConverter.cs | 150 ++ src/Layout/Pattern/ThreadPatternConverter.cs | 54 + .../Pattern/TypeNamePatternConverter.cs | 54 + .../Pattern/UserNamePatternConverter.cs | 45 + src/Layout/Pattern/UtcDatePatternConverter.cs | 91 + src/Layout/PatternLayout.cs | 1170 ++++++++++ src/Layout/RawLayoutConverter.cs | 88 + src/Layout/RawPropertyLayout.cs | 90 + src/Layout/RawTimeStampLayout.cs | 74 + src/Layout/RawUtcTimeStampLayout.cs | 74 + src/Layout/SimpleLayout.cs | 111 + src/Layout/XmlLayout.cs | 359 +++ src/Layout/XmlLayoutBase.cs | 248 +++ src/Layout/XmlLayoutSchemaLog4j.cs | 252 +++ src/Log4netAssemblyInfo.cs | 94 + src/LogManager.cs | 789 +++++++ src/LogicalThreadContext.cs | 151 ++ src/MDC.cs | 169 ++ src/NDC.cs | 311 +++ src/ObjectRenderer/DefaultRenderer.cs | 310 +++ src/ObjectRenderer/IObjectRenderer.cs | 61 + src/ObjectRenderer/RendererMap.cs | 326 +++ src/Plugin/IPlugin.cs | 85 + src/Plugin/IPluginFactory.cs | 45 + src/Plugin/PluginCollection.cs | 873 ++++++++ src/Plugin/PluginMap.cs | 189 ++ src/Plugin/PluginSkeleton.cs | 148 ++ src/Plugin/RemoteLoggingServerPlugin.cs | 279 +++ .../ConfigurationChangedEventArgs.cs | 51 + .../Hierarchy/DefaultLoggerFactory.cs | 114 + src/Repository/Hierarchy/Hierarchy.cs | 1077 +++++++++ src/Repository/Hierarchy/ILoggerFactory.cs | 64 + src/Repository/Hierarchy/Logger.cs | 789 +++++++ src/Repository/Hierarchy/LoggerKey.cs | 138 ++ src/Repository/Hierarchy/ProvisionNode.cs | 58 + src/Repository/Hierarchy/RootLogger.cs | 133 ++ .../Hierarchy/XmlHierarchyConfigurator.cs | 1124 ++++++++++ .../IBasicRepositoryConfigurator.cs | 63 + src/Repository/ILoggerRepository.cs | 349 +++ src/Repository/IXmlRepositoryConfigurator.cs | 54 + src/Repository/LoggerRepositorySkeleton.cs | 577 +++++ src/ThreadContext.cs | 139 ++ src/Util/AppenderAttachedImpl.cs | 376 ++++ src/Util/CompositeProperties.cs | 155 ++ src/Util/ContextPropertiesBase.cs | 50 + src/Util/ConverterInfo.cs | 94 + src/Util/CountingQuietTextWriter.cs | 180 ++ src/Util/CyclicBuffer.cs | 355 +++ src/Util/EmptyCollection.cs | 178 ++ src/Util/EmptyDictionary.cs | 339 +++ src/Util/FormattingInfo.cs | 136 ++ src/Util/GlobalContextProperties.cs | 177 ++ src/Util/ILogExtensions.cs | 1741 +++++++++++++++ src/Util/LevelMapping.cs | 150 ++ src/Util/LevelMappingEntry.cs | 100 + src/Util/LogLog.cs | 668 ++++++ src/Util/LogicalThreadContextProperties.cs | 264 +++ src/Util/LogicalThreadContextStack.cs | 415 ++++ src/Util/LogicalThreadContextStacks.cs | 133 ++ src/Util/NativeError.cs | 290 +++ src/Util/NullDictionaryEnumerator.cs | 202 ++ src/Util/NullEnumerator.cs | 134 ++ src/Util/NullSecurityContext.cs | 76 + src/Util/OnlyOnceErrorHandler.cs | 271 +++ src/Util/OptionConverter.cs | 659 ++++++ src/Util/PatternConverter.cs | 397 ++++ src/Util/PatternParser.cs | 435 ++++ src/Util/PatternString.cs | 501 +++++ .../AppDomainPatternConverter.cs | 54 + .../DatePatternConverter.cs | 190 ++ .../EnvironmentFolderPathPatternConverter.cs | 98 + .../EnvironmentPatternConverter.cs | 116 + .../IdentityPatternConverter.cs | 88 + .../LiteralPatternConverter.cs | 107 + .../NewLinePatternConverter.cs | 91 + .../ProcessIdPatternConverter.cs | 86 + .../PropertyPatternConverter.cs | 99 + .../RandomStringPatternConverter.cs | 156 ++ .../UserNamePatternConverter.cs | 88 + .../UtcDatePatternConverter.cs | 86 + src/Util/PropertiesDictionary.cs | 335 +++ src/Util/PropertyEntry.cs | 80 + src/Util/ProtectCloseTextWriter.cs | 93 + src/Util/QuietTextWriter.cs | 205 ++ src/Util/ReadOnlyPropertiesDictionary.cs | 381 ++++ src/Util/ReaderWriterLock.cs | 191 ++ src/Util/ReusableStringWriter.cs | 94 + src/Util/SystemInfo.cs | 1254 +++++++++++ src/Util/SystemStringFormat.cs | 237 ++ src/Util/TextWriterAdapter.cs | 234 ++ src/Util/ThreadContextProperties.cs | 200 ++ src/Util/ThreadContextStack.cs | 435 ++++ src/Util/ThreadContextStacks.cs | 124 ++ src/Util/Transform.cs | 200 ++ src/Util/TypeConverters/BooleanConverter.cs | 85 + .../ConversionNotSupportedException.cs | 154 ++ src/Util/TypeConverters/ConverterRegistry.cs | 293 +++ src/Util/TypeConverters/EncodingConverter.cs | 86 + src/Util/TypeConverters/IConvertFrom.cs | 63 + src/Util/TypeConverters/IConvertTo.cs | 63 + src/Util/TypeConverters/IPAddressConverter.cs | 144 ++ .../TypeConverters/PatternLayoutConverter.cs | 92 + .../TypeConverters/PatternStringConverter.cs | 140 ++ src/Util/TypeConverters/TypeConverter.cs | 87 + .../TypeConverters/TypeConverterAttribute.cs | 116 + src/Util/WindowsSecurityContext.cs | 387 ++++ src/assembly/bin.xml | 64 + src/changes/changes.xml | 28 + src/log4net.vs2008.csproj | 763 +++++++ src/log4net.vs2008.sln | 45 + src/log4net.vs2010.csproj | 802 +++++++ src/log4net.vs2010.sln | 45 + src/log4net.vs2012.csproj | 802 +++++++ src/log4net.vs2012.sln | 45 + src/site/apt/roadmap.apt | 27 + src/site/resources/css/maven-base.css | 168 ++ src/site/resources/css/site.css | 22 + src/site/resources/download_log4net.cgi | 22 + src/site/resources/images/logo.jpg | Bin 0 -> 8184 bytes .../resources/images/logos/maven-feather.png | Bin 0 -> 3330 bytes src/site/resources/images/ls-logo.jpg | Bin 0 -> 41915 bytes src/site/resources/images/od.gif | Bin 0 -> 5741 bytes src/site/site.vm | 542 +++++ src/site/site.xml | 80 + src/site/xdoc/download_log4net.xml | 151 ++ src/site/xdoc/history.xml | 58 + src/site/xdoc/index.xml | 48 + src/site/xdoc/release/building.xml | 139 ++ src/site/xdoc/release/config-examples.xml | 1109 ++++++++++ src/site/xdoc/release/example-apps.xml | 471 ++++ src/site/xdoc/release/faq.xml | 1248 +++++++++++ src/site/xdoc/release/features.xml | 310 +++ src/site/xdoc/release/framework-support.xml | 747 +++++++ src/site/xdoc/release/howto/chainsaw.xml | 115 + src/site/xdoc/release/howto/index.xml | 53 + .../xdoc/release/manual/configuration.xml | 1247 +++++++++++ src/site/xdoc/release/manual/contexts.xml | 245 ++ src/site/xdoc/release/manual/internals.xml | 259 +++ src/site/xdoc/release/manual/introduction.xml | 1041 +++++++++ src/site/xdoc/release/manual/plugins.xml | 101 + src/site/xdoc/release/manual/repositories.xml | 110 + src/site/xdoc/release/release-notes.xml | 1177 ++++++++++ tests/lib/prerequisites.txt | 37 + tests/nant.build | 847 +++++++ tests/src/Appender/AdoNet/Log4NetCommand.cs | 144 ++ .../src/Appender/AdoNet/Log4NetConnection.cs | 111 + tests/src/Appender/AdoNet/Log4NetParameter.cs | 103 + .../AdoNet/Log4NetParameterCollection.cs | 69 + .../src/Appender/AdoNet/Log4NetTransaction.cs | 62 + tests/src/Appender/AdoNetAppenderTest.cs | 213 ++ tests/src/Appender/AppenderCollectionTest.cs | 65 + tests/src/Appender/BufferingAppenderTest.cs | 112 + tests/src/Appender/CountingAppender.cs | 85 + tests/src/Appender/EventLogAppenderTest.cs | 100 + tests/src/Appender/MemoryAppenderTest.cs | 92 + tests/src/Appender/RemotingAppenderTest.cs | 426 ++++ tests/src/Appender/RollingFileAppenderTest.cs | 1961 +++++++++++++++++ tests/src/Appender/StringAppender.cs | 76 + tests/src/Appender/TraceAppenderTest.cs | 110 + tests/src/AssemblyInfo.cs | 32 + tests/src/Context/LogicalThreadContextTest.cs | 344 +++ tests/src/Context/ThreadContextTest.cs | 227 ++ tests/src/Core/EvaluatorTest.cs | 142 ++ tests/src/Core/FixingTest.cs | 151 ++ tests/src/Core/ShutdownTest.cs | 73 + tests/src/Core/StringFormatTest.cs | 709 ++++++ .../AbsoluteTimeDateFormatterTest.cs | 105 + tests/src/Filter/FilterTest.cs | 120 + tests/src/Hierarchy/Hierarchy.cs | 164 ++ tests/src/Hierarchy/Logger.cs | 307 +++ .../Hierarchy/XmlHierarchyConfiguratorTest.cs | 82 + tests/src/Layout/DynamicPatternLayoutTest.cs | 37 + tests/src/Layout/PatternLayoutTest.cs | 353 +++ tests/src/Layout/XmlLayoutTest.cs | 365 +++ .../LoggerRepository/ConfigurationMessages.cs | 101 + tests/src/Util/CyclicBufferTest.cs | 110 + .../Util/EnvironmentPatternConverterTest.cs | 117 + tests/src/Util/LogLogTest.cs | 109 + tests/src/Util/PatternConverterTest.cs | 192 ++ tests/src/Util/PatternStringTest.cs | 51 + tests/src/Util/PropertiesDictionaryTest.cs | 67 + .../Util/RandomStringPatternConverterTest.cs | 90 + tests/src/Util/SystemInfoTest.cs | 153 ++ tests/src/Util/TransformTest.cs | 45 + tests/src/Utils.cs | 111 + tests/src/log4net.Tests.vs2003.csproj | 293 +++ tests/src/log4net.Tests.vs2008.csproj | 218 ++ tests/src/log4net.Tests.vs2010.csproj | 251 +++ tests/src/log4net.Tests.vs2012.csproj | 251 +++ 698 files changed, 108716 insertions(+) create mode 100644 KEYS create mode 100644 LICENSE create mode 100644 NOTICE create mode 100644 README.txt create mode 100644 STATUS.txt create mode 100755 build.cmd create mode 100644 examples/mono/1.0/Performance/NotLogging/cs/nant.build create mode 100644 examples/mono/1.0/Performance/NotLogging/cs/nant.config create mode 100644 examples/mono/1.0/Performance/NotLogging/cs/src/AssemblyInfo.cs create mode 100644 examples/mono/1.0/Performance/NotLogging/cs/src/NotLogging.cs create mode 100644 examples/mono/1.0/Performance/NotLogging/nant.build create mode 100644 examples/mono/1.0/Performance/NotLogging/nant.config create mode 100644 examples/mono/1.0/Performance/nant.build create mode 100644 examples/mono/1.0/Performance/nant.config create mode 100644 examples/mono/1.0/Repository/SharedModule/cs/nant.build create mode 100644 examples/mono/1.0/Repository/SharedModule/cs/nant.config create mode 100644 examples/mono/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs create mode 100644 examples/mono/1.0/Repository/SharedModule/cs/src/Math.cs create mode 100644 examples/mono/1.0/Repository/SharedModule/nant.build create mode 100644 examples/mono/1.0/Repository/SharedModule/nant.config create mode 100644 examples/mono/1.0/Repository/SimpleApp/cs/nant.build create mode 100644 examples/mono/1.0/Repository/SimpleApp/cs/nant.config create mode 100644 examples/mono/1.0/Repository/SimpleApp/cs/src/App.config create mode 100644 examples/mono/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs create mode 100644 examples/mono/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs create mode 100644 examples/mono/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net create mode 100644 examples/mono/1.0/Repository/SimpleApp/nant.build create mode 100644 examples/mono/1.0/Repository/SimpleApp/nant.config create mode 100644 examples/mono/1.0/Repository/SimpleModule/cs/nant.build create mode 100644 examples/mono/1.0/Repository/SimpleModule/cs/nant.config create mode 100644 examples/mono/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs create mode 100644 examples/mono/1.0/Repository/SimpleModule/cs/src/Math.cs create mode 100644 examples/mono/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net create mode 100644 examples/mono/1.0/Repository/SimpleModule/nant.build create mode 100644 examples/mono/1.0/Repository/SimpleModule/nant.config create mode 100644 examples/mono/1.0/Repository/nant.build create mode 100644 examples/mono/1.0/Repository/nant.config create mode 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.build create mode 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.config create mode 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config create mode 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs create mode 100644 examples/mono/1.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs create mode 100644 examples/mono/1.0/Tutorials/ConsoleApp/nant.build create mode 100644 examples/mono/1.0/Tutorials/ConsoleApp/nant.config create mode 100644 examples/mono/1.0/Tutorials/nant.build create mode 100644 examples/mono/1.0/Tutorials/nant.config create mode 100644 examples/mono/1.0/nant.build create mode 100644 examples/mono/1.0/nant.config create mode 100644 examples/mono/nant.build create mode 100644 examples/mono/nant.config create mode 100644 examples/nant.build create mode 100644 examples/nant.config create mode 100644 examples/net/1.1/Repository/SharedModule/js/nant.build create mode 100644 examples/net/1.1/Repository/SharedModule/js/nant.config create mode 100644 examples/net/1.1/Repository/SharedModule/js/src/AssemblyInfo.js create mode 100644 examples/net/1.1/Repository/SharedModule/js/src/Math.js create mode 100644 examples/net/1.1/Repository/SharedModule/nant.build create mode 100644 examples/net/1.1/Repository/SharedModule/nant.config create mode 100644 examples/net/1.1/Repository/SimpleApp/js/nant.build create mode 100644 examples/net/1.1/Repository/SimpleApp/js/nant.config create mode 100644 examples/net/1.1/Repository/SimpleApp/js/src/App.config create mode 100644 examples/net/1.1/Repository/SimpleApp/js/src/AssemblyInfo.js create mode 100644 examples/net/1.1/Repository/SimpleApp/js/src/EntryPoint.js create mode 100644 examples/net/1.1/Repository/SimpleApp/js/src/SimpleApp.exe.log4net create mode 100644 examples/net/1.1/Repository/SimpleApp/nant.build create mode 100644 examples/net/1.1/Repository/SimpleApp/nant.config create mode 100644 examples/net/1.1/Repository/SimpleModule/js/nant.build create mode 100644 examples/net/1.1/Repository/SimpleModule/js/nant.config create mode 100644 examples/net/1.1/Repository/SimpleModule/js/src/AssemblyInfo.js create mode 100644 examples/net/1.1/Repository/SimpleModule/js/src/Math.js create mode 100644 examples/net/1.1/Repository/SimpleModule/js/src/SimpleModule.dll.log4net create mode 100644 examples/net/1.1/Repository/SimpleModule/nant.build create mode 100644 examples/net/1.1/Repository/SimpleModule/nant.config create mode 100644 examples/net/1.1/Repository/nant.build create mode 100644 examples/net/1.1/Repository/nant.config create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/nant.build create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/nant.config create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/src/App.config create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/src/AssemblyInfo.cpp create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/src/ConsoleApp.cpp create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/cpp/src/ConsoleApp.vcproj create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/js/nant.build create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/js/nant.config create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/js/src/App.config create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/js/src/AssemblyInfo.js create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/js/src/LoggingExample.js create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/nant.build create mode 100644 examples/net/1.1/Tutorials/ConsoleApp/nant.config create mode 100644 examples/net/1.1/Tutorials/nant.build create mode 100644 examples/net/1.1/Tutorials/nant.config create mode 100644 examples/net/1.1/cpp-examples.sln create mode 100644 examples/net/1.1/nant.build create mode 100644 examples/net/1.1/nant.config create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/nant.build create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/nant.config create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/App.config create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/AsyncAppender.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/FastDbAppender.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/FireEventAppender.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MessageBoxAppender.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MessageObjectExpanderAppender.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/MsmqAppender.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternFileAppender.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppender.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternLayoutAdoNetAppenderParameter.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/SimpleSmtpAppender.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/LoggingExample.cs create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/cs/src/SampleAppendersApp.csproj create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/nant.build create mode 100644 examples/net/2.0/Appenders/SampleAppendersApp/nant.config create mode 100644 examples/net/2.0/Appenders/WmiAppender/cs/nant.build create mode 100644 examples/net/2.0/Appenders/WmiAppender/cs/nant.config create mode 100644 examples/net/2.0/Appenders/WmiAppender/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Appenders/WmiAppender/cs/src/IWmiBoundEvent.cs create mode 100644 examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.cs create mode 100644 examples/net/2.0/Appenders/WmiAppender/cs/src/WmiAppender.csproj create mode 100644 examples/net/2.0/Appenders/WmiAppender/cs/src/WmiInstaller.cs create mode 100644 examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLayout.cs create mode 100644 examples/net/2.0/Appenders/WmiAppender/cs/src/WmiLoggingEvent.cs create mode 100644 examples/net/2.0/Appenders/WmiAppender/nant.build create mode 100644 examples/net/2.0/Appenders/WmiAppender/nant.config create mode 100644 examples/net/2.0/Appenders/nant.build create mode 100644 examples/net/2.0/Appenders/nant.config create mode 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/nant.build create mode 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/nant.config create mode 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/src/App.config create mode 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/src/EventIDLogApp.cs create mode 100644 examples/net/2.0/Extensibility/EventIDLogApp/cs/src/EventIDLogApp.csproj create mode 100644 examples/net/2.0/Extensibility/EventIDLogApp/nant.build create mode 100644 examples/net/2.0/Extensibility/EventIDLogApp/nant.config create mode 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/nant.build create mode 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/nant.config create mode 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.cs create mode 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.csproj create mode 100644 examples/net/2.0/Extensibility/TraceLogApp/cs/src/TraceLogApp.exe.log4net create mode 100644 examples/net/2.0/Extensibility/TraceLogApp/nant.build create mode 100644 examples/net/2.0/Extensibility/TraceLogApp/nant.config create mode 100644 examples/net/2.0/Extensibility/nant.build create mode 100644 examples/net/2.0/Extensibility/nant.config create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/nant.build create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/nant.config create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/App.config create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/ForwardingLayout.cs create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelConversionPattern.cs create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LevelPatternLayout.cs create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/Layout/LineWrappingLayout.cs create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/LoggingExample.cs create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/cs/src/SampleLayoutsApp.csproj create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/nant.build create mode 100644 examples/net/2.0/Layouts/SampleLayoutsApp/nant.config create mode 100644 examples/net/2.0/Layouts/nant.build create mode 100644 examples/net/2.0/Layouts/nant.config create mode 100644 examples/net/2.0/Performance/NotLogging/cs/nant.build create mode 100644 examples/net/2.0/Performance/NotLogging/cs/nant.config create mode 100644 examples/net/2.0/Performance/NotLogging/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.cs create mode 100644 examples/net/2.0/Performance/NotLogging/cs/src/NotLogging.csproj create mode 100644 examples/net/2.0/Performance/NotLogging/nant.build create mode 100644 examples/net/2.0/Performance/NotLogging/nant.config create mode 100644 examples/net/2.0/Performance/NotLogging/vb/nant.build create mode 100644 examples/net/2.0/Performance/NotLogging/vb/nant.config create mode 100644 examples/net/2.0/Performance/NotLogging/vb/src/AssemblyInfo.vb create mode 100644 examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vb create mode 100644 examples/net/2.0/Performance/NotLogging/vb/src/NotLogging.vbproj create mode 100644 examples/net/2.0/Performance/nant.build create mode 100644 examples/net/2.0/Performance/nant.config create mode 100644 examples/net/2.0/Remoting/RemotingClient/cs/nant.build create mode 100644 examples/net/2.0/Remoting/RemotingClient/cs/nant.config create mode 100644 examples/net/2.0/Remoting/RemotingClient/cs/src/App.config create mode 100644 examples/net/2.0/Remoting/RemotingClient/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Remoting/RemotingClient/cs/src/RemotingClient.cs create mode 100644 examples/net/2.0/Remoting/RemotingClient/cs/src/RemotingClient.csproj create mode 100644 examples/net/2.0/Remoting/RemotingClient/nant.build create mode 100644 examples/net/2.0/Remoting/RemotingClient/nant.config create mode 100644 examples/net/2.0/Remoting/RemotingServer/cs/nant.build create mode 100644 examples/net/2.0/Remoting/RemotingServer/cs/nant.config create mode 100644 examples/net/2.0/Remoting/RemotingServer/cs/src/App.config create mode 100644 examples/net/2.0/Remoting/RemotingServer/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.cs create mode 100644 examples/net/2.0/Remoting/RemotingServer/cs/src/RemotingServer.csproj create mode 100644 examples/net/2.0/Remoting/RemotingServer/nant.build create mode 100644 examples/net/2.0/Remoting/RemotingServer/nant.config create mode 100644 examples/net/2.0/Remoting/nant.build create mode 100644 examples/net/2.0/Remoting/nant.config create mode 100644 examples/net/2.0/Repository/SharedModule/cs/nant.build create mode 100644 examples/net/2.0/Repository/SharedModule/cs/nant.config create mode 100644 examples/net/2.0/Repository/SharedModule/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Repository/SharedModule/cs/src/Math.cs create mode 100644 examples/net/2.0/Repository/SharedModule/cs/src/SharedModule.csproj create mode 100644 examples/net/2.0/Repository/SharedModule/nant.build create mode 100644 examples/net/2.0/Repository/SharedModule/nant.config create mode 100644 examples/net/2.0/Repository/SharedModule/vb/nant.build create mode 100644 examples/net/2.0/Repository/SharedModule/vb/nant.config create mode 100644 examples/net/2.0/Repository/SharedModule/vb/src/AssemblyInfo.vb create mode 100644 examples/net/2.0/Repository/SharedModule/vb/src/Math.vb create mode 100644 examples/net/2.0/Repository/SharedModule/vb/src/SharedModule.vbproj create mode 100644 examples/net/2.0/Repository/SimpleApp/cs/nant.build create mode 100644 examples/net/2.0/Repository/SimpleApp/cs/nant.config create mode 100644 examples/net/2.0/Repository/SimpleApp/cs/src/App.config create mode 100644 examples/net/2.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Repository/SimpleApp/cs/src/EntryPoint.cs create mode 100644 examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.csproj create mode 100644 examples/net/2.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net create mode 100644 examples/net/2.0/Repository/SimpleApp/nant.build create mode 100644 examples/net/2.0/Repository/SimpleApp/nant.config create mode 100644 examples/net/2.0/Repository/SimpleApp/vb/nant.build create mode 100644 examples/net/2.0/Repository/SimpleApp/vb/nant.config create mode 100644 examples/net/2.0/Repository/SimpleApp/vb/src/App.config create mode 100644 examples/net/2.0/Repository/SimpleApp/vb/src/AssemblyInfo.vb create mode 100644 examples/net/2.0/Repository/SimpleApp/vb/src/EntryPoint.vb create mode 100644 examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.exe.log4net create mode 100644 examples/net/2.0/Repository/SimpleApp/vb/src/SimpleApp.vbproj create mode 100644 examples/net/2.0/Repository/SimpleModule/cs/nant.build create mode 100644 examples/net/2.0/Repository/SimpleModule/cs/nant.config create mode 100644 examples/net/2.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Repository/SimpleModule/cs/src/Math.cs create mode 100644 examples/net/2.0/Repository/SimpleModule/cs/src/SimpleModule.csproj create mode 100644 examples/net/2.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net create mode 100644 examples/net/2.0/Repository/SimpleModule/nant.build create mode 100644 examples/net/2.0/Repository/SimpleModule/nant.config create mode 100644 examples/net/2.0/Repository/SimpleModule/vb/nant.build create mode 100644 examples/net/2.0/Repository/SimpleModule/vb/nant.config create mode 100644 examples/net/2.0/Repository/SimpleModule/vb/src/AssemblyInfo.vb create mode 100644 examples/net/2.0/Repository/SimpleModule/vb/src/Math.vb create mode 100644 examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.dll.log4net create mode 100644 examples/net/2.0/Repository/SimpleModule/vb/src/SimpleModule.vbproj create mode 100644 examples/net/2.0/Repository/nant.build create mode 100644 examples/net/2.0/Repository/nant.config create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/nant.build create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/nant.config create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/src/App.config create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csproj create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/nant.build create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/nant.config create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/nant.build create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/nant.config create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/src/App.config create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/src/AssemblyInfo.vb create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.vbproj create mode 100644 examples/net/2.0/Tutorials/ConsoleApp/vb/src/LoggingExample.vb create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/nant.build create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/nant.config create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyInfo.cs create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/AssemblyVersionInfo.cs create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.cs create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/Global.asax.resx create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/SimpleModule.dll.log4net create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/Web.config create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.csproj.webinfo create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.dll.log4net create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebApp.vsdisco create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.cs create mode 100644 examples/net/2.0/Tutorials/WebApp/cs/src/WebForm1.aspx.resx create mode 100644 examples/net/2.0/Tutorials/WebApp/nant.build create mode 100644 examples/net/2.0/Tutorials/WebApp/nant.config create mode 100644 examples/net/2.0/Tutorials/WebApp/readme.txt create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/nant.build create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/nant.config create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyInfo.vb create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/AssemblyVersionInfo.vb create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.resx create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/Global.asax.vb create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/SimpleModule.dll.log4net create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/Web.config create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.dll.log4net create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vbproj.webinfo create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebApp.vsdisco create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.resx create mode 100644 examples/net/2.0/Tutorials/WebApp/vb/src/WebForm1.aspx.vb create mode 100644 examples/net/2.0/Tutorials/nant.build create mode 100644 examples/net/2.0/Tutorials/nant.config create mode 100644 examples/net/2.0/cs-examples.sln create mode 100644 examples/net/2.0/nant.build create mode 100644 examples/net/2.0/nant.config create mode 100644 examples/net/2.0/vb-examples.sln create mode 100644 examples/net/nant.build create mode 100644 examples/net/nant.config create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/nant.build create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/nant.config create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/AssemblyInfo.cs create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.csdproj create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/ConsoleApp.exe.config create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/EntryPoint.cs create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/cs/src/LoggingExample.cs create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/nant.build create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/nant.config create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/nant.build create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/nant.config create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/AssemblyInfo.vb create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.exe.config create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/ConsoleApp.vbdproj create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/EntryPoint.vb create mode 100644 examples/netcf/1.0/Tutorials/ConsoleApp/vb/src/LoggingExample.vb create mode 100644 examples/netcf/1.0/Tutorials/nant.build create mode 100644 examples/netcf/1.0/Tutorials/nant.config create mode 100644 examples/netcf/1.0/cs-examples.sln create mode 100644 examples/netcf/1.0/nant.build create mode 100644 examples/netcf/1.0/nant.config create mode 100644 examples/netcf/1.0/vb-examples.sln create mode 100644 examples/netcf/nant.build create mode 100644 examples/netcf/nant.config create mode 100644 examples/sscli/1.0/Repository/SharedModule/cs/nant.build create mode 100644 examples/sscli/1.0/Repository/SharedModule/cs/nant.config create mode 100644 examples/sscli/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs create mode 100644 examples/sscli/1.0/Repository/SharedModule/cs/src/Math.cs create mode 100644 examples/sscli/1.0/Repository/SharedModule/nant.build create mode 100644 examples/sscli/1.0/Repository/SharedModule/nant.config create mode 100644 examples/sscli/1.0/Repository/SimpleApp/cs/nant.build create mode 100644 examples/sscli/1.0/Repository/SimpleApp/cs/nant.config create mode 100644 examples/sscli/1.0/Repository/SimpleApp/cs/src/App.config create mode 100644 examples/sscli/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs create mode 100644 examples/sscli/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs create mode 100644 examples/sscli/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net create mode 100644 examples/sscli/1.0/Repository/SimpleApp/nant.build create mode 100644 examples/sscli/1.0/Repository/SimpleApp/nant.config create mode 100644 examples/sscli/1.0/Repository/SimpleModule/cs/nant.build create mode 100644 examples/sscli/1.0/Repository/SimpleModule/cs/nant.config create mode 100644 examples/sscli/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs create mode 100644 examples/sscli/1.0/Repository/SimpleModule/cs/src/Math.cs create mode 100644 examples/sscli/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net create mode 100644 examples/sscli/1.0/Repository/SimpleModule/nant.build create mode 100644 examples/sscli/1.0/Repository/SimpleModule/nant.config create mode 100644 examples/sscli/1.0/Repository/nant.build create mode 100644 examples/sscli/1.0/Repository/nant.config create mode 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/nant.build create mode 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/nant.config create mode 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/src/App.config create mode 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/src/AssemblyInfo.js create mode 100644 examples/sscli/1.0/Tutorials/ConsoleApp/js/src/LoggingExample.js create mode 100644 examples/sscli/1.0/Tutorials/ConsoleApp/nant.build create mode 100644 examples/sscli/1.0/Tutorials/ConsoleApp/nant.config create mode 100644 examples/sscli/1.0/Tutorials/nant.build create mode 100644 examples/sscli/1.0/Tutorials/nant.config create mode 100644 examples/sscli/1.0/nant.build create mode 100644 examples/sscli/1.0/nant.config create mode 100644 examples/sscli/nant.build create mode 100644 examples/sscli/nant.config create mode 100644 extensions/nant.build create mode 100644 extensions/nant.config create mode 100644 extensions/net/1.0/cs-extensions.sln create mode 100644 extensions/net/1.0/log4net.Ext.EventID/cs/nant.build create mode 100644 extensions/net/1.0/log4net.Ext.EventID/cs/nant.config create mode 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/AssemblyInfo.cs create mode 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/EventIDLogImpl.cs create mode 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/EventIDLogManager.cs create mode 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/IEventIDLog.cs create mode 100644 extensions/net/1.0/log4net.Ext.EventID/cs/src/log4net.Ext.EventID.csproj create mode 100644 extensions/net/1.0/log4net.Ext.EventID/nant.build create mode 100644 extensions/net/1.0/log4net.Ext.EventID/nant.config create mode 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/nant.build create mode 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/nant.config create mode 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/AssemblyInfo.cs create mode 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/MarshalByRefLogImpl.cs create mode 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/MarshalByRefLogManager.cs create mode 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/cs/src/log4net.Ext.MarshalByRef.csproj create mode 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/nant.build create mode 100644 extensions/net/1.0/log4net.Ext.MarshalByRef/nant.config create mode 100644 extensions/net/1.0/log4net.Ext.Trace/cs/nant.build create mode 100644 extensions/net/1.0/log4net.Ext.Trace/cs/nant.config create mode 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/AssemblyInfo.cs create mode 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/ITraceLog.cs create mode 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs create mode 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogManager.cs create mode 100644 extensions/net/1.0/log4net.Ext.Trace/cs/src/log4net.Ext.Trace.csproj create mode 100644 extensions/net/1.0/log4net.Ext.Trace/nant.build create mode 100644 extensions/net/1.0/log4net.Ext.Trace/nant.config create mode 100644 extensions/net/1.0/nant.build create mode 100644 extensions/net/1.0/nant.config create mode 100644 extensions/net/nant.build create mode 100644 extensions/net/nant.config create mode 100644 log4net.build create mode 100644 log4net.include create mode 100644 log4net.snk create mode 100644 log4net.snk.readme create mode 100644 old-log4net.snk.gpg create mode 100644 pom.xml create mode 100644 src/Appender/AdoNetAppender.cs create mode 100644 src/Appender/AnsiColorTerminalAppender.cs create mode 100644 src/Appender/AppenderCollection.cs create mode 100644 src/Appender/AppenderSkeleton.cs create mode 100644 src/Appender/AspNetTraceAppender.cs create mode 100644 src/Appender/BufferingAppenderSkeleton.cs create mode 100644 src/Appender/BufferingForwardingAppender.cs create mode 100644 src/Appender/ColoredConsoleAppender.cs create mode 100644 src/Appender/ConsoleAppender.cs create mode 100644 src/Appender/DebugAppender.cs create mode 100644 src/Appender/EventLogAppender.cs create mode 100644 src/Appender/FileAppender.cs create mode 100644 src/Appender/ForwardingAppender.cs create mode 100644 src/Appender/IAppender.cs create mode 100644 src/Appender/IBulkAppender.cs create mode 100644 src/Appender/LocalSyslogAppender.cs create mode 100644 src/Appender/ManagedColoredConsoleAppender.cs create mode 100644 src/Appender/MemoryAppender.cs create mode 100644 src/Appender/NetSendAppender.cs create mode 100644 src/Appender/OutputDebugStringAppender.cs create mode 100644 src/Appender/RemoteSyslogAppender.cs create mode 100644 src/Appender/RemotingAppender.cs create mode 100644 src/Appender/RollingFileAppender.cs create mode 100644 src/Appender/SmtpAppender.cs create mode 100644 src/Appender/SmtpPickupDirAppender.cs create mode 100644 src/Appender/TelnetAppender.cs create mode 100644 src/Appender/TextWriterAppender.cs create mode 100644 src/Appender/TraceAppender.cs create mode 100644 src/Appender/UdpAppender.cs create mode 100644 src/AssemblyInfo.cs create mode 100644 src/AssemblyVersionInfo.cpp create mode 100644 src/AssemblyVersionInfo.cs create mode 100644 src/AssemblyVersionInfo.js create mode 100644 src/AssemblyVersionInfo.vb create mode 100644 src/Config/AliasDomainAttribute.cs create mode 100644 src/Config/AliasRepositoryAttribute.cs create mode 100644 src/Config/BasicConfigurator.cs create mode 100644 src/Config/ConfiguratorAttribute.cs create mode 100644 src/Config/DOMConfigurator.cs create mode 100644 src/Config/DOMConfiguratorAttribute.cs create mode 100644 src/Config/DomainAttribute.cs create mode 100644 src/Config/Log4NetConfigurationSectionHandler.cs create mode 100644 src/Config/PluginAttribute.cs create mode 100644 src/Config/RepositoryAttribute.cs create mode 100644 src/Config/SecurityContextProviderAttribute.cs create mode 100644 src/Config/XmlConfigurator.cs create mode 100644 src/Config/XmlConfiguratorAttribute.cs create mode 100644 src/Core/CompactRepositorySelector.cs create mode 100644 src/Core/DefaultRepositorySelector.cs create mode 100644 src/Core/ErrorCode.cs create mode 100644 src/Core/ExceptionEvaluator.cs create mode 100644 src/Core/IAppenderAttachable.cs create mode 100644 src/Core/IErrorHandler.cs create mode 100644 src/Core/IFixingRequired.cs create mode 100644 src/Core/ILogger.cs create mode 100644 src/Core/ILoggerWrapper.cs create mode 100644 src/Core/IOptionHandler.cs create mode 100644 src/Core/IRepositorySelector.cs create mode 100644 src/Core/ITriggeringEventEvaluator.cs create mode 100644 src/Core/Level.cs create mode 100644 src/Core/LevelCollection.cs create mode 100644 src/Core/LevelEvaluator.cs create mode 100644 src/Core/LevelMap.cs create mode 100644 src/Core/LocationInfo.cs create mode 100644 src/Core/LogException.cs create mode 100644 src/Core/LogImpl.cs create mode 100644 src/Core/LoggerManager.cs create mode 100644 src/Core/LoggerWrapperImpl.cs create mode 100644 src/Core/LoggingEvent.cs create mode 100644 src/Core/MethodItem.cs create mode 100644 src/Core/SecurityContext.cs create mode 100644 src/Core/SecurityContextProvider.cs create mode 100644 src/Core/StackFrameItem.cs create mode 100644 src/Core/TimeEvaluator.cs create mode 100644 src/Core/WrapperMap.cs create mode 100644 src/DateFormatter/AbsoluteTimeDateFormatter.cs create mode 100644 src/DateFormatter/DateTimeDateFormatter.cs create mode 100644 src/DateFormatter/IDateFormatter.cs create mode 100644 src/DateFormatter/Iso8601DateFormatter.cs create mode 100644 src/DateFormatter/SimpleDateFormatter.cs create mode 100644 src/Filter/DenyAllFilter.cs create mode 100644 src/Filter/FilterDecision.cs create mode 100644 src/Filter/FilterSkeleton.cs create mode 100644 src/Filter/IFilter.cs create mode 100644 src/Filter/LevelMatchFilter.cs create mode 100644 src/Filter/LevelRangeFilter.cs create mode 100644 src/Filter/LoggerMatchFilter.cs create mode 100644 src/Filter/MdcFilter.cs create mode 100644 src/Filter/NdcFilter.cs create mode 100644 src/Filter/PropertyFilter.cs create mode 100644 src/Filter/StringMatchFilter.cs create mode 100644 src/GlobalContext.cs create mode 100644 src/ILog.cs create mode 100644 src/Layout/DynamicPatternLayout.cs create mode 100644 src/Layout/ExceptionLayout.cs create mode 100644 src/Layout/ILayout.cs create mode 100644 src/Layout/IRawLayout.cs create mode 100644 src/Layout/Layout2RawLayoutAdapter.cs create mode 100644 src/Layout/LayoutSkeleton.cs create mode 100644 src/Layout/Pattern/AppDomainPatternConverter.cs create mode 100644 src/Layout/Pattern/AspNetCachePatternConverter.cs create mode 100644 src/Layout/Pattern/AspNetContextPatternConverter.cs create mode 100644 src/Layout/Pattern/AspNetPatternConverter.cs create mode 100644 src/Layout/Pattern/AspNetRequestPatternConverter.cs create mode 100644 src/Layout/Pattern/AspNetSessionPatternConverter.cs create mode 100644 src/Layout/Pattern/DatePatternConverter.cs create mode 100644 src/Layout/Pattern/ExceptionPatternConverter.cs create mode 100644 src/Layout/Pattern/FileLocationPatternConverter.cs create mode 100644 src/Layout/Pattern/FullLocationPatternConverter.cs create mode 100644 src/Layout/Pattern/IdentityPatternConverter.cs create mode 100644 src/Layout/Pattern/LevelPatternConverter.cs create mode 100644 src/Layout/Pattern/LineLocationPatternConverter.cs create mode 100644 src/Layout/Pattern/LoggerPatternConverter.cs create mode 100644 src/Layout/Pattern/MessagePatternConverter.cs create mode 100644 src/Layout/Pattern/MethodLocationPatternConverter.cs create mode 100644 src/Layout/Pattern/NamedPatternConverter.cs create mode 100644 src/Layout/Pattern/NdcPatternConverter.cs create mode 100644 src/Layout/Pattern/PatternLayoutConverter.cs create mode 100644 src/Layout/Pattern/PropertyPatternConverter.cs create mode 100644 src/Layout/Pattern/RelativeTimePatternConverter.cs create mode 100644 src/Layout/Pattern/StackTraceDetailPatternConverter.cs create mode 100644 src/Layout/Pattern/StackTracePatternConverter.cs create mode 100644 src/Layout/Pattern/ThreadPatternConverter.cs create mode 100644 src/Layout/Pattern/TypeNamePatternConverter.cs create mode 100644 src/Layout/Pattern/UserNamePatternConverter.cs create mode 100644 src/Layout/Pattern/UtcDatePatternConverter.cs create mode 100644 src/Layout/PatternLayout.cs create mode 100644 src/Layout/RawLayoutConverter.cs create mode 100644 src/Layout/RawPropertyLayout.cs create mode 100644 src/Layout/RawTimeStampLayout.cs create mode 100644 src/Layout/RawUtcTimeStampLayout.cs create mode 100644 src/Layout/SimpleLayout.cs create mode 100644 src/Layout/XmlLayout.cs create mode 100644 src/Layout/XmlLayoutBase.cs create mode 100644 src/Layout/XmlLayoutSchemaLog4j.cs create mode 100644 src/Log4netAssemblyInfo.cs create mode 100644 src/LogManager.cs create mode 100644 src/LogicalThreadContext.cs create mode 100644 src/MDC.cs create mode 100644 src/NDC.cs create mode 100644 src/ObjectRenderer/DefaultRenderer.cs create mode 100644 src/ObjectRenderer/IObjectRenderer.cs create mode 100644 src/ObjectRenderer/RendererMap.cs create mode 100644 src/Plugin/IPlugin.cs create mode 100644 src/Plugin/IPluginFactory.cs create mode 100644 src/Plugin/PluginCollection.cs create mode 100644 src/Plugin/PluginMap.cs create mode 100644 src/Plugin/PluginSkeleton.cs create mode 100644 src/Plugin/RemoteLoggingServerPlugin.cs create mode 100644 src/Repository/ConfigurationChangedEventArgs.cs create mode 100644 src/Repository/Hierarchy/DefaultLoggerFactory.cs create mode 100644 src/Repository/Hierarchy/Hierarchy.cs create mode 100644 src/Repository/Hierarchy/ILoggerFactory.cs create mode 100644 src/Repository/Hierarchy/Logger.cs create mode 100644 src/Repository/Hierarchy/LoggerKey.cs create mode 100644 src/Repository/Hierarchy/ProvisionNode.cs create mode 100644 src/Repository/Hierarchy/RootLogger.cs create mode 100644 src/Repository/Hierarchy/XmlHierarchyConfigurator.cs create mode 100644 src/Repository/IBasicRepositoryConfigurator.cs create mode 100644 src/Repository/ILoggerRepository.cs create mode 100644 src/Repository/IXmlRepositoryConfigurator.cs create mode 100644 src/Repository/LoggerRepositorySkeleton.cs create mode 100644 src/ThreadContext.cs create mode 100644 src/Util/AppenderAttachedImpl.cs create mode 100644 src/Util/CompositeProperties.cs create mode 100644 src/Util/ContextPropertiesBase.cs create mode 100644 src/Util/ConverterInfo.cs create mode 100644 src/Util/CountingQuietTextWriter.cs create mode 100644 src/Util/CyclicBuffer.cs create mode 100644 src/Util/EmptyCollection.cs create mode 100644 src/Util/EmptyDictionary.cs create mode 100644 src/Util/FormattingInfo.cs create mode 100644 src/Util/GlobalContextProperties.cs create mode 100644 src/Util/ILogExtensions.cs create mode 100644 src/Util/LevelMapping.cs create mode 100644 src/Util/LevelMappingEntry.cs create mode 100644 src/Util/LogLog.cs create mode 100644 src/Util/LogicalThreadContextProperties.cs create mode 100644 src/Util/LogicalThreadContextStack.cs create mode 100644 src/Util/LogicalThreadContextStacks.cs create mode 100644 src/Util/NativeError.cs create mode 100644 src/Util/NullDictionaryEnumerator.cs create mode 100644 src/Util/NullEnumerator.cs create mode 100644 src/Util/NullSecurityContext.cs create mode 100644 src/Util/OnlyOnceErrorHandler.cs create mode 100644 src/Util/OptionConverter.cs create mode 100644 src/Util/PatternConverter.cs create mode 100644 src/Util/PatternParser.cs create mode 100644 src/Util/PatternString.cs create mode 100644 src/Util/PatternStringConverters/AppDomainPatternConverter.cs create mode 100644 src/Util/PatternStringConverters/DatePatternConverter.cs create mode 100644 src/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs create mode 100644 src/Util/PatternStringConverters/EnvironmentPatternConverter.cs create mode 100644 src/Util/PatternStringConverters/IdentityPatternConverter.cs create mode 100644 src/Util/PatternStringConverters/LiteralPatternConverter.cs create mode 100644 src/Util/PatternStringConverters/NewLinePatternConverter.cs create mode 100644 src/Util/PatternStringConverters/ProcessIdPatternConverter.cs create mode 100644 src/Util/PatternStringConverters/PropertyPatternConverter.cs create mode 100644 src/Util/PatternStringConverters/RandomStringPatternConverter.cs create mode 100644 src/Util/PatternStringConverters/UserNamePatternConverter.cs create mode 100644 src/Util/PatternStringConverters/UtcDatePatternConverter.cs create mode 100644 src/Util/PropertiesDictionary.cs create mode 100644 src/Util/PropertyEntry.cs create mode 100644 src/Util/ProtectCloseTextWriter.cs create mode 100644 src/Util/QuietTextWriter.cs create mode 100644 src/Util/ReadOnlyPropertiesDictionary.cs create mode 100644 src/Util/ReaderWriterLock.cs create mode 100644 src/Util/ReusableStringWriter.cs create mode 100644 src/Util/SystemInfo.cs create mode 100644 src/Util/SystemStringFormat.cs create mode 100644 src/Util/TextWriterAdapter.cs create mode 100644 src/Util/ThreadContextProperties.cs create mode 100644 src/Util/ThreadContextStack.cs create mode 100644 src/Util/ThreadContextStacks.cs create mode 100644 src/Util/Transform.cs create mode 100644 src/Util/TypeConverters/BooleanConverter.cs create mode 100644 src/Util/TypeConverters/ConversionNotSupportedException.cs create mode 100644 src/Util/TypeConverters/ConverterRegistry.cs create mode 100644 src/Util/TypeConverters/EncodingConverter.cs create mode 100644 src/Util/TypeConverters/IConvertFrom.cs create mode 100644 src/Util/TypeConverters/IConvertTo.cs create mode 100644 src/Util/TypeConverters/IPAddressConverter.cs create mode 100644 src/Util/TypeConverters/PatternLayoutConverter.cs create mode 100644 src/Util/TypeConverters/PatternStringConverter.cs create mode 100644 src/Util/TypeConverters/TypeConverter.cs create mode 100644 src/Util/TypeConverters/TypeConverterAttribute.cs create mode 100644 src/Util/WindowsSecurityContext.cs create mode 100644 src/assembly/bin.xml create mode 100644 src/changes/changes.xml create mode 100644 src/log4net.vs2008.csproj create mode 100644 src/log4net.vs2008.sln create mode 100644 src/log4net.vs2010.csproj create mode 100644 src/log4net.vs2010.sln create mode 100644 src/log4net.vs2012.csproj create mode 100644 src/log4net.vs2012.sln create mode 100644 src/site/apt/roadmap.apt create mode 100644 src/site/resources/css/maven-base.css create mode 100644 src/site/resources/css/site.css create mode 100755 src/site/resources/download_log4net.cgi create mode 100644 src/site/resources/images/logo.jpg create mode 100644 src/site/resources/images/logos/maven-feather.png create mode 100644 src/site/resources/images/ls-logo.jpg create mode 100644 src/site/resources/images/od.gif create mode 100644 src/site/site.vm create mode 100644 src/site/site.xml create mode 100644 src/site/xdoc/download_log4net.xml create mode 100644 src/site/xdoc/history.xml create mode 100644 src/site/xdoc/index.xml create mode 100644 src/site/xdoc/release/building.xml create mode 100644 src/site/xdoc/release/config-examples.xml create mode 100644 src/site/xdoc/release/example-apps.xml create mode 100644 src/site/xdoc/release/faq.xml create mode 100644 src/site/xdoc/release/features.xml create mode 100644 src/site/xdoc/release/framework-support.xml create mode 100644 src/site/xdoc/release/howto/chainsaw.xml create mode 100644 src/site/xdoc/release/howto/index.xml create mode 100644 src/site/xdoc/release/manual/configuration.xml create mode 100644 src/site/xdoc/release/manual/contexts.xml create mode 100644 src/site/xdoc/release/manual/internals.xml create mode 100644 src/site/xdoc/release/manual/introduction.xml create mode 100644 src/site/xdoc/release/manual/plugins.xml create mode 100644 src/site/xdoc/release/manual/repositories.xml create mode 100644 src/site/xdoc/release/release-notes.xml create mode 100644 tests/lib/prerequisites.txt create mode 100644 tests/nant.build create mode 100644 tests/src/Appender/AdoNet/Log4NetCommand.cs create mode 100644 tests/src/Appender/AdoNet/Log4NetConnection.cs create mode 100644 tests/src/Appender/AdoNet/Log4NetParameter.cs create mode 100644 tests/src/Appender/AdoNet/Log4NetParameterCollection.cs create mode 100644 tests/src/Appender/AdoNet/Log4NetTransaction.cs create mode 100644 tests/src/Appender/AdoNetAppenderTest.cs create mode 100644 tests/src/Appender/AppenderCollectionTest.cs create mode 100644 tests/src/Appender/BufferingAppenderTest.cs create mode 100644 tests/src/Appender/CountingAppender.cs create mode 100644 tests/src/Appender/EventLogAppenderTest.cs create mode 100644 tests/src/Appender/MemoryAppenderTest.cs create mode 100644 tests/src/Appender/RemotingAppenderTest.cs create mode 100644 tests/src/Appender/RollingFileAppenderTest.cs create mode 100644 tests/src/Appender/StringAppender.cs create mode 100644 tests/src/Appender/TraceAppenderTest.cs create mode 100644 tests/src/AssemblyInfo.cs create mode 100644 tests/src/Context/LogicalThreadContextTest.cs create mode 100644 tests/src/Context/ThreadContextTest.cs create mode 100644 tests/src/Core/EvaluatorTest.cs create mode 100644 tests/src/Core/FixingTest.cs create mode 100644 tests/src/Core/ShutdownTest.cs create mode 100644 tests/src/Core/StringFormatTest.cs create mode 100644 tests/src/DateFormatter/AbsoluteTimeDateFormatterTest.cs create mode 100644 tests/src/Filter/FilterTest.cs create mode 100644 tests/src/Hierarchy/Hierarchy.cs create mode 100644 tests/src/Hierarchy/Logger.cs create mode 100644 tests/src/Hierarchy/XmlHierarchyConfiguratorTest.cs create mode 100644 tests/src/Layout/DynamicPatternLayoutTest.cs create mode 100644 tests/src/Layout/PatternLayoutTest.cs create mode 100644 tests/src/Layout/XmlLayoutTest.cs create mode 100644 tests/src/LoggerRepository/ConfigurationMessages.cs create mode 100644 tests/src/Util/CyclicBufferTest.cs create mode 100644 tests/src/Util/EnvironmentPatternConverterTest.cs create mode 100644 tests/src/Util/LogLogTest.cs create mode 100644 tests/src/Util/PatternConverterTest.cs create mode 100644 tests/src/Util/PatternStringTest.cs create mode 100644 tests/src/Util/PropertiesDictionaryTest.cs create mode 100644 tests/src/Util/RandomStringPatternConverterTest.cs create mode 100644 tests/src/Util/SystemInfoTest.cs create mode 100644 tests/src/Util/TransformTest.cs create mode 100644 tests/src/Utils.cs create mode 100644 tests/src/log4net.Tests.vs2003.csproj create mode 100644 tests/src/log4net.Tests.vs2008.csproj create mode 100644 tests/src/log4net.Tests.vs2010.csproj create mode 100644 tests/src/log4net.Tests.vs2012.csproj diff --git a/KEYS b/KEYS new file mode 100644 index 00000000..d8de1236 --- /dev/null +++ b/KEYS @@ -0,0 +1,602 @@ +This file contains the PGP keys of various Apache developers. +These keys are primarily used for code signing. + +These keys can be verified using any OpenPGP compatible system, +for example, http://www.gnupg.org. + +Developers: To add key information use: + gpg --list-keys UID + gpg --export -a UID + +(Where UID is your email address) + +The original source of this file is +https://svn.apache.org/repos/asf/logging/log4net/trunk/KEYS + +User: To import this key file into your keyring use: + gpg --import KEYS + + + + + +pub 1024D/914A4D28 2005-03-07 +uid Nicko Cadell +sub 2048g/6923CBDA 2005-03-07 + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.0 (MingW32) + +mQGiBEIsjHURBAC9JqRzMEh6pEZuuyqHGwfBkQZnvOuj0Yp88lDsJtNl62cRaQJk +7eP+kVxCbl12qr1EDz1z/ZON7/+vF9YoiRh7Cydck6wLe/kQcJtUevm00q35pUQJ +7c2TSY+QbTKWriUKueOyRR6p2lpscUHhbCPB9NOLfQmJvZsa47gDZSybCwCgh0+u +8KkkcovlV55K/WrSGg16o8kEAKFGmpDKDnv0Sg1rRnvBGJv5WZFR/57p1SArMXHi +oBkj71wlWz9Ia4tonfc12TXUwoVs3WbIFOoLz1Iw31cGnwUsNkvEclaZigG9iYhx +S6+2i7jrQIivO5iXJtTuePb4zFgLwZcaoFySvLIKRm8+X6KXvoslKAYM/F/Yd0jm +OebkA/4uwIt7cGOWGIaiH2n/80QgXN6FyOhNsgCihZZcPwXo7c/gtszpJ74CwtXD +SVghIwTQ0zK4wtWcHSjf7FelPmeDSga7dLgnxQmmhjIK+sBnPIcBrNiUc3jFnRzK +o3ZIBPsGoo0jUsemgkiQA4ptVybeak/SmrTsRgxWkT4Paw41zrQfTmlja28gQ2Fk +ZWxsIDxuaWNrb0BhcGFjaGUub3JnPoheBBMRAgAeBQJCLIx1AhsDBgsJCAcDAgMV +AgMDFgIBAh4BAheAAAoJEA3R7CqRSk0ooTIAnRZ+vUY+ZN8CgL0fvDbZv76kgQG+ +AJ9vp4BwPLU5jM+YOY3hJPp1bNw1RLkCDQRCLIx/EAgArSrXU4kkXNLCTBIAMaIx +diiVvQ2JqzrFkXf4yAlE+xiy19bqGewmslt+dLmLUEtt1UFMU5b2kAiZLNMvdBWQ +OStwK0SABRESjb5sAjAcFXUeqBzjVBDvsSGxJZZa5He1pQMjFzm4hG6GNl3+vOx6 +r6fly9W5Ddc8wqfDb8JU0c6gG8s10D4gthWWyJ2K1u3BcvpggoGyqyxisvF/QM68 +KnXf8/wp+5sOfl6glyluR/OyGMCU3c38eHYU2XMzlcT3fh1VcU5MvPastp+76vUy +ImrAfb7RhS3sDrmRd9ZS8FE5JRB3967hETRSLjHW+/TZeyvxaGMJkBPdv2BdwnD8 +6wADBQf+NaK8teolegPc1LdmX3bAhR2bhfqIpuUwPBRHqIU2OtWsMJ9sEsVZY4LC +OLOHMHI1spWHEo39mx3fz5MR4x2z3+HzZRq8tzMFn5PC3c7yb06CMfqRf8pvYWVP +0cMvEctViAc+xwSpZgXQGLkwZ37KtqWncfBVocxQMj4CVUx3PeyozWGEG+bpGSso +Mrvnch41AGL3NA9bA2cgTVuOYSXZLK9TOgh4gXCM4jWTI4BqTY5w0riDwqwt5+qH +e8/HBowGa4jNopl9kWaQuEoXH7GGOTJsc9eKMK+k++iqSWiqVXFTLd7/UhUPv6Oj +7Pqm7+oSumphn00rC2DVeAAWDt7umohJBBgRAgAJBQJCLIx/AhsMAAoJEA3R7CqR +Sk0ouF4An1sFuJ+/kJlvKRs+nNjFqrQdsuDCAJ9WDNgUqnAkdLVTRJq8UeK0AjOq +oQ== +=4aNz +-----END PGP PUBLIC KEY BLOCK----- + +pub 1024D/5F6B8B72 2001-05-28 +uid Stefan Bodewig +sig 3 5F6B8B72 2001-05-28 Stefan Bodewig +sig 51898504 2002-01-11 Conor MacNeill +sig 3 F88341D9 2003-03-17 Lars Eilebrecht +sig 3 2261D073 2003-03-17 Astrid Kessler (Kess) +sig 21D0A71B 2003-03-17 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 75A67692 2003-03-18 Erik Abele +sig B3B2A12C 2003-05-20 ct magazine CERTIFICATE +sig 3 8103A37E 2003-04-04 Andre Malo +sig 3 5F6B8B72 2001-05-28 Stefan Bodewig +sig D6298F01 2003-04-27 Paulo Henrique Gaspar Jorge +sig 0CAA68B4 2004-11-11 Patrick Rentsch +sig 2FE28BCF 2005-07-01 Harald Wilhelm (HAWI) +sig 5793498F 2005-07-21 Tim Ellison +sig E4136392 2005-07-21 Noel J. Bergman +sig 8408F755 2005-07-21 Christian Geisert +sig 2 FC243F3C 2005-07-20 Henk P. Penning +sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 3 EE65E321 2005-07-20 Martin Kraemer +sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size +sig 3 3642CB4B 2005-07-20 Martin Kraemer +sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) +sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size +sig 3 CC78C893 2005-07-22 Rich Bowen +sig 3 E2D774DF 2005-07-22 Sylvain Wallez +sig 3 E04F9A89 2005-07-22 Roy T. Fielding +sig 3 015AFC8A 2005-07-22 Bertrand Delacretaz +sig 3 87315C31 2005-07-23 Raphal Luta +sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler +sig 3 F39B3750 2005-07-24 Colm MacCarthaigh +sig 1CD4861F 2005-07-25 Eran Chinthaka +sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) +sig 333E4E84 2005-07-26 Chathura Kamalanath Herath (Apachecon Europe 2005) +sig 152924AF 2005-07-29 Sander Temme +sig 3 9C85222B 2005-07-24 Henning Schmiedehausen +sig 3 9978AF86 2005-07-25 [User ID not found] +sig 3 2A623F72 2005-07-25 [User ID not found] +sig 3 F8EA2967 2005-07-26 [User ID not found] +sig 3 C152431A 2005-07-27 Steve Loughran +sig DE885DD3 2005-11-25 Sander Striker +sig CE419C8F 2007-01-05 Upayavira +sig E222DE4F 2007-05-02 Mathias Herberts +sig 911203E4 2007-05-02 [User ID not found] +sig F12F6072 2007-05-05 [User ID not found] +sig 3 990ED4AA 2007-05-02 Knut Anders Hatlen +sig 3 311A3DE5 2007-05-05 Ruediger Pluem +sig 3 88817402 2007-05-06 Thomas Vandahl +sig 5F298824 2007-05-06 Simon Pepping +sig 4CEED75F 2007-05-06 Nick Burch +sig 4358C584 2007-05-06 Vincent Hennebert +sig 0B7E6CFA 2007-05-06 Sami Siren +sig 3 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) +sig 40581837 2007-05-08 Nick Kew +uid Stefan Bodewig +sig 3 5F6B8B72 2003-03-07 Stefan Bodewig +sig 3 F88341D9 2003-03-17 Lars Eilebrecht +sig 3 2261D073 2003-03-17 Astrid Kessler (Kess) +sig 21D0A71B 2003-03-17 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 75A67692 2003-03-18 Erik Abele +sig B3B2A12C 2003-05-20 ct magazine CERTIFICATE +sig 3 8103A37E 2003-04-04 Andre Malo +sig 51898504 2005-06-21 Conor MacNeill +sig 0CAA68B4 2004-11-11 Patrick Rentsch +sig 2FE28BCF 2005-07-01 Harald Wilhelm (HAWI) +sig 5793498F 2005-07-21 Tim Ellison +sig 8408F755 2005-07-21 Christian Geisert +sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 3 EE65E321 2005-07-20 Martin Kraemer +sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size +sig 3 3642CB4B 2005-07-20 Martin Kraemer +sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) +sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size +sig 3 CC78C893 2005-07-22 Rich Bowen +sig 3 E2D774DF 2005-07-22 Sylvain Wallez +sig 3 E04F9A89 2005-07-22 Roy T. Fielding +sig 3 87315C31 2005-07-23 Raphal Luta +sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler +sig 3 F39B3750 2005-07-24 Colm MacCarthaigh +sig 1CD4861F 2005-07-25 Eran Chinthaka +sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) +sig 333E4E84 2005-07-26 Chathura Kamalanath Herath (Apachecon Europe 2005) +sig 152924AF 2005-07-29 Sander Temme +sig 3 9C85222B 2005-07-24 Henning Schmiedehausen +sig 3 9978AF86 2005-07-25 [User ID not found] +sig 3 2A623F72 2005-07-25 [User ID not found] +sig 3 F8EA2967 2005-07-26 [User ID not found] +sig 3 C152431A 2005-07-27 Steve Loughran +sig DE885DD3 2005-11-25 Sander Striker +sig E222DE4F 2007-05-02 Mathias Herberts +sig 911203E4 2007-05-02 [User ID not found] +sig F12F6072 2007-05-05 [User ID not found] +sig 3 990ED4AA 2007-05-02 Knut Anders Hatlen +sig 3 311A3DE5 2007-05-05 Ruediger Pluem +sig 3 88817402 2007-05-06 Thomas Vandahl +sig 4CEED75F 2007-05-06 Nick Burch +sig 4358C584 2007-05-06 Vincent Hennebert +sig 0B7E6CFA 2007-05-06 Sami Siren +sig 3 DE8884A0 2007-05-07 Xavier Hanin +sig 3 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) +sig 40581837 2007-05-08 Nick Kew +uid Stefan Bodewig +sig 3 5F6B8B72 2005-05-31 Stefan Bodewig +sig 51898504 2005-06-21 Conor MacNeill +sig 2FE28BCF 2005-07-01 Harald Wilhelm (HAWI) +sig 5793498F 2005-07-21 Tim Ellison +sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 3 EE65E321 2005-07-20 Martin Kraemer +sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size +sig 3 21D0A71B 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) +sig 3 3642CB4B 2005-07-20 Martin Kraemer +sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) +sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size +sig 3 CC78C893 2005-07-22 Rich Bowen +sig 3 E2D774DF 2005-07-22 Sylvain Wallez +sig 3 E04F9A89 2005-07-22 Roy T. Fielding +sig 3 87315C31 2005-07-23 Raphal Luta +sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler +sig 3 F39B3750 2005-07-24 Colm MacCarthaigh +sig 1CD4861F 2005-07-25 Eran Chinthaka +sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) +sig 333E4E84 2005-07-26 Chathura Kamalanath Herath (Apachecon Europe 2005) +sig 152924AF 2005-07-29 Sander Temme +sig 3 9C85222B 2005-07-24 Henning Schmiedehausen +sig 3 9978AF86 2005-07-25 [User ID not found] +sig 3 2A623F72 2005-07-25 [User ID not found] +sig 3 F8EA2967 2005-07-26 [User ID not found] +sig 3 C152431A 2005-07-27 Steve Loughran +sig DE885DD3 2005-11-25 Sander Striker +sig E222DE4F 2007-05-02 Mathias Herberts +sig 911203E4 2007-05-02 [User ID not found] +sig F12F6072 2007-05-05 [User ID not found] +sig 3 990ED4AA 2007-05-02 Knut Anders Hatlen +sig 3 311A3DE5 2007-05-05 Ruediger Pluem +sig 3 88817402 2007-05-06 Thomas Vandahl +sig 4CEED75F 2007-05-06 Nick Burch +sig 4358C584 2007-05-06 Vincent Hennebert +sig 0B7E6CFA 2007-05-06 Sami Siren +sig 3 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) +sig 40581837 2007-05-08 Nick Kew +sub 1024g/24774157 2001-05-28 +sig 5F6B8B72 2001-05-28 Stefan Bodewig + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.2 (GNU/Linux) + +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 +b0zPjKjGuiwdKSnkFbNcFS3g +=UxMc +-----END PGP PUBLIC KEY BLOCK----- diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..29deee30 --- /dev/null +++ b/NOTICE @@ -0,0 +1,5 @@ + Apache log4net + Copyright 2004-2013 The Apache Software Foundation + + This product includes software developed at + The Apache Software Foundation (http://www.apache.org/). diff --git a/README.txt b/README.txt new file mode 100644 index 00000000..40a4b012 --- /dev/null +++ b/README.txt @@ -0,0 +1,16 @@ +Project Status +============== + +Apache log4net is a sub project of the Apache Logging Services project. +Apache log4net graduated from the Apache Incubator in February 2007. +Web site: http://logging.apache.org/log4net + + +Documentation +============= + +For local documentation, which is correct for this release see: +doc/index.html + +For the latest documentation see the log4net web site at: +http://logging.apache.org/log4net diff --git a/STATUS.txt b/STATUS.txt new file mode 100644 index 00000000..110415fe --- /dev/null +++ b/STATUS.txt @@ -0,0 +1,31 @@ +APACHE LOG4NET PROJECT STATUS +============================= + +Project Status +============== + +Apache log4net is a sub project of the Apache Logging Services project. +Apache log4net graduated from the Apache Incubator in February 2007. + + +Project Details +=============== + +Web site: http://logging.apache.org/log4net/ +Issue Tracking: http://issues.apache.org/jira/browse/LOG4NET +Source Code: http://svn.apache.org/viewvc/logging/log4net/ +Mailing Lists: + User: log4net-user@logging.apache.org + Dev: log4net-dev@logging.apache.org + + +Active Committers +================= + +* Nicko Cadell (nicko) +* Niall Daley (niall) +* Gert Driesen (drieseng) +* Ron Grabowski (rgrabowski) +* Stefan Bodewig (bodewig) +* Dominik Psenner (dpsenner) + diff --git a/build.cmd b/build.cmd new file mode 100755 index 00000000..db885124 --- /dev/null +++ b/build.cmd @@ -0,0 +1,131 @@ +rem +rem +rem Licensed to the Apache Software Foundation (ASF) under one +rem or more contributor license agreements. See the NOTICE file +rem distributed with this work for additional information +rem regarding copyright ownership. The ASF licenses this file +rem to you under the Apache License, Version 2.0 (the +rem "License"); you may not use this file except in compliance +rem with the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, +rem software distributed under the License is distributed on an +rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +rem KIND, either express or implied. See the License for the +rem specific language governing permissions and limitations +rem under the License. +rem +rem +@ECHO OFF + +REM We are going to change the environment variables, so protect the current settings. +SETLOCAL ENABLEDELAYEDEXPANSION + +IF "%1"=="-?" GOTO CommandLineOptions + +REM Figure out the path to the log4net directory +CALL :ComputeBase %~f0 +SET LOG4NET_DIR=%RESULT% +ECHO LOG4NET_DIR is %LOG4NET_DIR% + +REM Get path to NAnt.exe + +REM Try and determine if NAnt is in the PATH +SET NANTEXE_PATH=nant.exe +"%NANTEXE_PATH%" -help >NUL: 2>NUL: +IF NOT ERRORLEVEL 1 goto FoundNAnt + +REM Try hard coded path for NAnt +SET NANTEXE_PATH=C:\Program Files\NAnt\nant-0.85\bin\nant.exe +"%NANTEXE_PATH%" -help >NUL: 2>NUL: +IF NOT ERRORLEVEL 1 goto FoundNAnt + +REM We have not found NAnt +ECHO. +ECHO NAnt does not appear to be installed. NAnt.exe failed to execute. +ECHO Please ensure NAnt is installed and can be found in the PATH. +GOTO EndError + + +:FoundNAnt +ECHO NANTEXE_PATH is %NANTEXE_PATH% + +REM Setup the build file +IF EXIST nant.build ( + SET BUILD_FILE=nant.build +) ELSE ( + SET BUILD_FILE=%LOG4NET_DIR%\log4net.build +) + +ECHO BUILD_FILE is %BUILD_FILE% + + +IF "%1"=="package" GOTO Package + +"%NANTEXE_PATH%" "-buildfile:%BUILD_FILE%" %1 %2 %3 %4 %5 %6 %7 %8 +GOTO EndOk + +:Package +IF "%2"=="" GOTO NoProjectVersion + +"%NANTEXE_PATH%" "-buildfile:%BUILD_FILE%" package "-D:package.version=%2" %3 %4 %5 %6 %7 %8 +GOTO EndOk + +:NoProjectVersion +ECHO. +ECHO SYNTAX ERROR: Missing Version String. +ECHO Please specify the version number of log4net that you want to package. +GOTO CommandLineOptions + +:CommandLineOptions +ECHO. +ECHO Use the following command line syntax: +ECHO. +ECHO build.cmd -? +ECHO build.cmd -projecthelp +ECHO build.cmd [nant target] +ECHO build.cmd package [version string] +ECHO. +ECHO To get a list of all NAnt build targets run build.cmd with the -projecthelp option. +ECHO If no NAnt target is specified then the default target is 'compile-all'. This will compile all configurations on all available frameworks. +ECHO When using the 'package' command the version label for the package must be specified. +ECHO. +ECHO Examples: +ECHO. +ECHO build.cmd compile-mono-1.0 +ECHO build.cmd compile-all +ECHO build.cmd package 1.3.0 +ECHO build.cmd package 2.1.0-alpha +ECHO. +GOTO EndError + + +REM ------------------------------------------ +REM Expand a string to a full path +REM ------------------------------------------ +:FullPath +SET RESULT=%~f1 +GOTO :EOF + +REM ------------------------------------------ +REM Compute the current directory +REM given a path to this batch script. +REM ------------------------------------------ +:ComputeBase +SET RESULT=%~dp1 +REM Remove the trailing \ +SET RESULT=%RESULT:~0,-1% +CALL :FullPath %RESULT% +GOTO :EOF + + +:EndOk +ENDLOCAL +EXIT /B 0 + +:EndError +ENDLOCAL +EXIT /B 1 + diff --git a/examples/mono/1.0/Performance/NotLogging/cs/nant.build b/examples/mono/1.0/Performance/NotLogging/cs/nant.build new file mode 100644 index 00000000..4d5ac2c8 --- /dev/null +++ b/examples/mono/1.0/Performance/NotLogging/cs/nant.build @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Performance/NotLogging/cs/nant.config b/examples/mono/1.0/Performance/NotLogging/cs/nant.config new file mode 100644 index 00000000..52613e83 --- /dev/null +++ b/examples/mono/1.0/Performance/NotLogging/cs/nant.config @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/examples/mono/1.0/Performance/NotLogging/cs/src/AssemblyInfo.cs b/examples/mono/1.0/Performance/NotLogging/cs/src/AssemblyInfo.cs new file mode 100644 index 00000000..b278ed8c --- /dev/null +++ b/examples/mono/1.0/Performance/NotLogging/cs/src/AssemblyInfo.cs @@ -0,0 +1,61 @@ +#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.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("log4net - NotLogging")] +[assembly: AssemblyDescription("log4net performance test - NotLogging")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyProduct("log4net - NotLogging")] +[assembly: AssemblyCulture("")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/examples/mono/1.0/Performance/NotLogging/cs/src/NotLogging.cs b/examples/mono/1.0/Performance/NotLogging/cs/src/NotLogging.cs new file mode 100644 index 00000000..0501ef94 --- /dev/null +++ b/examples/mono/1.0/Performance/NotLogging/cs/src/NotLogging.cs @@ -0,0 +1,434 @@ +#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 + +namespace NotLogging +{ + using System; + using System.Collections; + + using log4net; + using log4net.Appender; + using log4net.Layout; + using log4net.Repository; + using log4net.Repository.Hierarchy; + + public class NotLogging + { + #region Init Code + + private static int WARM_UP_CYCLES = 10000; + + static readonly ILog SHORT_LOG = LogManager.GetLogger("A0123456789"); + static readonly ILog MEDIUM_LOG= LogManager.GetLogger("A0123456789.B0123456789"); + static readonly ILog LONG_LOG = LogManager.GetLogger("A0123456789.B0123456789.C0123456789"); + + static readonly ILog INEXISTENT_SHORT_LOG = LogManager.GetLogger("I0123456789"); + static readonly ILog INEXISTENT_MEDIUM_LOG= LogManager.GetLogger("I0123456789.B0123456789"); + static readonly ILog INEXISTENT_LONG_LOG = LogManager.GetLogger("I0123456789.B0123456789.C0123456789"); + + + static readonly ILog[] LOG_ARRAY = new ILog[] { + SHORT_LOG, + MEDIUM_LOG, + LONG_LOG, + INEXISTENT_SHORT_LOG, + INEXISTENT_MEDIUM_LOG, + INEXISTENT_LONG_LOG}; + + static readonly TimedTest[] TIMED_TESTS = new TimedTest[] { + new SimpleMessage_Bare(), + new SimpleMessage_Array(), + new SimpleMessage_MethodGuard_Bare(), + new SimpleMessage_LocalGuard_Bare(), + new ComplexMessage_Bare(), + new ComplexMessage_Array(), + new ComplexMessage_MethodGuard_Bare(), + new ComplexMessage_MethodGuard_Array(), + new ComplexMessage_MemberGuard_Bare(), + new ComplexMessage_LocalGuard_Bare()}; + + private static void Usage() + { + System.Console.WriteLine( + "Usage: NotLogging " + Environment.NewLine + + "\t true indicates shipped code" + Environment.NewLine + + "\t false indicates code in development" + Environment.NewLine + + "\t runLength is an int representing the run length of loops" + Environment.NewLine + + "\t We suggest that runLength be at least 1000000 (1 million)."); + Environment.Exit(1); + } + + + /// + /// Program wide initialization method + /// + /// + private static int ProgramInit(String[] args) + { + int runLength = 0; + + try + { + runLength = int.Parse(args[1]); + } + catch(Exception e) + { + System.Console.Error.WriteLine(e); + Usage(); + } + + ConsoleAppender appender = new ConsoleAppender(new SimpleLayout()); + + if("false" == args[0]) + { + // nothing to do + } + else if ("true" == args[0]) + { + System.Console.WriteLine("Flagging as shipped code."); + ((Hierarchy)LogManager.GetRepository()).Threshold = log4net.Core.Level.Warn; + } + else + { + Usage(); + } + + ((Logger)SHORT_LOG.Logger).Level = log4net.Core.Level.Info; + ((Hierarchy)LogManager.GetRepository()).Root.Level = log4net.Core.Level.Info; + ((Hierarchy)LogManager.GetRepository()).Root.AddAppender(appender); + + return runLength; + } + + #endregion + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] argv) + { + if (System.Diagnostics.Debugger.IsAttached) + { + WARM_UP_CYCLES = 0; + argv = new string[] { "false", "2" }; + } + if(argv.Length != 2) + { + Usage(); + } + + int runLength = ProgramInit(argv); + + System.Console.WriteLine(); + System.Console.Write("Warming Up..."); + + if (WARM_UP_CYCLES > 0) + { + foreach(ILog logger in LOG_ARRAY) + { + foreach(TimedTest timedTest in TIMED_TESTS) + { + timedTest.Run(logger, WARM_UP_CYCLES); + } + } + } + System.Console.WriteLine("Done"); + System.Console.WriteLine(); + + // Calculate maximum description length + int maxDescLen = 0; + foreach(TimedTest timedTest in TIMED_TESTS) + { + maxDescLen = Math.Max(maxDescLen, timedTest.Description.Length); + } + + string formatString = "{0,-"+(maxDescLen+1)+"} {1,9:G} ticks. Log: {2}"; + double delta; + + ArrayList averageData = new ArrayList(); + + foreach(TimedTest timedTest in TIMED_TESTS) + { + double total = 0; + foreach(ILog logger in LOG_ARRAY) + { + delta = timedTest.Run(logger, runLength); + System.Console.WriteLine(string.Format(formatString, timedTest.Description, delta, ((Logger)logger.Logger).Name)); + + total += delta; + } + System.Console.WriteLine(); + + averageData.Add(new object[] { timedTest, total/((double)LOG_ARRAY.Length) }); + } + System.Console.WriteLine(); + System.Console.WriteLine("Averages:"); + System.Console.WriteLine(); + + foreach(object[] pair in averageData) + { + string avgFormatString = "{0,-"+(maxDescLen+1)+"} {1,9:G} ticks."; + System.Console.WriteLine(string.Format(avgFormatString, ((TimedTest)pair[0]).Description, ((double)pair[1]))); + } + } + } + + abstract class TimedTest + { + abstract public double Run(ILog log, long runLength); + abstract public string Description {get;} + } + + #region Tests calling Debug(string) + + class SimpleMessage_Bare : TimedTest + { + override public double Run(ILog log, long runLength) + { + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + log.Debug("msg"); + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + + override public string Description + { + get { return "log.Debug(\"msg\");"; } + } + } + class ComplexMessage_MethodGuard_Bare : TimedTest + { + override public double Run(ILog log, long runLength) + { + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + if(log.IsDebugEnabled) + { + log.Debug("msg" + i + "msg"); + } + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + + override public string Description + { + get { return "if(log.IsDebugEnabled) log.Debug(\"msg\" + i + \"msg\");"; } + } + } + class ComplexMessage_Bare : TimedTest + { + override public double Run(ILog log, long runLength) + { + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + log.Debug("msg" + i + "msg"); + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + + override public string Description + { + get { return "log.Debug(\"msg\" + i + \"msg\");"; } + } + } + + #endregion + + #region Tests calling Debug(new object[] { ... }) + + class SimpleMessage_Array : TimedTest + { + override public double Run(ILog log, long runLength) + { + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + log.Debug(new object[] { "msg" }); + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + + override public string Description + { + get { return "log.Debug(new object[] { \"msg\" });"; } + } + } + class ComplexMessage_MethodGuard_Array : TimedTest + { + override public double Run(ILog log, long runLength) + { + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + if(log.IsDebugEnabled) + { + log.Debug(new object[] { "msg" , i , "msg" }); + } + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + + override public string Description + { + get { return "if(log.IsDebugEnabled) log.Debug(new object[] { \"msg\" , i , \"msg\" });"; } + } + } + class ComplexMessage_Array : TimedTest + { + override public double Run(ILog log, long runLength) + { + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + log.Debug(new object[] { "msg" , i , "msg" }); + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + + override public string Description + { + get { return "log.Debug(new object[] { \"msg\" , i , \"msg\" });"; } + } + } + + #endregion + + #region Tests calling Debug(string) (using class members) + + class ComplexMessage_MemberGuard_Bare : TimedTest + { + override public double Run(ILog log, long runLength) + { + return (new Impl(log)).Run(runLength); + } + + override public string Description + { + get { return "if(m_isEnabled) m_log.Debug(\"msg\" + i + \"msg\");"; } + } + + class Impl + { + private readonly ILog m_log; + private readonly bool m_isEnabled; + + public Impl(ILog log) + { + m_log = log; + m_isEnabled = m_log.IsDebugEnabled; + } + + public double Run(long runLength) + { + + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + if(m_isEnabled) + { + m_log.Debug("msg" + i + "msg"); + } + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + } + } + class SimpleMessage_LocalGuard_Bare : TimedTest + { + override public double Run(ILog log, long runLength) + { + bool isEnabled = log.IsDebugEnabled; + + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + if (isEnabled) log.Debug("msg"); + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + + override public string Description + { + get { return "if (isEnabled) log.Debug(\"msg\");"; } + } + } + class SimpleMessage_MethodGuard_Bare : TimedTest + { + override public double Run(ILog log, long runLength) + { + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + if (log.IsDebugEnabled) log.Debug("msg"); + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + + override public string Description + { + get { return "if (log.IsDebugEnabled) log.Debug(\"msg\");"; } + } + } + class ComplexMessage_LocalGuard_Bare : TimedTest + { + override public double Run(ILog log, long runLength) + { + bool isEnabled = log.IsDebugEnabled; + + DateTime before = DateTime.Now; + for(int i = 0; i < runLength; i++) + { + if(isEnabled) log.Debug("msg" + i + "msg"); + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks)/((double)runLength); + } + + override public string Description + { + get { return "if (isEnabled) log.Debug(\"msg\" + i + \"msg\");"; } + } + } + #endregion + +} diff --git a/examples/mono/1.0/Performance/NotLogging/nant.build b/examples/mono/1.0/Performance/NotLogging/nant.build new file mode 100644 index 00000000..59179243 --- /dev/null +++ b/examples/mono/1.0/Performance/NotLogging/nant.build @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Performance/NotLogging/nant.config b/examples/mono/1.0/Performance/NotLogging/nant.config new file mode 100644 index 00000000..ba0a7243 --- /dev/null +++ b/examples/mono/1.0/Performance/NotLogging/nant.config @@ -0,0 +1,21 @@ + + + + + + diff --git a/examples/mono/1.0/Performance/nant.build b/examples/mono/1.0/Performance/nant.build new file mode 100644 index 00000000..50cad4a2 --- /dev/null +++ b/examples/mono/1.0/Performance/nant.build @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Performance/nant.config b/examples/mono/1.0/Performance/nant.config new file mode 100644 index 00000000..ba0a7243 --- /dev/null +++ b/examples/mono/1.0/Performance/nant.config @@ -0,0 +1,21 @@ + + + + + + diff --git a/examples/mono/1.0/Repository/SharedModule/cs/nant.build b/examples/mono/1.0/Repository/SharedModule/cs/nant.build new file mode 100644 index 00000000..36fce7f9 --- /dev/null +++ b/examples/mono/1.0/Repository/SharedModule/cs/nant.build @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Repository/SharedModule/cs/nant.config b/examples/mono/1.0/Repository/SharedModule/cs/nant.config new file mode 100644 index 00000000..52613e83 --- /dev/null +++ b/examples/mono/1.0/Repository/SharedModule/cs/nant.config @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/examples/mono/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs b/examples/mono/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs new file mode 100644 index 00000000..ee756423 --- /dev/null +++ b/examples/mono/1.0/Repository/SharedModule/cs/src/AssemblyInfo.cs @@ -0,0 +1,61 @@ +#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.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("log4net - SharedModule")] +[assembly: AssemblyDescription("log4net SharedModule")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyProduct("log4net - SharedModule")] +[assembly: AssemblyCulture("")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/examples/mono/1.0/Repository/SharedModule/cs/src/Math.cs b/examples/mono/1.0/Repository/SharedModule/cs/src/Math.cs new file mode 100644 index 00000000..64211dc3 --- /dev/null +++ b/examples/mono/1.0/Repository/SharedModule/cs/src/Math.cs @@ -0,0 +1,42 @@ +#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 + +namespace SharedModule +{ + /// + /// Summary description for Math. + /// + public class Math + { + // Create a logger for use in this class + private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + public Math() + { + if (log.IsDebugEnabled) log.Debug("Constructor"); + } + + public int Subtract(int left, int right) + { + int result = left - right; + if (log.IsInfoEnabled) log.Info(""+left+" - "+right+" = "+result); + return result; + } + } +} diff --git a/examples/mono/1.0/Repository/SharedModule/nant.build b/examples/mono/1.0/Repository/SharedModule/nant.build new file mode 100644 index 00000000..a11e9cd2 --- /dev/null +++ b/examples/mono/1.0/Repository/SharedModule/nant.build @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Repository/SharedModule/nant.config b/examples/mono/1.0/Repository/SharedModule/nant.config new file mode 100644 index 00000000..ba0a7243 --- /dev/null +++ b/examples/mono/1.0/Repository/SharedModule/nant.config @@ -0,0 +1,21 @@ + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/nant.build b/examples/mono/1.0/Repository/SimpleApp/cs/nant.build new file mode 100644 index 00000000..40688e33 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleApp/cs/nant.build @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/nant.config b/examples/mono/1.0/Repository/SimpleApp/cs/nant.config new file mode 100644 index 00000000..52613e83 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleApp/cs/nant.config @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/src/App.config b/examples/mono/1.0/Repository/SimpleApp/cs/src/App.config new file mode 100644 index 00000000..10a5b298 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleApp/cs/src/App.config @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs b/examples/mono/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs new file mode 100644 index 00000000..cc3415de --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleApp/cs/src/AssemblyInfo.cs @@ -0,0 +1,61 @@ +#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.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("log4net - SimpleApp")] +[assembly: AssemblyDescription("log4net SimpleApp")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyProduct("log4net - SimpleApp")] +[assembly: AssemblyCulture("")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs b/examples/mono/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs new file mode 100644 index 00000000..a2a9f359 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleApp/cs/src/EntryPoint.cs @@ -0,0 +1,80 @@ +#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 + +// Configure logging for this assembly using the 'SimpleApp.exe.log4net' file +[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net", Watch=true)] + +// The following alias attribute can be used to capture the logging +// repository for the 'SimpleModule' assembly. Without specifying this +// attribute the logging configuration for the 'SimpleModule' assembly +// will be read from the 'SimpleModule.dll.log4net' file. When this +// attribute is specified the configuration will be shared with this +// assemby's configuration. +//[assembly: log4net.Config.AliasRepository("SimpleModule")] + +namespace SimpleApp +{ + using System; + + /// + /// Summary description for Class1. + /// + class EntryPoint + { + // Create a logger for use in this class + private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + if (log.IsInfoEnabled) log.Info(args); + + if (args.Length != 2) + { + log.Error("Must supply 2 command line arguments"); + } + else + { + int left = int.Parse(args[0]); + int right = int.Parse(args[1]); + int result = 0; + + if (log.IsDebugEnabled) log.Debug("Adding ["+left+"] to ["+right+"]"); + + result = (new SimpleModule.Math()).Add(left, right); + + if (log.IsDebugEnabled) log.Debug("Result ["+result+"]"); + + Console.Out.WriteLine(result); + + + if (log.IsDebugEnabled) log.Debug("Subtracting ["+right+"] from ["+left+"]"); + + result = (new SharedModule.Math()).Subtract(left, right); + + if (log.IsDebugEnabled) log.Debug("Result ["+result+"]"); + + Console.Out.WriteLine(result); + } + } + } +} diff --git a/examples/mono/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net b/examples/mono/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net new file mode 100644 index 00000000..ffef9585 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleApp/cs/src/SimpleApp.exe.log4net @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleApp/nant.build b/examples/mono/1.0/Repository/SimpleApp/nant.build new file mode 100644 index 00000000..d92e4c5b --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleApp/nant.build @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleApp/nant.config b/examples/mono/1.0/Repository/SimpleApp/nant.config new file mode 100644 index 00000000..ba0a7243 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleApp/nant.config @@ -0,0 +1,21 @@ + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/nant.build b/examples/mono/1.0/Repository/SimpleModule/cs/nant.build new file mode 100644 index 00000000..9ee2cbeb --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleModule/cs/nant.build @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/nant.config b/examples/mono/1.0/Repository/SimpleModule/cs/nant.config new file mode 100644 index 00000000..52613e83 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleModule/cs/nant.config @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs b/examples/mono/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs new file mode 100644 index 00000000..1c32a350 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleModule/cs/src/AssemblyInfo.cs @@ -0,0 +1,61 @@ +#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.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("log4net - SimpleModule")] +[assembly: AssemblyDescription("log4net SimpleModule")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyProduct("log4net - SimpleModule")] +[assembly: AssemblyCulture("")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/src/Math.cs b/examples/mono/1.0/Repository/SimpleModule/cs/src/Math.cs new file mode 100644 index 00000000..3c01a792 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleModule/cs/src/Math.cs @@ -0,0 +1,49 @@ +#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 + +// We want this assembly to have a seperate logging repository to the +// rest of the application. We will configure this repository seperatly. +[assembly: log4net.Config.Repository("SimpleModule")] + +// Configure logging for this assembly using the 'SimpleModule.dll.log4net' file +[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net", Watch=true)] + +namespace SimpleModule +{ + /// + /// Summary description for Math. + /// + public class Math + { + // Create a logger for use in this class + private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + public Math() + { + if (log.IsDebugEnabled) log.Debug("Constructor"); + } + + public int Add(int left, int right) + { + int result = left + right; + if (log.IsInfoEnabled) log.Info(""+left+" + "+right+" = "+result); + return result; + } + } +} diff --git a/examples/mono/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net b/examples/mono/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net new file mode 100644 index 00000000..cd01ae19 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleModule/cs/src/SimpleModule.dll.log4net @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleModule/nant.build b/examples/mono/1.0/Repository/SimpleModule/nant.build new file mode 100644 index 00000000..614f891f --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleModule/nant.build @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Repository/SimpleModule/nant.config b/examples/mono/1.0/Repository/SimpleModule/nant.config new file mode 100644 index 00000000..ba0a7243 --- /dev/null +++ b/examples/mono/1.0/Repository/SimpleModule/nant.config @@ -0,0 +1,21 @@ + + + + + + diff --git a/examples/mono/1.0/Repository/nant.build b/examples/mono/1.0/Repository/nant.build new file mode 100644 index 00000000..27c3394a --- /dev/null +++ b/examples/mono/1.0/Repository/nant.build @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Repository/nant.config b/examples/mono/1.0/Repository/nant.config new file mode 100644 index 00000000..ba0a7243 --- /dev/null +++ b/examples/mono/1.0/Repository/nant.config @@ -0,0 +1,21 @@ + + + + + + diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.build b/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.build new file mode 100644 index 00000000..c88e310d --- /dev/null +++ b/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.build @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.config b/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.config new file mode 100644 index 00000000..2be781bc --- /dev/null +++ b/examples/mono/1.0/Tutorials/ConsoleApp/cs/nant.config @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config b/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config new file mode 100644 index 00000000..f312d5f2 --- /dev/null +++ b/examples/mono/1.0/Tutorials/ConsoleApp/cs/src/App.config @@ -0,0 +1,208 @@ + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    +