Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

asynchronous APIs - lots of changes, completely untested

  • Loading branch information...
commit 697467ad0c696c44836de51d55e9a63e8ee2d604 1 parent 665cba2
Jarek Kowalski authored
Showing with 2,025 additions and 332 deletions.
  1. +36 −4 src/LocalTestRun.netfx40.testrunconfig
  2. +1 −0  src/NLog.proj
  3. +12 −11 src/NLog/Config/LoggingConfiguration.cs
  4. +39 −0 src/NLog/Internal/AsyncContinuation.cs
  5. +255 −0 src/NLog/Internal/AsyncHelpers.cs
  6. +39 −0 src/NLog/Internal/AsynchronousAction.cs
  7. +46 −0 src/NLog/Internal/ExtensionAttribute.cs
  8. +70 −0 src/NLog/Internal/SingleCallContinuation.cs
  9. +37 −0 src/NLog/Internal/SynchronousAction.cs
  10. +90 −0 src/NLog/Internal/TimeoutContinuation.cs
  11. +38 −3 src/NLog/LogFactory.cs
  12. +56 −24 src/NLog/LogManager.cs
  13. +106 −65 src/NLog/LoggerImpl.cs
  14. +9 −1 src/NLog/NLog.mono2.csproj
  15. +9 −1 src/NLog/NLog.netcf20.csproj
  16. +10 −1 src/NLog/NLog.netcf35.csproj
  17. +9 −1 src/NLog/NLog.netfx20.csproj
  18. +9 −1 src/NLog/NLog.netfx35.csproj
  19. +9 −1 src/NLog/NLog.netfx40.csproj
  20. +9 −1 src/NLog/NLog.sl2.csproj
  21. +9 −1 src/NLog/NLog.sl3.csproj
  22. +9 −1 src/NLog/NLog.sl4.csproj
  23. +2 −2 src/NLog/{Config → }/NLogConfigurationException.cs
  24. +90 −0 src/NLog/NLogRuntimeException.cs
  25. +1 −1  src/NLog/ProjectFileInfo.xml
  26. +12 −1 src/NLog/Targets/Compound/CompoundTargetBase.cs
  27. +48 −15 src/NLog/Targets/Compound/FallbackTarget.cs
  28. +13 −5 src/NLog/Targets/Compound/RandomizeTarget.cs
  29. +7 −4 src/NLog/Targets/Compound/RoundRobinTarget.cs
  30. +7 −5 src/NLog/Targets/Compound/SplitTarget.cs
  31. +15 −6 src/NLog/Targets/FileTarget.cs
  32. +9 −4 src/NLog/Targets/NetworkTarget.cs
  33. +88 −31 src/NLog/Targets/Target.cs
  34. +1 −2  src/NLog/Targets/Wrappers/AspNetBufferingTargetWrapper.cs
  35. +1 −1  src/NLog/Targets/Wrappers/AsyncRequestQueue-T.cs
  36. +49 −58 src/NLog/Targets/Wrappers/AsyncTargetWrapper.cs
  37. +7 −4 src/NLog/Targets/Wrappers/AutoFlushTargetWrapper.cs
  38. +24 −12 src/NLog/Targets/Wrappers/BufferingTargetWrapper.cs
  39. +9 −2 src/NLog/Targets/Wrappers/FilteringTargetWrapper.cs
  40. +6 −4 src/NLog/Targets/Wrappers/ImpersonatingTargetWrapper.cs
  41. +14 −5 src/NLog/Targets/Wrappers/PostFilteringTargetWrapper.cs
  42. +6 −25 src/NLog/Targets/Wrappers/RepeatingTargetWrapper.cs
  43. +26 −17 src/NLog/Targets/Wrappers/RetryingTargetWrapper.cs
  44. +15 −3 src/NLog/Targets/Wrappers/WrapperTargetBase.cs
  45. +427 −0 tests/NLog.UnitTests/AsyncHelperTests.cs
  46. +2 −0  tests/NLog.UnitTests/NLog.UnitTests.netcf20.csproj
  47. +2 −0  tests/NLog.UnitTests/NLog.UnitTests.netcf35.csproj
  48. +2 −0  tests/NLog.UnitTests/NLog.UnitTests.netfx20.csproj
  49. +2 −0  tests/NLog.UnitTests/NLog.UnitTests.netfx35.csproj
  50. +2 −0  tests/NLog.UnitTests/NLog.UnitTests.netfx40.csproj
  51. +2 −0  tests/NLog.UnitTests/NLog.UnitTests.sl2.csproj
  52. +2 −0  tests/NLog.UnitTests/NLog.UnitTests.sl3.csproj
  53. +2 −0  tests/NLog.UnitTests/NLog.UnitTests.sl4.csproj
  54. +1 −1  tests/NLog.UnitTests/ProjectFileInfo.xml
  55. +5 −0 tests/NLog.UnitTests/SourceCodeTests.cs
  56. +10 −7 tests/NLog.UnitTests/Targets/ConcurrentFileTargetTests.cs
  57. +4 −1 tests/NLog.UnitTests/Targets/FileTargetTests.cs
  58. +205 −0 tests/NLog.UnitTests/Targets/Wrappers/AutoFlushTargetWrapperTests.cs
40 src/LocalTestRun.netfx40.testrunconfig
View
@@ -1,5 +1,37 @@
-<?xml version="1.0" encoding="utf-8"?>
-<TestRunConfiguration name="Local Test Run" id="d5ad33a1-e178-4da8-880b-e73a8eedbdbe" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
+<?xml version="1.0" encoding="UTF-8"?>
+<TestSettings name="Local Test Run" id="d5ad33a1-e178-4da8-880b-e73a8eedbdbe" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Description>This is a default test run configuration for a local test run.</Description>
- <TestTypeSpecific />
-</TestRunConfiguration>
+ <Execution>
+ <TestTypeSpecific>
+ <UnitTestRunConfig testTypeId="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b">
+ <AssemblyResolution>
+ <TestDirectory useLoadContext="true" />
+ </AssemblyResolution>
+ </UnitTestRunConfig>
+ <WebTestRunConfiguration testTypeId="4e7599fa-5ecb-43e9-a887-cd63cf72d207">
+ <Browser name="Internet Explorer 7.0">
+ <Headers>
+ <Header name="User-Agent" value="Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)" />
+ <Header name="Accept" value="*/*" />
+ <Header name="Accept-Language" value="{{$IEAcceptLanguage}}" />
+ <Header name="Accept-Encoding" value="GZIP" />
+ </Headers>
+ </Browser>
+ </WebTestRunConfiguration>
+ </TestTypeSpecific>
+ <AgentRule name="LocalMachineDefaultRole">
+ <DataCollectors>
+ <DataCollector uri="datacollector://Microsoft/CodeCoverage/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TestTools.CodeCoverage.CoveragePlugIn, Microsoft.VisualStudio.QualityTools.Plugins.CodeCoverage, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="Code Coverage">
+ <Configuration>
+ <CodeCoverage keyFile="NLog.snk" xmlns="">
+ <Regular>
+ <CodeCoverageItem binaryFile="NLog\bin\Debug\.NET Framework 4.0\NLog.dll" pdbFile="NLog\bin\Debug\.NET Framework 4.0\NLog.pdb" instrumentInPlace="true" />
+ <CodeCoverageItem binaryFile="NLog\bin\Debug\.NET Framework 4.0\NLog.Extended.dll" pdbFile="NLog\bin\Debug\.NET Framework 4.0\NLog.Extended.pdb" instrumentInPlace="true" />
+ </Regular>
+ </CodeCoverage>
+ </Configuration>
+ </DataCollector>
+ </DataCollectors>
+ </AgentRule>
+ </Execution>
+</TestSettings>
1  src/NLog.proj
View
@@ -248,6 +248,7 @@
</Target>
<Target Name="CheckinSuite">
+ <CallTarget Targets="SyncProjectItems" />
<CallTarget Targets="DeepClean" />
<CallTarget Targets="Rebuild" />
<CallTarget Targets="DumpApi" />
23 src/NLog/Config/LoggingConfiguration.cs
View
@@ -40,6 +40,7 @@ namespace NLog.Config
using NLog.Common;
using NLog.Internal;
using NLog.Targets;
+ using System.Threading;
/// <summary>
/// Keeps logging configuration and provides simple API
@@ -193,22 +194,22 @@ internal void Dump()
/// <summary>
/// Flushes any pending log messages on all appenders.
/// </summary>
- /// <param name="timeout">
- /// The timeout.
- /// </param>
- internal void FlushAllTargets(TimeSpan timeout)
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ internal void FlushAllTargets(AsyncContinuation asyncContinuation)
{
- foreach (Target target in this.targets.Values)
+ List<Target> targets = new List<Target>();
+ foreach (var rule in this.LoggingRules)
{
- try
- {
- target.Flush(timeout);
- }
- catch (Exception ex)
+ foreach (var t in rule.Targets)
{
- InternalLogger.Error("Error while flushing target: {0} {1}", target.Name, ex);
+ if (!targets.Contains(t))
+ {
+ targets.Add(t);
+ }
}
}
+
+ AsyncHelpers.RunInParallel(targets, asyncContinuation, (cont, target) => target.Flush(cont));
}
internal void InitializeAll()
39 src/NLog/Internal/AsyncContinuation.cs
View
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2004-2010 Jaroslaw Kowalski <jaak@jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog.Internal
+{
+ using System;
+
+ public delegate void AsyncContinuation(Exception exception);
+}
255 src/NLog/Internal/AsyncHelpers.cs
View
@@ -0,0 +1,255 @@
+//
+// Copyright (c) 2004-2010 Jaroslaw Kowalski <jaak@jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog.Internal
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Threading;
+ using NLog.Common;
+
+ /// <summary>
+ /// Helpers for asynchronous operations.
+ /// </summary>
+ public static class AsyncHelpers
+ {
+ public static void LogException(Exception ex)
+ {
+ InternalLogger.Error("EXCEPTION: {0}", ex);
+ }
+
+ public static void ForEachItemSequentially<T>(IEnumerable<T> items, AsyncContinuation asyncContinuation, AsynchronousAction<T> action)
+ {
+ action = ExceptionGuard(action);
+ AsyncContinuation invokeNext = null;
+ IEnumerator<T> enumerator = items.GetEnumerator();
+
+ invokeNext = ex =>
+ {
+ if (ex != null)
+ {
+ asyncContinuation(ex);
+ return;
+ }
+
+ if (!enumerator.MoveNext())
+ {
+ asyncContinuation(null);
+ return;
+ }
+
+ action(invokeNext.OneTimeOnly(), enumerator.Current);
+ };
+
+ invokeNext(null);
+ }
+
+ public static void Repeat(int repeatCount, AsyncContinuation asyncContinuation, AsynchronousAction action)
+ {
+ action = ExceptionGuard(action);
+ AsyncContinuation invokeNext = null;
+ int remaining = repeatCount;
+
+ invokeNext = ex =>
+ {
+ if (ex != null)
+ {
+ asyncContinuation(ex);
+ return;
+ }
+
+ if (remaining-- <= 0)
+ {
+ asyncContinuation(null);
+ return;
+ }
+
+ action(invokeNext.OneTimeOnly());
+ };
+
+ invokeNext(null);
+ }
+
+ private static AsynchronousAction ExceptionGuard(AsynchronousAction action)
+ {
+ return cont =>
+ {
+ try
+ {
+ action(cont);
+ }
+ catch (Exception ex)
+ {
+ cont(ex);
+ }
+ };
+ }
+
+ private static AsynchronousAction<T> ExceptionGuard<T>(AsynchronousAction<T> action)
+ {
+ return (AsyncContinuation cont, T argument) =>
+ {
+ try
+ {
+ action(cont, argument);
+ }
+ catch (Exception ex)
+ {
+ cont(ex);
+ }
+ };
+ }
+
+ /// <summary>
+ /// Modifies the continuation by pre-pending given action to execute just before it.
+ /// </summary>
+ /// <param name="asyncContinuation">The async continuation.</param>
+ /// <param name="action">The action to pre-pend.</param>
+ /// <returns>Continuation which will execute the given action before forwarding to the actual continuation.</returns>
+ public static AsyncContinuation PrecededBy(this AsyncContinuation asyncContinuation, AsynchronousAction action)
+ {
+ action = ExceptionGuard(action);
+
+ AsyncContinuation continuation =
+ ex =>
+ {
+ if (ex != null)
+ {
+ // if got exception from from original invocation, don't execute action
+ asyncContinuation(ex);
+ return;
+ }
+
+ // call the action and continue
+ action(asyncContinuation.OneTimeOnly());
+ };
+
+ return continuation;
+ }
+
+ public static AsyncContinuation PrecededByRegardlessOfResult(this AsyncContinuation asyncContinuation, SynchronousAction action)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static AsyncContinuation WithTimeout(this AsyncContinuation asyncContinuation, TimeSpan timeout)
+ {
+ return new TimeoutContinuation(asyncContinuation, timeout).Function;
+ }
+
+ public static void RunInParallel<T>(IEnumerable<T> values, AsyncContinuation asyncContinuation, AsynchronousAction<T> action)
+ {
+ action = ExceptionGuard(action);
+
+ var items = new List<T>(values);
+ int remaining = items.Count;
+ var exceptions = new List<Exception>();
+
+ InternalLogger.Trace("RunInParallel() {0} items", items.Count);
+
+ if (remaining == 0)
+ {
+ asyncContinuation(null);
+ return;
+ }
+
+ AsyncContinuation continuation =
+ ex =>
+ {
+ int r;
+
+ if (ex == null)
+ {
+ r = Interlocked.Decrement(ref remaining);
+ InternalLogger.Trace("Parallel task completed. {0} items remaining", r);
+ if (r == 0)
+ {
+ if (exceptions.Count == 0)
+ {
+ asyncContinuation(null);
+ }
+ else
+ {
+ asyncContinuation(new NLogRuntimeException("TODO - combine all exceptions into one."));
+ }
+ }
+
+ return;
+ }
+
+ lock (exceptions)
+ {
+ exceptions.Add(ex);
+ }
+
+ r = Interlocked.Decrement(ref remaining);
+ InternalLogger.Trace("Parallel task failed {0}. {1} items remaining", ex, r);
+ if (r == 0)
+ {
+ asyncContinuation(new NLogRuntimeException("TODO - combine all exceptions into one."));
+ }
+ };
+
+ foreach (var v in items)
+ {
+ action(OneTimeOnly(continuation), v);
+ }
+ }
+
+ public static void RunSynchronously(AsynchronousAction action)
+ {
+ var ev = new ManualResetEvent(false);
+ Exception lastException = null;
+
+ action(OneTimeOnly(ex => { lastException = ex; ev.Set(); }));
+ ev.WaitOne();
+ if (lastException != null)
+ {
+ throw new NLogRuntimeException("Asynchronous exception has occured.");
+ }
+ }
+
+ public static AsyncContinuation OneTimeOnly(this AsyncContinuation asyncContinuation)
+ {
+#if !NETCF2_0
+ // target is not available on .NET CF 2.0
+ if (asyncContinuation.Target is SingleCallContinuation)
+ {
+ return asyncContinuation;
+ }
+#endif
+
+ return new SingleCallContinuation(asyncContinuation).Function;
+ }
+ }
+}
39 src/NLog/Internal/AsynchronousAction.cs
View
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2004-2010 Jaroslaw Kowalski <jaak@jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog.Internal
+{
+ public delegate void AsynchronousAction(AsyncContinuation asyncContinuation);
+
+ public delegate void AsynchronousAction<T>(AsyncContinuation asyncContinuation, T argument);
+}
46 src/NLog/Internal/ExtensionAttribute.cs
View
@@ -0,0 +1,46 @@
+//
+// Copyright (c) 2004-2010 Jaroslaw Kowalski <jaak@jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if NET2_0 || NETCF2_0
+
+namespace System.Runtime.CompilerServices
+{
+ using System;
+
+ [AttributeUsage(AttributeTargets.Method)]
+ public class ExtensionAttribute : Attribute
+ {
+ }
+}
+
+#endif
70 src/NLog/Internal/SingleCallContinuation.cs
View
@@ -0,0 +1,70 @@
+//
+// Copyright (c) 2004-2010 Jaroslaw Kowalski <jaak@jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog.Internal
+{
+ using System;
+ using System.Threading;
+ using NLog.Common;
+
+ internal class SingleCallContinuation
+ {
+ private readonly AsyncContinuation asyncContinuation;
+ private int counter;
+
+ public SingleCallContinuation(AsyncContinuation asyncContinuation)
+ {
+ this.asyncContinuation = asyncContinuation;
+ }
+
+ public void Function(Exception exception)
+ {
+ try
+ {
+ if (Interlocked.Increment(ref counter) == 1)
+ {
+ this.asyncContinuation(exception);
+ }
+ }
+ catch (Exception ex)
+ {
+ ReportExceptionInHandler(ex);
+ }
+ }
+
+ private static void ReportExceptionInHandler(Exception exception)
+ {
+ InternalLogger.Error("Exception in asynchronous handler {0}", exception);
+ }
+ }
+}
37 src/NLog/Internal/SynchronousAction.cs
View
@@ -0,0 +1,37 @@
+//
+// Copyright (c) 2004-2010 Jaroslaw Kowalski <jaak@jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog.Internal
+{
+ public delegate void SynchronousAction();
+}
90 src/NLog/Internal/TimeoutContinuation.cs
View
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2004-2010 Jaroslaw Kowalski <jaak@jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog.Internal
+{
+ using System;
+ using System.Threading;
+ using NLog.Common;
+
+ internal class TimeoutContinuation
+ {
+ private readonly AsyncContinuation asyncContinuation;
+ private Timer timeoutTimer;
+ private int counter;
+
+ public TimeoutContinuation(AsyncContinuation asyncContinuation, TimeSpan timeout)
+ {
+ this.asyncContinuation = asyncContinuation;
+ this.timeoutTimer = new Timer(TimerElapsed, null, timeout, TimeSpan.FromMilliseconds(-1));
+ }
+
+ public void Function(Exception exception)
+ {
+ try
+ {
+ this.StopTimer();
+ if (Interlocked.Increment(ref counter) == 1)
+ {
+ this.asyncContinuation(exception);
+ }
+ }
+ catch (Exception ex)
+ {
+ ReportExceptionInHandler(ex);
+ }
+ }
+
+ private void StopTimer()
+ {
+ lock (this)
+ {
+ if (this.timeoutTimer != null)
+ {
+ this.timeoutTimer.Dispose();
+ this.timeoutTimer = null;
+ }
+ }
+ }
+
+ private void TimerElapsed(object state)
+ {
+ this.Function(new TimeoutException("Timeout."));
+ }
+
+ private static void ReportExceptionInHandler(Exception exception)
+ {
+ InternalLogger.Error("Exception in asynchronous handler {0}", exception);
+ }
+ }
+}
41 src/NLog/LogFactory.cs
View
@@ -52,6 +52,8 @@ namespace NLog
/// </summary>
public class LogFactory
{
+ private static TimeSpan DefaultFlushTimeout = TimeSpan.FromSeconds(15);
+
#if !NET_CF && !SILVERLIGHT
private readonly MultiFileWatcher watcher;
private const int ReconfigAfterFileChangedTimeout = 1000;
@@ -182,6 +184,9 @@ public LoggingConfiguration Configuration
if (oldConfig != null)
{
InternalLogger.Info("Closing old configuration.");
+#if !SILVERLIGHT
+ this.Flush();
+#endif
oldConfig.Close();
}
@@ -324,7 +329,7 @@ public void ReconfigExistingLoggers()
/// </summary>
public void Flush()
{
- this.Configuration.FlushAllTargets(TimeSpan.MaxValue);
+ this.Flush(DefaultFlushTimeout);
}
/// <summary>
@@ -333,7 +338,7 @@ public void Flush()
/// <param name="timeout">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
public void Flush(TimeSpan timeout)
{
- this.Configuration.FlushAllTargets(timeout);
+ AsyncHelpers.RunSynchronously(cb => this.Flush(cb, timeout));
}
/// <summary>
@@ -342,7 +347,37 @@ public void Flush(TimeSpan timeout)
/// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
public void Flush(int timeoutMilliseconds)
{
- this.Configuration.FlushAllTargets(TimeSpan.FromMilliseconds(timeoutMilliseconds));
+ this.Flush(TimeSpan.FromMilliseconds(timeoutMilliseconds));
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ public void Flush(AsyncContinuation asyncContinuation)
+ {
+ this.Flush(asyncContinuation, TimeSpan.MaxValue);
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ /// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+ public void Flush(AsyncContinuation asyncContinuation, int timeoutMilliseconds)
+ {
+ this.Flush(asyncContinuation, TimeSpan.FromMilliseconds(timeoutMilliseconds));
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ /// <param name="timeout">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+ public void Flush(AsyncContinuation asyncContinuation, TimeSpan timeout)
+ {
+ InternalLogger.Trace("LogFactory.Flush({0})", timeout);
+ this.Configuration.FlushAllTargets(asyncContinuation.WithTimeout(timeout));
}
/// <summary>Decreases the log enable counter and if it reaches -1
80 src/NLog/LogManager.cs
View
@@ -38,8 +38,9 @@ namespace NLog
using System.Runtime.CompilerServices;
using NLog.Common;
using NLog.Config;
+ using NLog.Internal;
- /// <summary>
+ /// <summary>
/// Creates and manages instances of <see cref="T:NLog.Logger" /> objects.
/// </summary>
public sealed class LogManager
@@ -195,31 +196,62 @@ public static void ReconfigExistingLoggers()
globalFactory.ReconfigExistingLoggers();
}
- /// <summary>
- /// Flush any pending log messages (in case of asynchronous targets).
- /// </summary>
- public static void Flush()
- {
- globalFactory.Flush();
- }
+#if !SILVERLIGHT
+/// <summary>
+/// Flush any pending log messages (in case of asynchronous targets).
+/// </summary>
+public static void Flush()
+{
+ globalFactory.Flush();
+}
- /// <summary>
- /// Flush any pending log messages (in case of asynchronous targets).
- /// </summary>
- /// <param name="timeout">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
- public static void Flush(TimeSpan timeout)
- {
- globalFactory.Flush(timeout);
- }
+/// <summary>
+/// Flush any pending log messages (in case of asynchronous targets).
+/// </summary>
+/// <param name="timeout">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+public static void Flush(TimeSpan timeout)
+{
+ globalFactory.Flush(timeout);
+}
- /// <summary>
- /// Flush any pending log messages (in case of asynchronous targets).
- /// </summary>
- /// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
- public static void Flush(int timeoutMilliseconds)
- {
- globalFactory.Flush(timeoutMilliseconds);
- }
+/// <summary>
+/// Flush any pending log messages (in case of asynchronous targets).
+/// </summary>
+/// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+public static void Flush(int timeoutMilliseconds)
+{
+ globalFactory.Flush(timeoutMilliseconds);
+}
+#endif
+
+/// <summary>
+/// Flush any pending log messages (in case of asynchronous targets).
+/// </summary>
+/// <param name="asyncContinuation">The asynchronous continuation.</param>
+public static void Flush(AsyncContinuation asyncContinuation)
+{
+ globalFactory.Flush(asyncContinuation);
+}
+
+/// <summary>
+/// Flush any pending log messages (in case of asynchronous targets).
+/// </summary>
+/// <param name="asyncContinuation">The asynchronous continuation.</param>
+/// <param name="timeout">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+public static void Flush(AsyncContinuation asyncContinuation, TimeSpan timeout)
+{
+ globalFactory.Flush(asyncContinuation, timeout);
+}
+
+/// <summary>
+/// Flush any pending log messages (in case of asynchronous targets).
+/// </summary>
+/// <param name="asyncContinuation">The asynchronous continuation.</param>
+/// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+public static void Flush(AsyncContinuation asyncContinuation, int timeoutMilliseconds)
+{
+ globalFactory.Flush(asyncContinuation, timeoutMilliseconds);
+}
/// <summary>Decreases the log enable counter and if it reaches -1
/// the logs are disabled.</summary>
171 src/NLog/LoggerImpl.cs
View
@@ -34,9 +34,10 @@
namespace NLog
{
using System;
+ using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
-
+ using System.Threading;
using NLog.Common;
using NLog.Config;
using NLog.Filters;
@@ -61,104 +62,144 @@ internal static void Write(Type loggerType, TargetWithFilterChain targets, LogEv
#if !NET_CF
StackTraceUsage stu = targets.GetStackTraceUsage();
- StackTrace stackTrace;
if (stu != StackTraceUsage.None && !logEvent.HasStackTrace)
{
- int firstUserFrame = 0;
+ StackTrace stackTrace;
#if !SILVERLIGHT
stackTrace = new StackTrace(StackTraceSkipMethods, stu == StackTraceUsage.WithSource);
#else
stackTrace = new StackTrace();
#endif
- for (int i = 0; i < stackTrace.FrameCount; ++i)
- {
- var frame = stackTrace.GetFrame(i);
- MethodBase mb = frame.GetMethod();
- Assembly methodAssembly = null;
+ int firstUserFrame = FindCallingMethodOnStackTrace(stackTrace, loggerType);
- if (mb.DeclaringType != null)
- {
- methodAssembly = mb.DeclaringType.Assembly;
- }
+ logEvent.SetStackTrace(stackTrace, firstUserFrame);
+ }
+#endif
+
+ int originalThreadId = Thread.CurrentThread.ManagedThreadId;
- if (methodAssembly == nlogAssembly || mb.DeclaringType == loggerType)
+ WriteToTargetWithFilterChain(targets, logEvent, ex =>
+ {
+ if (factory.ThrowExceptions && Thread.CurrentThread.ManagedThreadId == originalThreadId)
{
- firstUserFrame = i + 1;
+ throw new NLogRuntimeException("Exception occured in NLog", ex);
}
- else
+ });
+ }
+
+#if !NET_CF
+ private static int FindCallingMethodOnStackTrace(StackTrace stackTrace, Type loggerType)
+ {
+ int firstUserFrame = 0;
+ for (int i = 0; i < stackTrace.FrameCount; ++i)
+ {
+ var frame = stackTrace.GetFrame(i);
+ MethodBase mb = frame.GetMethod();
+ Assembly methodAssembly = null;
+
+ if (mb.DeclaringType != null)
+ {
+ methodAssembly = mb.DeclaringType.Assembly;
+ }
+
+ if (methodAssembly == nlogAssembly || mb.DeclaringType == loggerType)
+ {
+ firstUserFrame = i + 1;
+ }
+ else
+ {
+ if (firstUserFrame != 0)
{
- if (firstUserFrame != 0)
- {
- break;
- }
+ break;
}
}
-
- logEvent.SetStackTrace(stackTrace, firstUserFrame);
}
+
+ return firstUserFrame;
+ }
#endif
- for (TargetWithFilterChain awf = targets; awf != null; awf = awf.NextInChain)
+
+ private static void WriteToTargetWithFilterChain(TargetWithFilterChain targetListHead, LogEventInfo logEvent, AsyncContinuation onException)
+ {
+ if (targetListHead == null)
{
- Target app = awf.Target;
- FilterResult result = FilterResult.Neutral;
+ return;
+ }
+
+ Target target = targetListHead.Target;
+ FilterResult result = GetFilterResult(targetListHead.FilterChain, logEvent);
- try
+ if ((result == FilterResult.Ignore) || (result == FilterResult.IgnoreFinal))
+ {
+ if (InternalLogger.IsDebugEnabled)
{
- foreach (Filter f in awf.FilterChain)
- {
- result = f.GetFilterResult(logEvent);
- if (result != FilterResult.Neutral)
- {
- break;
- }
- }
+ InternalLogger.Debug("{0}.{1} Rejecting message because of a filter.", logEvent.LoggerName, logEvent.Level);
+ }
+
+ if (result == FilterResult.IgnoreFinal)
+ {
+ return;
+ }
+
+ // move to next target
+ WriteToTargetWithFilterChain(targetListHead.NextInChain, logEvent, onException);
+ return;
+ }
- if ((result == FilterResult.Ignore) || (result == FilterResult.IgnoreFinal))
+ target.WriteLogEvent(logEvent,
+ AsyncHelpers.OneTimeOnly(
+ ex =>
{
- if (InternalLogger.IsDebugEnabled)
+ if (ex == null)
{
- InternalLogger.Debug("{0}.{1} Rejecting message because of a filter.", logEvent.LoggerName, logEvent.Level);
+ // success
+ if (result == FilterResult.LogFinal)
+ {
+ return;
+ }
}
-
- if (result == FilterResult.IgnoreFinal)
+ else
{
- return;
+ // intentionally not returning here
+ // onException will throw or not, depending on ThrowExceptions setting
+ // and/or whether we are still on the original thread
+ // if it does not throw, we just proceed to the next target
+ InternalLogger.Error("Target exception: {0}", ex);
+ onException(ex);
}
- continue;
- }
- }
- catch (Exception ex)
- {
- InternalLogger.Error("FilterChain exception: {0}", ex);
- if (factory.ThrowExceptions)
- {
- throw;
- }
+ // write to the next target
+ WriteToTargetWithFilterChain(targetListHead.NextInChain, logEvent, onException);
+ }));
+ }
- continue;
- }
+ /// <summary>
+ /// Gets the filter result.
+ /// </summary>
+ /// <param name="filterChain">The filter chain.</param>
+ /// <param name="logEvent">The log event.</param>
+ /// <returns></returns>
+ private static FilterResult GetFilterResult(ICollection<Filter> filterChain, LogEventInfo logEvent)
+ {
+ var result = FilterResult.Neutral;
- try
- {
- app.WriteLogEvent(logEvent);
- }
- catch (Exception ex)
+ try
+ {
+ foreach (Filter f in filterChain)
{
- InternalLogger.Error("Target exception: {0}", ex);
- if (factory.ThrowExceptions)
+ result = f.GetFilterResult(logEvent);
+ if (result != FilterResult.Neutral)
{
- throw;
+ break;
}
-
- continue;
}
- if (result == FilterResult.LogFinal)
- {
- return;
- }
+ return result;
+ }
+ catch (Exception ex)
+ {
+ return FilterResult.Ignore;
}
}
}
10 src/NLog/NLog.mono2.csproj
View
@@ -100,7 +100,6 @@
<Compile Include="Config\LoggingRule.cs" />
<Compile Include="Config\MethodFactory.cs" />
<Compile Include="Config\NameBaseAttribute.cs" />
- <Compile Include="Config\NLogConfigurationException.cs" />
<Compile Include="Config\NLogFactories.cs" />
<Compile Include="Config\RequiredParameterAttribute.cs" />
<Compile Include="Config\RuntimeOS.cs" />
@@ -127,11 +126,15 @@
<Compile Include="Internal\AspHelper.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
+ <Compile Include="Internal\AsyncContinuation.cs" />
+ <Compile Include="Internal\AsyncHelpers.cs" />
+ <Compile Include="Internal\AsynchronousAction.cs" />
<Compile Include="Internal\CompactFrameworkHelper.cs" />
<Compile Include="Internal\CurrentTimeGetter.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EnumerableHelpers.cs" />
<Compile Include="Internal\EnvironmentHelper.cs" />
+ <Compile Include="Internal\ExtensionAttribute.cs" />
<Compile Include="Internal\FactoryHelper.cs" />
<Compile Include="Internal\FileAppenders\BaseFileAppender.cs" />
<Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" />
@@ -160,9 +163,12 @@
<Compile Include="Internal\PortableFileInfoHelper.cs" />
<Compile Include="Internal\PortableThreadIDHelper.cs" />
<Compile Include="Internal\PropertyHelper.cs" />
+ <Compile Include="Internal\SingleCallContinuation.cs" />
<Compile Include="Internal\StackTraceUsageUtils.cs" />
+ <Compile Include="Internal\SynchronousAction.cs" />
<Compile Include="Internal\TargetWithFilterChain.cs" />
<Compile Include="Internal\ThreadIDHelper.cs" />
+ <Compile Include="Internal\TimeoutContinuation.cs" />
<Compile Include="Internal\UrlHelper.cs" />
<Compile Include="Internal\Win32FileInfoHelper.cs" />
<Compile Include="Internal\Win32FileNativeMethods.cs" />
@@ -257,6 +263,8 @@
<Compile Include="LogReceiverService\NLogEvents.cs" />
<Compile Include="LogReceiverService\SoapLogReceiverClient.cs" />
<Compile Include="LogReceiverService\WcfLogReceiverClient.cs" />
+ <Compile Include="NLogConfigurationException.cs" />
+ <Compile Include="NLogRuntimeException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Targets\ArchiveNumberingMode.cs" />
<Compile Include="Targets\AspNetTraceTarget.cs" />
10 src/NLog/NLog.netcf20.csproj
View
@@ -108,7 +108,6 @@
<Compile Include="Config\LoggingRule.cs" />
<Compile Include="Config\MethodFactory.cs" />
<Compile Include="Config\NameBaseAttribute.cs" />
- <Compile Include="Config\NLogConfigurationException.cs" />
<Compile Include="Config\NLogFactories.cs" />
<Compile Include="Config\RequiredParameterAttribute.cs" />
<Compile Include="Config\RuntimeOS.cs" />
@@ -135,11 +134,15 @@
<Compile Include="Internal\AspHelper.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
+ <Compile Include="Internal\AsyncContinuation.cs" />
+ <Compile Include="Internal\AsyncHelpers.cs" />
+ <Compile Include="Internal\AsynchronousAction.cs" />
<Compile Include="Internal\CompactFrameworkHelper.cs" />
<Compile Include="Internal\CurrentTimeGetter.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EnumerableHelpers.cs" />
<Compile Include="Internal\EnvironmentHelper.cs" />
+ <Compile Include="Internal\ExtensionAttribute.cs" />
<Compile Include="Internal\FactoryHelper.cs" />
<Compile Include="Internal\FileAppenders\BaseFileAppender.cs" />
<Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" />
@@ -168,9 +171,12 @@
<Compile Include="Internal\PortableFileInfoHelper.cs" />
<Compile Include="Internal\PortableThreadIDHelper.cs" />
<Compile Include="Internal\PropertyHelper.cs" />
+ <Compile Include="Internal\SingleCallContinuation.cs" />
<Compile Include="Internal\StackTraceUsageUtils.cs" />
+ <Compile Include="Internal\SynchronousAction.cs" />
<Compile Include="Internal\TargetWithFilterChain.cs" />
<Compile Include="Internal\ThreadIDHelper.cs" />
+ <Compile Include="Internal\TimeoutContinuation.cs" />
<Compile Include="Internal\UrlHelper.cs" />
<Compile Include="Internal\Win32FileInfoHelper.cs" />
<Compile Include="Internal\Win32FileNativeMethods.cs" />
@@ -265,6 +271,8 @@
<Compile Include="LogReceiverService\NLogEvents.cs" />
<Compile Include="LogReceiverService\SoapLogReceiverClient.cs" />
<Compile Include="LogReceiverService\WcfLogReceiverClient.cs" />
+ <Compile Include="NLogConfigurationException.cs" />
+ <Compile Include="NLogRuntimeException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Targets\ArchiveNumberingMode.cs" />
<Compile Include="Targets\AspNetTraceTarget.cs" />
11 src/NLog/NLog.netcf35.csproj
View
@@ -55,6 +55,7 @@
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
+ <Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Messaging" />
<Reference Include="System.Web.Services" />
@@ -108,7 +109,6 @@
<Compile Include="Config\LoggingRule.cs" />
<Compile Include="Config\MethodFactory.cs" />
<Compile Include="Config\NameBaseAttribute.cs" />
- <Compile Include="Config\NLogConfigurationException.cs" />
<Compile Include="Config\NLogFactories.cs" />
<Compile Include="Config\RequiredParameterAttribute.cs" />
<Compile Include="Config\RuntimeOS.cs" />
@@ -135,11 +135,15 @@
<Compile Include="Internal\AspHelper.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
+ <Compile Include="Internal\AsyncContinuation.cs" />
+ <Compile Include="Internal\AsyncHelpers.cs" />
+ <Compile Include="Internal\AsynchronousAction.cs" />
<Compile Include="Internal\CompactFrameworkHelper.cs" />
<Compile Include="Internal\CurrentTimeGetter.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EnumerableHelpers.cs" />
<Compile Include="Internal\EnvironmentHelper.cs" />
+ <Compile Include="Internal\ExtensionAttribute.cs" />
<Compile Include="Internal\FactoryHelper.cs" />
<Compile Include="Internal\FileAppenders\BaseFileAppender.cs" />
<Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" />
@@ -168,9 +172,12 @@
<Compile Include="Internal\PortableFileInfoHelper.cs" />
<Compile Include="Internal\PortableThreadIDHelper.cs" />
<Compile Include="Internal\PropertyHelper.cs" />
+ <Compile Include="Internal\SingleCallContinuation.cs" />
<Compile Include="Internal\StackTraceUsageUtils.cs" />
+ <Compile Include="Internal\SynchronousAction.cs" />
<Compile Include="Internal\TargetWithFilterChain.cs" />
<Compile Include="Internal\ThreadIDHelper.cs" />
+ <Compile Include="Internal\TimeoutContinuation.cs" />
<Compile Include="Internal\UrlHelper.cs" />
<Compile Include="Internal\Win32FileInfoHelper.cs" />
<Compile Include="Internal\Win32FileNativeMethods.cs" />
@@ -265,6 +272,8 @@
<Compile Include="LogReceiverService\NLogEvents.cs" />
<Compile Include="LogReceiverService\SoapLogReceiverClient.cs" />
<Compile Include="LogReceiverService\WcfLogReceiverClient.cs" />
+ <Compile Include="NLogConfigurationException.cs" />
+ <Compile Include="NLogRuntimeException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Targets\ArchiveNumberingMode.cs" />
<Compile Include="Targets\AspNetTraceTarget.cs" />
10 src/NLog/NLog.netfx20.csproj
View
@@ -98,7 +98,6 @@
<Compile Include="Config\LoggingRule.cs" />
<Compile Include="Config\MethodFactory.cs" />
<Compile Include="Config\NameBaseAttribute.cs" />
- <Compile Include="Config\NLogConfigurationException.cs" />
<Compile Include="Config\NLogFactories.cs" />
<Compile Include="Config\RequiredParameterAttribute.cs" />
<Compile Include="Config\RuntimeOS.cs" />
@@ -125,11 +124,15 @@
<Compile Include="Internal\AspHelper.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
+ <Compile Include="Internal\AsyncContinuation.cs" />
+ <Compile Include="Internal\AsyncHelpers.cs" />
+ <Compile Include="Internal\AsynchronousAction.cs" />
<Compile Include="Internal\CompactFrameworkHelper.cs" />
<Compile Include="Internal\CurrentTimeGetter.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EnumerableHelpers.cs" />
<Compile Include="Internal\EnvironmentHelper.cs" />
+ <Compile Include="Internal\ExtensionAttribute.cs" />
<Compile Include="Internal\FactoryHelper.cs" />
<Compile Include="Internal\FileAppenders\BaseFileAppender.cs" />
<Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" />
@@ -158,9 +161,12 @@
<Compile Include="Internal\PortableFileInfoHelper.cs" />
<Compile Include="Internal\PortableThreadIDHelper.cs" />
<Compile Include="Internal\PropertyHelper.cs" />
+ <Compile Include="Internal\SingleCallContinuation.cs" />
<Compile Include="Internal\StackTraceUsageUtils.cs" />
+ <Compile Include="Internal\SynchronousAction.cs" />
<Compile Include="Internal\TargetWithFilterChain.cs" />
<Compile Include="Internal\ThreadIDHelper.cs" />
+ <Compile Include="Internal\TimeoutContinuation.cs" />
<Compile Include="Internal\UrlHelper.cs" />
<Compile Include="Internal\Win32FileInfoHelper.cs" />
<Compile Include="Internal\Win32FileNativeMethods.cs" />
@@ -255,6 +261,8 @@
<Compile Include="LogReceiverService\NLogEvents.cs" />
<Compile Include="LogReceiverService\SoapLogReceiverClient.cs" />
<Compile Include="LogReceiverService\WcfLogReceiverClient.cs" />
+ <Compile Include="NLogConfigurationException.cs" />
+ <Compile Include="NLogRuntimeException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Targets\ArchiveNumberingMode.cs" />
<Compile Include="Targets\AspNetTraceTarget.cs" />
10 src/NLog/NLog.netfx35.csproj
View
@@ -100,7 +100,6 @@
<Compile Include="Config\LoggingRule.cs" />
<Compile Include="Config\MethodFactory.cs" />
<Compile Include="Config\NameBaseAttribute.cs" />
- <Compile Include="Config\NLogConfigurationException.cs" />
<Compile Include="Config\NLogFactories.cs" />
<Compile Include="Config\RequiredParameterAttribute.cs" />
<Compile Include="Config\RuntimeOS.cs" />
@@ -127,11 +126,15 @@
<Compile Include="Internal\AspHelper.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
+ <Compile Include="Internal\AsyncContinuation.cs" />
+ <Compile Include="Internal\AsyncHelpers.cs" />
+ <Compile Include="Internal\AsynchronousAction.cs" />
<Compile Include="Internal\CompactFrameworkHelper.cs" />
<Compile Include="Internal\CurrentTimeGetter.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EnumerableHelpers.cs" />
<Compile Include="Internal\EnvironmentHelper.cs" />
+ <Compile Include="Internal\ExtensionAttribute.cs" />
<Compile Include="Internal\FactoryHelper.cs" />
<Compile Include="Internal\FileAppenders\BaseFileAppender.cs" />
<Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" />
@@ -160,9 +163,12 @@
<Compile Include="Internal\PortableFileInfoHelper.cs" />
<Compile Include="Internal\PortableThreadIDHelper.cs" />
<Compile Include="Internal\PropertyHelper.cs" />
+ <Compile Include="Internal\SingleCallContinuation.cs" />
<Compile Include="Internal\StackTraceUsageUtils.cs" />
+ <Compile Include="Internal\SynchronousAction.cs" />
<Compile Include="Internal\TargetWithFilterChain.cs" />
<Compile Include="Internal\ThreadIDHelper.cs" />
+ <Compile Include="Internal\TimeoutContinuation.cs" />
<Compile Include="Internal\UrlHelper.cs" />
<Compile Include="Internal\Win32FileInfoHelper.cs" />
<Compile Include="Internal\Win32FileNativeMethods.cs" />
@@ -251,6 +257,8 @@
<Compile Include="LogReceiverService\NLogEvents.cs" />
<Compile Include="LogReceiverService\SoapLogReceiverClient.cs" />
<Compile Include="LogReceiverService\WcfLogReceiverClient.cs" />
+ <Compile Include="NLogConfigurationException.cs" />
+ <Compile Include="NLogRuntimeException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Targets\ArchiveNumberingMode.cs" />
<Compile Include="Targets\AspResponseTarget.cs" />
10 src/NLog/NLog.netfx40.csproj
View
@@ -101,7 +101,6 @@
<Compile Include="Config\LoggingRule.cs" />
<Compile Include="Config\MethodFactory.cs" />
<Compile Include="Config\NameBaseAttribute.cs" />
- <Compile Include="Config\NLogConfigurationException.cs" />
<Compile Include="Config\NLogFactories.cs" />
<Compile Include="Config\RequiredParameterAttribute.cs" />
<Compile Include="Config\RuntimeOS.cs" />
@@ -128,11 +127,15 @@
<Compile Include="Internal\AspHelper.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
+ <Compile Include="Internal\AsyncContinuation.cs" />
+ <Compile Include="Internal\AsyncHelpers.cs" />
+ <Compile Include="Internal\AsynchronousAction.cs" />
<Compile Include="Internal\CompactFrameworkHelper.cs" />
<Compile Include="Internal\CurrentTimeGetter.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EnumerableHelpers.cs" />
<Compile Include="Internal\EnvironmentHelper.cs" />
+ <Compile Include="Internal\ExtensionAttribute.cs" />
<Compile Include="Internal\FactoryHelper.cs" />
<Compile Include="Internal\FileAppenders\BaseFileAppender.cs" />
<Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" />
@@ -161,9 +164,12 @@
<Compile Include="Internal\PortableFileInfoHelper.cs" />
<Compile Include="Internal\PortableThreadIDHelper.cs" />
<Compile Include="Internal\PropertyHelper.cs" />
+ <Compile Include="Internal\SingleCallContinuation.cs" />
<Compile Include="Internal\StackTraceUsageUtils.cs" />
+ <Compile Include="Internal\SynchronousAction.cs" />
<Compile Include="Internal\TargetWithFilterChain.cs" />
<Compile Include="Internal\ThreadIDHelper.cs" />
+ <Compile Include="Internal\TimeoutContinuation.cs" />
<Compile Include="Internal\UrlHelper.cs" />
<Compile Include="Internal\Win32FileInfoHelper.cs" />
<Compile Include="Internal\Win32FileNativeMethods.cs" />
@@ -252,6 +258,8 @@
<Compile Include="LogReceiverService\NLogEvents.cs" />
<Compile Include="LogReceiverService\SoapLogReceiverClient.cs" />
<Compile Include="LogReceiverService\WcfLogReceiverClient.cs" />
+ <Compile Include="NLogConfigurationException.cs" />
+ <Compile Include="NLogRuntimeException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Targets\ArchiveNumberingMode.cs" />
<Compile Include="Targets\AspResponseTarget.cs" />
10 src/NLog/NLog.sl2.csproj
View
@@ -102,7 +102,6 @@
<Compile Include="Config\LoggingRule.cs" />
<Compile Include="Config\MethodFactory.cs" />
<Compile Include="Config\NameBaseAttribute.cs" />
- <Compile Include="Config\NLogConfigurationException.cs" />
<Compile Include="Config\NLogFactories.cs" />
<Compile Include="Config\RequiredParameterAttribute.cs" />
<Compile Include="Config\RuntimeOS.cs" />
@@ -129,11 +128,15 @@
<Compile Include="Internal\AspHelper.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
+ <Compile Include="Internal\AsyncContinuation.cs" />
+ <Compile Include="Internal\AsyncHelpers.cs" />
+ <Compile Include="Internal\AsynchronousAction.cs" />
<Compile Include="Internal\CompactFrameworkHelper.cs" />
<Compile Include="Internal\CurrentTimeGetter.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EnumerableHelpers.cs" />
<Compile Include="Internal\EnvironmentHelper.cs" />
+ <Compile Include="Internal\ExtensionAttribute.cs" />
<Compile Include="Internal\FactoryHelper.cs" />
<Compile Include="Internal\FileAppenders\BaseFileAppender.cs" />
<Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" />
@@ -162,9 +165,12 @@
<Compile Include="Internal\PortableFileInfoHelper.cs" />
<Compile Include="Internal\PortableThreadIDHelper.cs" />
<Compile Include="Internal\PropertyHelper.cs" />
+ <Compile Include="Internal\SingleCallContinuation.cs" />
<Compile Include="Internal\StackTraceUsageUtils.cs" />
+ <Compile Include="Internal\SynchronousAction.cs" />
<Compile Include="Internal\TargetWithFilterChain.cs" />
<Compile Include="Internal\ThreadIDHelper.cs" />
+ <Compile Include="Internal\TimeoutContinuation.cs" />
<Compile Include="Internal\UrlHelper.cs" />
<Compile Include="Internal\Win32FileInfoHelper.cs" />
<Compile Include="Internal\Win32FileNativeMethods.cs" />
@@ -259,6 +265,8 @@
<Compile Include="LogReceiverService\NLogEvents.cs" />
<Compile Include="LogReceiverService\SoapLogReceiverClient.cs" />
<Compile Include="LogReceiverService\WcfLogReceiverClient.cs" />
+ <Compile Include="NLogConfigurationException.cs" />
+ <Compile Include="NLogRuntimeException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Targets\ArchiveNumberingMode.cs" />
<Compile Include="Targets\AspNetTraceTarget.cs" />
10 src/NLog/NLog.sl3.csproj
View
@@ -102,7 +102,6 @@
<Compile Include="Config\LoggingRule.cs" />
<Compile Include="Config\MethodFactory.cs" />
<Compile Include="Config\NameBaseAttribute.cs" />
- <Compile Include="Config\NLogConfigurationException.cs" />
<Compile Include="Config\NLogFactories.cs" />
<Compile Include="Config\RequiredParameterAttribute.cs" />
<Compile Include="Config\RuntimeOS.cs" />
@@ -129,11 +128,15 @@
<Compile Include="Internal\AspHelper.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
+ <Compile Include="Internal\AsyncContinuation.cs" />
+ <Compile Include="Internal\AsyncHelpers.cs" />
+ <Compile Include="Internal\AsynchronousAction.cs" />
<Compile Include="Internal\CompactFrameworkHelper.cs" />
<Compile Include="Internal\CurrentTimeGetter.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EnumerableHelpers.cs" />
<Compile Include="Internal\EnvironmentHelper.cs" />
+ <Compile Include="Internal\ExtensionAttribute.cs" />
<Compile Include="Internal\FactoryHelper.cs" />
<Compile Include="Internal\FileAppenders\BaseFileAppender.cs" />
<Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" />
@@ -162,9 +165,12 @@
<Compile Include="Internal\PortableFileInfoHelper.cs" />
<Compile Include="Internal\PortableThreadIDHelper.cs" />
<Compile Include="Internal\PropertyHelper.cs" />
+ <Compile Include="Internal\SingleCallContinuation.cs" />
<Compile Include="Internal\StackTraceUsageUtils.cs" />
+ <Compile Include="Internal\SynchronousAction.cs" />
<Compile Include="Internal\TargetWithFilterChain.cs" />
<Compile Include="Internal\ThreadIDHelper.cs" />
+ <Compile Include="Internal\TimeoutContinuation.cs" />
<Compile Include="Internal\UrlHelper.cs" />
<Compile Include="Internal\Win32FileInfoHelper.cs" />
<Compile Include="Internal\Win32FileNativeMethods.cs" />
@@ -259,6 +265,8 @@
<Compile Include="LogReceiverService\NLogEvents.cs" />
<Compile Include="LogReceiverService\SoapLogReceiverClient.cs" />
<Compile Include="LogReceiverService\WcfLogReceiverClient.cs" />
+ <Compile Include="NLogConfigurationException.cs" />
+ <Compile Include="NLogRuntimeException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Targets\ArchiveNumberingMode.cs" />
<Compile Include="Targets\AspNetTraceTarget.cs" />
10 src/NLog/NLog.sl4.csproj
View
@@ -103,7 +103,6 @@
<Compile Include="Config\LoggingRule.cs" />
<Compile Include="Config\MethodFactory.cs" />
<Compile Include="Config\NameBaseAttribute.cs" />
- <Compile Include="Config\NLogConfigurationException.cs" />
<Compile Include="Config\NLogFactories.cs" />
<Compile Include="Config\RequiredParameterAttribute.cs" />
<Compile Include="Config\RuntimeOS.cs" />
@@ -130,11 +129,15 @@
<Compile Include="Internal\AspHelper.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
+ <Compile Include="Internal\AsyncContinuation.cs" />
+ <Compile Include="Internal\AsyncHelpers.cs" />
+ <Compile Include="Internal\AsynchronousAction.cs" />
<Compile Include="Internal\CompactFrameworkHelper.cs" />
<Compile Include="Internal\CurrentTimeGetter.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EnumerableHelpers.cs" />
<Compile Include="Internal\EnvironmentHelper.cs" />
+ <Compile Include="Internal\ExtensionAttribute.cs" />
<Compile Include="Internal\FactoryHelper.cs" />
<Compile Include="Internal\FileAppenders\BaseFileAppender.cs" />
<Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" />
@@ -163,9 +166,12 @@
<Compile Include="Internal\PortableFileInfoHelper.cs" />
<Compile Include="Internal\PortableThreadIDHelper.cs" />
<Compile Include="Internal\PropertyHelper.cs" />
+ <Compile Include="Internal\SingleCallContinuation.cs" />
<Compile Include="Internal\StackTraceUsageUtils.cs" />
+ <Compile Include="Internal\SynchronousAction.cs" />
<Compile Include="Internal\TargetWithFilterChain.cs" />
<Compile Include="Internal\ThreadIDHelper.cs" />
+ <Compile Include="Internal\TimeoutContinuation.cs" />
<Compile Include="Internal\UrlHelper.cs" />
<Compile Include="Internal\Win32FileInfoHelper.cs" />
<Compile Include="Internal\Win32FileNativeMethods.cs" />
@@ -260,6 +266,8 @@
<Compile Include="LogReceiverService\NLogEvents.cs" />
<Compile Include="LogReceiverService\SoapLogReceiverClient.cs" />
<Compile Include="LogReceiverService\WcfLogReceiverClient.cs" />
+ <Compile Include="NLogConfigurationException.cs" />
+ <Compile Include="NLogRuntimeException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Targets\ArchiveNumberingMode.cs" />
<Compile Include="Targets\AspNetTraceTarget.cs" />
4 src/NLog/Config/NLogConfigurationException.cs → src/NLog/NLogConfigurationException.cs
View
@@ -31,12 +31,12 @@
// THE POSSIBILITY OF SUCH DAMAGE.
//
-namespace NLog.Config
+namespace NLog
{
using System;
/// <summary>
- /// Exception thrown during configuration.
+ /// Exception thrown during NLog configuration.
/// </summary>
#if !NET_CF && !SILVERLIGHT
[Serializable]
90 src/NLog/NLogRuntimeException.cs
View
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2004-2010 Jaroslaw Kowalski <jaak@jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog
+{
+ using System;
+
+ /// <summary>
+ /// Exception thrown during log event processing.
+ /// </summary>
+#if !NET_CF && !SILVERLIGHT
+ [Serializable]
+#endif
+ public class NLogRuntimeException : Exception
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NLogRuntimeException" /> class.
+ /// </summary>
+ public NLogRuntimeException()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NLogRuntimeException" /> class.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ public NLogRuntimeException(string message)
+ : base(message)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NLogRuntimeException" /> class.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="innerException">The inner exception.</param>
+ public NLogRuntimeException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+#if !NET_CF && !SILVERLIGHT
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NLogRuntimeException" /> class.
+ /// </summary>
+ /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+ /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ /// <exception cref="T:System.ArgumentNullException">
+ /// The <paramref name="info"/> parameter is null.
+ /// </exception>
+ /// <exception cref="T:System.Runtime.Serialization.SerializationException">
+ /// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
+ /// </exception>
+ protected NLogRuntimeException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
+ }
+}
2  src/NLog/ProjectFileInfo.xml
View
@@ -1,6 +1,6 @@
<ProjectFiles>
<!--
- this file contains information necessary to regenerate <Compile /> items in all NLog project files
+ this file contains information necessary to regenerate Compile items in all NLog project files
based on contents of this directory
The file is processed by SyncProjectItems.exe in tools directory.
13 src/NLog/Targets/Compound/CompoundTargetBase.cs
View
@@ -33,6 +33,7 @@
namespace NLog.Targets.Compound
{
+ using System;
using System.Collections.Generic;
using NLog.Layouts;
@@ -59,5 +60,15 @@ protected CompoundTargetBase(params Target[] targets)
/// Gets the collection of targets managed by this compound target.
/// </summary>
public IList<Target> Targets { get; private set; }
- }
+
+ /// <summary>
+ /// Writes logging event to the log target. Must be overridden in inheriting
+ /// classes.
+ /// </summary>
+ /// <param name="logEvent">Logging event to be written out.</param>
+ protected override void Write(LogEventInfo logEvent)
+ {
+ throw new NotSupportedException("This target must not be invoked in a synchronous way.");
+ }
+ }
}
63 src/NLog/Targets/Compound/FallbackTarget.cs
View
@@ -35,6 +35,7 @@ namespace NLog.Targets.Compound
{
using System;
using NLog.Common;
+ using NLog.Internal;
/// <summary>
/// A compound target that provides fallback-on-error functionality.
@@ -57,6 +58,7 @@ namespace NLog.Targets.Compound
public class FallbackTarget : CompoundTargetBase
{
private int currentTarget;
+ private object lockObject = new object();
/// <summary>
/// Initializes a new instance of the <see cref="FallbackTarget"/> class.
@@ -84,42 +86,73 @@ public FallbackTarget(params Target[] targets)
/// Forwards the log event to the sub-targets until one of them succeeds.
/// </summary>
/// <param name="logEvent">The log event.</param>
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
/// <remarks>
- /// The method remembers the last-known-successful target
+ /// The method remembers the last-known-successful target
/// and starts the iteration from it.
/// If <see cref="ReturnToFirstOnSuccess"/> is set, the method
- /// resets the target to the first target
+ /// resets the target to the first target
/// stored in <see cref="Targets"/>.
/// </remarks>
- protected override void Write(LogEventInfo logEvent)
+ protected override void Write(LogEventInfo logEvent, AsyncContinuation asyncContinuation)
{
- lock (this)
- {
- for (int i = 0; i < this.Targets.Count; ++i)
+ AsyncContinuation continuation = null;
+ int tryCounter = 0;
+ int targetToInvoke;
+
+ continuation = ex =>
{
- try
+ if (ex == null)
{
- this.Targets[this.currentTarget].WriteLogEvent(logEvent);
- if (this.currentTarget != 0)
+ // success
+ lock (this.lockObject)
{
- if (this.ReturnToFirstOnSuccess)
+ if (this.currentTarget != 0)
{
- InternalLogger.Debug("Fallback: target '{0}' succeeded. Returning to the first one.", this.Targets[this.currentTarget]);
- this.currentTarget = 0;
+ if (this.ReturnToFirstOnSuccess)
+ {
+ InternalLogger.Debug("Fallback: target '{0}' succeeded. Returning to the first one.", this.Targets[this.currentTarget]);
+ this.currentTarget = 0;
+ }
}
}
+ asyncContinuation(null);
return;
}
- catch (Exception ex)
+
+ // failure
+ lock (this.lockObject)
{
InternalLogger.Warn("Fallback: target '{0}' failed. Proceeding to the next one. Error was: {1}", this.Targets[this.currentTarget], ex);
- // error while writing, try another one
+ // error while writing, go to the next one
this.currentTarget = (this.currentTarget + 1) % this.Targets.Count;
+
+ tryCounter++;
+ targetToInvoke = this.currentTarget;
+ if (tryCounter >= this.Targets.Count)
+ {
+ targetToInvoke = -1;
+ }
+ }
+
+ if (targetToInvoke >= 0)
+ {
+ this.Targets[targetToInvoke].WriteLogEvent(logEvent, continuation);
+ }
+ else
+ {
+ asyncContinuation(ex);
}
- }
+ };
+
+ lock (this.lockObject)
+ {
+ targetToInvoke = this.currentTarget;
}
+
+ this.Targets[targetToInvoke].WriteLogEvent(logEvent, continuation);
}
}
}
18 src/NLog/Targets/Compound/RandomizeTarget.cs
View
@@ -34,6 +34,7 @@
namespace NLog.Targets.Compound
{
using System;
+ using NLog.Internal;
/// <summary>
/// A compound target writes to a randomly-chosen target among the sub-targets.
@@ -56,7 +57,7 @@ namespace NLog.Targets.Compound
[Target("RandomizeGroup", IsCompound = true)]
public class RandomizeTarget : CompoundTargetBase
{
- private static Random random = new Random();
+ private Random random = new Random();
/// <summary>
/// Initializes a new instance of the <see cref="RandomizeTarget" /> class.
@@ -75,14 +76,21 @@ public RandomizeTarget(params Target[] targets)
}
/// <summary>
- /// Forwards the log event to one of the sub-targets.
+ /// Forwards the log event to one of the sub-targets.
/// The sub-target is randomly chosen.
/// </summary>
/// <param name="logEvent">The log event.</param>
- protected override void Write(LogEventInfo logEvent)
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ protected override void Write(LogEventInfo logEvent, AsyncContinuation asyncContinuation)
{
- int pos = random.Next(this.Targets.Count);
- this.Targets[pos].WriteLogEvent(logEvent);
+ int selectedTarget;
+
+ lock (random)
+ {
+ selectedTarget = random.Next(this.Targets.Count);
+ }
+
+ this.Targets[selectedTarget].WriteLogEvent(logEvent, asyncContinuation);
}
}
}
11 src/NLog/Targets/Compound/RoundRobinTarget.cs
View
@@ -33,7 +33,9 @@
namespace NLog.Targets.Compound
{
+ using System;
using System.Threading;
+ using NLog.Internal;
/// <summary>
/// A compound target that forwards writes to the sub-targets in a
@@ -76,10 +78,11 @@ public RoundRobinTarget(params Target[] targets)
}
/// <summary>
- /// Forwards the write to one of the targets from
+ /// Forwards the write to one of the targets from
/// the <see cref="Targets"/> collection.
/// </summary>
/// <param name="logEvent">The log event.</param>
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
/// <remarks>
/// The writes are routed in a round-robin fashion.
/// The first log event goes to the first target, the second
@@ -87,10 +90,10 @@ public RoundRobinTarget(params Target[] targets)
/// first target when there are no more targets available.
/// In general request N goes to Targets[N % Targets.Count].
/// </remarks>
- protected override void Write(LogEventInfo logEvent)
+ protected override void Write(LogEventInfo logEvent, AsyncContinuation asyncContinuation)
{
- int currentTarget = Interlocked.Increment(ref this.currentTarget);
- this.Targets[currentTarget % this.Targets.Count].WriteLogEvent(logEvent);
+ int selectedTarget = Interlocked.Increment(ref this.currentTarget);
+ this.Targets[selectedTarget % this.Targets.Count].WriteLogEvent(logEvent, asyncContinuation);
}
}
}
12 src/NLog/Targets/Compound/SplitTarget.cs
View
@@ -33,6 +33,10 @@
namespace NLog.Targets.Compound
{
+ using System;
+ using System.Threading;
+ using NLog.Internal;
+
/// <summary>
/// A compound target that writes logging events to all attached
/// sub-targets.
@@ -74,12 +78,10 @@ public SplitTarget(params Target[] targets)
/// Forwards the specified log event to all sub-targets.
/// </summary>
/// <param name="logEvent">The log event.</param>
- protected override void Write(LogEventInfo logEvent)
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ protected override void Write(LogEventInfo logEvent, AsyncContinuation asyncContinuation)
{
- for (int i = 0; i < this.Targets.Count; ++i)
- {
- this.Targets[i].WriteLogEvent(logEvent);
- }
+ AsyncHelpers.ForEachItemSequentially(this.Targets, asyncContinuation, (cont, t) => t.WriteLogEvent(logEvent, cont));
}
}
}
21 src/NLog/Targets/FileTarget.cs
View
@@ -491,21 +491,30 @@ public void CleanupInitializedFiles(DateTime cleanupThreshold)
/// <summary>
/// Flushes all pending file operations.
/// </summary>
- /// <param name="timeout">The timeout.</param>
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
/// <remarks>
/// The timeout parameter is ignored, because file APIs don't provide
/// the needed functionality.
/// </remarks>
- public override void Flush(TimeSpan timeout)
+ protected override void FlushAsync(AsyncContinuation asyncContinuation)
{
- for (int i = 0; i < this.recentAppenders.Length; ++i)
+ try
{
- if (this.recentAppenders[i] == null)
+ for (int i = 0; i < this.recentAppenders.Length; ++i)
{
- break;
+ if (this.recentAppenders[i] == null)
+ {
+ break;
+ }
+
+ this.recentAppenders[i].Flush();
}
- this.recentAppenders[i].Flush();
+ asyncContinuation(null);
+ }
+ catch (Exception ex)
+ {
+ asyncContinuation(ex);
}
}
13 src/NLog/Targets/NetworkTarget.cs
View
@@ -38,6 +38,7 @@ namespace NLog.Targets
using System.ComponentModel;
using System.Text;
using NLog.Common;
+ using NLog.Internal;
using NLog.Internal.NetworkSenders;
using NLog.Layouts;
@@ -162,18 +163,22 @@ public enum OverflowAction
public Encoding Encoding { get; set; }
/// <summary>
- /// Flushes any buffers.
+ /// Flush any pending log messages asynchronously (in case of asynchronous targets).
/// </summary>
- /// <param name="timeout">Flush timeout.</param>
- public override void Flush(TimeSpan timeout)
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ protected override void FlushAsync(AsyncContinuation asyncContinuation)
{
- lock (this)
+ try
{
if (this.sender != null)
{
this.sender.Flush();
}
}
+ catch (Exception ex)
+ {
+ asyncContinuation(ex);
+ }
}
/// <summary>
119 src/NLog/Targets/Target.cs
View
@@ -40,6 +40,7 @@ namespace NLog.Targets
using NLog.Config;
using NLog.Internal;
using NLog.Layouts;
+ using System.Threading;
/// <summary>
/// Represents logging target.
@@ -54,52 +55,69 @@ public abstract class Target : ISupportsInitialize, INLogConfigurationItem, IDis
/// <docgen category='General Options' order='10' />
public string Name { get; set; }
- /// <summary>
- /// Flush any pending log messages (in case of asynchronous targets).
- /// </summary>
- public void Flush()
- {
- this.Flush(TimeSpan.MaxValue);
- }
+/// <summary>
+/// Flush any pending log messages (in case of asynchronous targets).
+/// </summary>
+/// <param name="asyncContinuation">The asynchronous continuation.</param>
+public void Flush(AsyncContinuation asyncContinuation)
+{
+ asyncContinuation = asyncContinuation.OneTimeOnly();
- /// <summary>
- /// Flush any pending log messages (in case of asynchronous targets).
- /// </summary>
- /// <param name="timeout">
- /// Maximum time to allow for the flush. Any messages after that time will be discarded.
- /// </param>
- public virtual void Flush(TimeSpan timeout)
- {
- // do nothing
- }
+ try
+ {
+ this.FlushAsync(asyncContinuation);
+ }
+ catch (Exception ex)
+ {
+ asyncContinuation(ex);
+ }
+}
- /// <summary>
- /// Flush any pending log messages (in case of asynchronous targets).
- /// </summary>
- /// <param name="timeoutMilliseconds">
- /// Maximum time to allow for the flush. Any messages after that time will be discarded.
- /// </param>
- public void Flush(int timeoutMilliseconds)
- {
- this.Flush(TimeSpan.FromMilliseconds(timeoutMilliseconds));
- }
+/// <summary>
+/// Flush any pending log messages asynchronously (in case of asynchronous targets).
+/// </summary>
+/// <param name="asyncContinuation">The asynchronous continuation.</param>
+protected virtual void FlushAsync(AsyncContinuation asyncContinuation)
+{
+ asyncContinuation(null);
+}
/// <summary>
/// Writes the log to the target.
/// </summary>
/// <param name="logEvent">Log event to write.</param>
- public void WriteLogEvent(LogEventInfo logEvent)
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ public void WriteLogEvent(LogEventInfo logEvent, AsyncContinuation asyncContinuation)
{
- this.Write(logEvent);
+ asyncContinuation = asyncContinuation.OneTimeOnly();
+
+ try
+ {
+ this.Write(logEvent, asyncContinuation);
+ }
+ catch (Exception ex)
+ {
+ asyncContinuation(ex);
+ }
}
/// <summary>
/// Writes the array of log events.
/// </summary>
/// <param name="logEvents">The log events.</param>
- public void WriteLogEvents(LogEventInfo[] logEvents)
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ public void WriteLogEvents(LogEventInfo[] logEvents, AsyncContinuation asyncContinuation)
{
- this.Write(logEvents);
+ asyncContinuation = asyncContinuation.OneTimeOnly();
+
+ try
+ {
+ this.Write(logEvents, asyncContinuation);
+ }
+ catch (Exception ex)
+ {
+ asyncContinuation(ex);
+ }
}
/// <summary>
@@ -185,6 +203,45 @@ protected virtual void Initialize()
protected abstract void Write(LogEventInfo logEvent);
/// <summary>
+ /// Writes log event to the log target. Must be overridden in inheriting
+ /// classes.
+ /// </summary>
+ /// <param name="logEvent">Log event to be written out.</param>
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ protected virtual void Write(LogEventInfo logEvent, AsyncContinuation asyncContinuation)
+ {
+ try
+ {
+ this.Write(logEvent);
+ asyncContinuation(null);
+ }
+ catch (Exception ex)
+ {
+ asyncContinuation(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes an array of logging events to the log target. By default it iterates on all
+ /// events and passes them to "Write" method. Inheriting classes can use this method to
+ /// optimize batch writes.
+ /// </summary>
+ /// <param name="logEvents">Logging events to be written out.</param>
+ /// <param name="asyncContinuation">The asynchronous continuation.</param>
+ protected virtual void Write(LogEventInfo[] logEvents, AsyncContinuation asyncContinuation)
+ {
+ try
+ {
+ this.Write(logEvents);
+ asyncContinuation(null);
+ }
+ catch (Exception ex)
+ {
+ asyncContinuation(ex);
+ }
+ }
+
+ /// <summary>
/// Writes an array of logging events to the log target. By default it iterates on all
/// events and passes them to "Write" method. Inheriting classes can use this method to
/// optimize batch writes.
3  src/NLog/Targets/Wrappers/AspNetBufferingTargetWrapper.cs
View
@@ -181,7 +181,6 @@ protected override void Close()
{
NLogHttpModule.BeginRequest -= this.OnBeginRequest;
NLogHttpModule.EndRequest -= this.OnEndRequest;
- Flush(TimeSpan.FromSeconds(3));
base.Close();
}
@@ -225,7 +224,7 @@ private void OnEndRequest(object sender, EventArgs args)
LogEventInfo[] events = buffer.GetEventsAndClear();
if (events.Length > 0)
{
- WrappedTarget.WriteLogEvents(events);
+ WrappedTarget.WriteLogEvents(events, AsyncHelpers.LogException);
}
}
}
2  src/NLog/Targets/Wrappers/AsyncRequestQueue-T.cs
View
@@ -137,7 +137,7 @@ public void Enqueue(T o)
/// <returns>List of dequeued items.</returns>